496 lines
18 KiB
JavaScript
496 lines
18 KiB
JavaScript
'use strict';
|
|
|
|
var chai = chai || require('chai');
|
|
var should = chai.should();
|
|
var sinon = require('sinon');
|
|
var is_browser = (typeof process == 'undefined' || typeof process.versions === 'undefined');
|
|
if (is_browser) {
|
|
var copay = require('copay'); //browser
|
|
} else {
|
|
var copay = require('../copay'); //node
|
|
}
|
|
var copayConfig = require('../config');
|
|
var Wallet = require('../js/models/core/Wallet');
|
|
var Structure = copay.Structure;
|
|
var Storage = require('./mocks/FakeStorage');
|
|
var Network = require('./mocks/FakeNetwork');
|
|
var Blockchain = require('./mocks/FakeBlockchain');
|
|
var bitcore = bitcore || require('bitcore');
|
|
var TransactionBuilder = bitcore.TransactionBuilder;
|
|
var Transaction = bitcore.Transaction;
|
|
var Address = bitcore.Address;
|
|
var PayPro = bitcore.PayPro;
|
|
|
|
var G = is_browser ? window : global;
|
|
G.SSL_UNTRUSTED = true;
|
|
|
|
var x509 = {
|
|
priv: ''
|
|
+ 'LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeFRKdUsyYUdM'
|
|
+ 'bjFkWEpLRGg0TXdQTFVrbDNISTVwR25HNWFjNGwvMGlobXE4Y3dDCitGVlBnWk1TNTlheWtpc0Ir'
|
|
+ 'ekM3dnR2a0prL2J2K0JTT1g3b3hkSXN1TDNkS1FGcHVYWFZmcmRiOTV3WW40TSsKL25qRWhYTWxo'
|
|
+ 'Vk1IL09DaUFnOUpLaFRLV0w2R1JXWkFBaEE3bEJSaGdTTkRUaVRDNTFDYmlLN3hBNnBONCt0UQpI'
|
|
+ 'eG9tSlBYclpSa2JCMmtsT2ZXd2J2OTNZM0oxS0ZEK2kwUE1RSEx3N3JoRXVteEM5MytISFVWWVZI'
|
|
+ 'N0gxVFBaCkgxYmRVSkowMmdRZXlsSnNzWUNKeWRaUHpOVC96dXRzL0tKV2RSdjVseHdHOXU5dE1O'
|
|
+ 'TWdoSmJtQWFNa01HaSsKbzdQTkV5UDNxSEZyWXBZaHM1cHFMSE1STkI3OFFNOUllTmpMRndJREFR'
|
|
+ 'QUJBb0lCQVFERVJyalBiQUdjbmwxaAorZGIrOTczNGZ0aElBUkpWSko1dTRFK1JKcThSRWhGTEVL'
|
|
+ 'UFlKNW0yUC94dVZBMXpYV2xnYXhaRUZ6d1VRaUpZCjdsOEpLVjlwSHhReVlaQ1M4dndYZzhpWGtz'
|
|
+ 'dndQaWRvQmN1YW4vd0RWQ1FCZXk2VkxjVXpSYUd1Ui9sTHNYK1YKN2Z0QjBvUnFsSXFrYmNQZE1N'
|
|
+ 'dnFUeG93UnVoUG11Q3JWVGpPNHBiTnFuU09OUExPaUovRkFYYjJwZnpGZnBCUgpHeCtFTW16d2Ur'
|
|
+ 'SEZuSkJHRGhIWjk5bm4vVEJmYUp6TlZDcURZLzNid3o1WDdIUU5ZN1QrSnlUVUZzZVE5NHhzCnpy'
|
|
+ 'a2lidGRmVGNUanB1K1VoWm80c1p6Q3IrZkhHWm9FOUdEUHF0ZDRnQ3ByazRFS0pzbXFCRVN4QlhT'
|
|
+ 'RGhZZ04KOXBVRDM4c1pBb0dCQU9yZkRqdDZaL0ZDamFuVThXek5GaWYrOVQxQTJ4b013RDVWU2xN'
|
|
+ 'dVJyWW1HbGZyMEM5TQpmMUVvZ2l2dVRrYnA3cmtnZFRhWVRTYndmTnFaQkt4Y3R5YzdCaGRwWnhE'
|
|
+ 'RVdKa2Z5cThxVngvem1Cek1JK1ZzCjJLYi9hcHZXcmJlb3NET0NyeUg1YzhKc1VUOXhUWDNYYnhF'
|
|
+ 'anlPSlFCU1lHRE1qUHlKNkU5czZMQW9HQkFOYnYKd2d0S2Nra0tLbDJhNXZzaGR2RENnNnFLL1Fn'
|
|
+ 'T20vNktUSlVKRVNqaHoydFIrZlBWUjcwVEg5UmhoVFJscERXQgpCd3oyU2NCc1RRNDIvTGsxRnky'
|
|
+ 'MFQvck12S3VmSEw1VE1BNGZ6NWRxMUxIbmN6ejZVazVnWEtBT09rUjlVdVhpClR0eTNoREcyQkM4'
|
|
+ 'Nk1LTVJ4SjUxRWJxam94d0VSMTAwU2FuTVBmTWxBb0dBSUhLY1pyOHNhUHBHMC9XbFBPREEKZE5v'
|
|
+ 'V1MxWVFidkxnQkR5SVBpR2doejJRV2lFcjY3em53ZkNVdXpqNiszVUtFKzFXQkNyYVRjemZrdHVj'
|
|
+ 'OTZyLwphcDRPNDJFZWFnU1dNT0ZoZ1AyYWQ4R1JmRGovcEl4N0NlY3pkVUFkVThnc1A1R0lYR3M0'
|
|
+ 'QU40eUEwL0Y0dUxHCloxbklRT3ZKS2syZnFvWjZNdHd2dEswQ2dZRUFnSjdGTGVDRTkzUmYyZGdD'
|
|
+ 'ZFRHWGJZZlpKc3M1bEFLNkV0NUwKNmJ1ZFN5dWw1Z0VPWkgyekNsQlJjZFJSMUFNbSt1V1ZoSW8x'
|
|
+ 'cERLckFlQ2g1MnIvemRmakxLQXNIejkrQWQ3aQpHUEdzVmw0Vm5jaDFTMzQ0bHJKUGUzQklLZ2dj'
|
|
+ 'L1hncDNTYnNzcHJMY2orT0wyZElrOUpXbzZ1Y3hmMUJmMkwwCjJlbGhBUWtDZ1lCWHN5elZWL1pK'
|
|
+ 'cVhOcFdDZzU1TDNVRm9UTHlLU3FsVktNM1dpRzVCS240QWF6VkNITCtHUVUKeHd4U2dSOWZRNElu'
|
|
+ 'dStyUHJOM0lteWswbEtQR0Y5U3pDUlJUaUpGUjcyc05xbE82bDBWOENXUkFQVFBKY2dxVgoxVThO'
|
|
+ 'SEs4YjNaaUlvR0orbXNOenBkeHJqNjJIM0E2K1krQXNOWTRTbVVUWEg5eWpnK251a2c9PQotLS0t'
|
|
+ 'LUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=',
|
|
pub: ''
|
|
+ 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FR'
|
|
+ 'OEFNSUlCQ2dLQ0FRRUF4VEp1SzJhR0xuMWRYSktEaDRNdwpQTFVrbDNISTVwR25HNWFjNGwvMGlo'
|
|
+ 'bXE4Y3dDK0ZWUGdaTVM1OWF5a2lzQit6Qzd2dHZrSmsvYnYrQlNPWDdvCnhkSXN1TDNkS1FGcHVY'
|
|
+ 'WFZmcmRiOTV3WW40TSsvbmpFaFhNbGhWTUgvT0NpQWc5SktoVEtXTDZHUldaQUFoQTcKbEJSaGdT'
|
|
+ 'TkRUaVRDNTFDYmlLN3hBNnBONCt0UUh4b21KUFhyWlJrYkIya2xPZld3YnY5M1kzSjFLRkQraTBQ'
|
|
+ 'TQpRSEx3N3JoRXVteEM5MytISFVWWVZIN0gxVFBaSDFiZFVKSjAyZ1FleWxKc3NZQ0p5ZFpQek5U'
|
|
+ 'L3p1dHMvS0pXCmRSdjVseHdHOXU5dE1OTWdoSmJtQWFNa01HaStvN1BORXlQM3FIRnJZcFloczVw'
|
|
+ 'cUxITVJOQjc4UU05SWVOakwKRndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==',
|
|
der: ''
|
|
+ 'MIIDBjCCAe4CCQDI2qWdA3/VpDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTETMBEGA1UE'
|
|
+ 'CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE0MDcx'
|
|
+ 'NjAxMzM1MVoXDTE1MDcxNjAxMzM1MVowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh'
|
|
+ 'dGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQAD'
|
|
+ 'ggEPADCCAQoCggEBAMUybitmhi59XVySg4eDMDy1JJdxyOaRpxuWnOJf9IoZqvHMAvhVT4GTEufW'
|
|
+ 'spIrAfswu77b5CZP27/gUjl+6MXSLLi93SkBabl11X63W/ecGJ+DPv54xIVzJYVTB/zgogIPSSoU'
|
|
+ 'yli+hkVmQAIQO5QUYYEjQ04kwudQm4iu8QOqTePrUB8aJiT162UZGwdpJTn1sG7/d2NydShQ/otD'
|
|
+ 'zEBy8O64RLpsQvd/hx1FWFR+x9Uz2R9W3VCSdNoEHspSbLGAicnWT8zU/87rbPyiVnUb+ZccBvbv'
|
|
+ 'bTDTIISW5gGjJDBovqOzzRMj96hxa2KWIbOaaixzETQe/EDPSHjYyxcCAwEAATANBgkqhkiG9w0B'
|
|
+ 'AQUFAAOCAQEAL6AMMfC3TlRcmsIgHxjVD4XYtISlldnrn2X9zvFbJKCpNy8XQQosQxrhyfzPHQKj'
|
|
+ 'lS2L/KCGMnjx9QkYD2Hlp1MJ1uVv9888th/gcZOv3Or3hQyi5K1Sh5xCG+69lUOqUEGu9B4irsqo'
|
|
+ 'FomQVbQolSy+t4apdJi7kuEDwFDk4gZiVEfsuX+naN5a6pCnWnhX1Vf4fKwfkLobKKXm2zQVsjxl'
|
|
+ 'wBAqOEmJGDLoRMXH56qJnEZ/dqsczaJOHQSi9mFEHL0r5rsEDTT5AVxdnBfNnyGaCH7/zANEko+F'
|
|
+ 'GBj1JdJaJgFTXdbxDoyoPTPD+LJqSK5XYToo46y/T0u9CLveNA==',
|
|
pem: ''
|
|
+ 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCakNDQWU0Q0NRREkycVdkQTMvVnBEQU5C'
|
|
+ 'Z2txaGtpRzl3MEJBUVVGQURCRk1Rc3dDUVlEVlFRR0V3SkIKVlRFVE1CRUdBMVVFQ0F3S1UyOXRa'
|
|
+ 'UzFUZEdGMFpURWhNQjhHQTFVRUNnd1lTVzUwWlhKdVpYUWdWMmxrWjJsMApjeUJRZEhrZ1RIUmtN'
|
|
+ 'QjRYRFRFME1EY3hOakF4TXpNMU1Wb1hEVEUxTURjeE5qQXhNek0xTVZvd1JURUxNQWtHCkExVUVC'
|
|
+ 'aE1DUVZVeEV6QVJCZ05WQkFnTUNsTnZiV1V0VTNSaGRHVXhJVEFmQmdOVkJBb01HRWx1ZEdWeWJt'
|
|
+ 'VjAKSUZkcFpHZHBkSE1nVUhSNUlFeDBaRENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFE'
|
|
+ 'Q0NBUW9DZ2dFQgpBTVV5Yml0bWhpNTlYVnlTZzRlRE1EeTFKSmR4eU9hUnB4dVduT0pmOUlvWnF2'
|
|
+ 'SE1BdmhWVDRHVEV1ZldzcElyCkFmc3d1NzdiNUNaUDI3L2dVamwrNk1YU0xMaTkzU2tCYWJsMTFY'
|
|
+ 'NjNXL2VjR0orRFB2NTR4SVZ6SllWVEIvemcKb2dJUFNTb1V5bGkraGtWbVFBSVFPNVFVWVlFalEw'
|
|
+ 'NGt3dWRRbTRpdThRT3FUZVByVUI4YUppVDE2MlVaR3dkcApKVG4xc0c3L2QyTnlkU2hRL290RHpF'
|
|
+ 'Qnk4TzY0Ukxwc1F2ZC9oeDFGV0ZSK3g5VXoyUjlXM1ZDU2ROb0VIc3BTCmJMR0FpY25XVDh6VS84'
|
|
+ 'N3JiUHlpVm5VYitaY2NCdmJ2YlREVElJU1c1Z0dqSkRCb3ZxT3p6Uk1qOTZoeGEyS1cKSWJPYWFp'
|
|
+ 'eHpFVFFlL0VEUFNIall5eGNDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFMNkFNTWZD'
|
|
+ 'MwpUbFJjbXNJZ0h4alZENFhZdElTbGxkbnJuMlg5enZGYkpLQ3BOeThYUVFvc1F4cmh5ZnpQSFFL'
|
|
+ 'amxTMkwvS0NHCk1uang5UWtZRDJIbHAxTUoxdVZ2OTg4OHRoL2djWk92M09yM2hReWk1SzFTaDV4'
|
|
+ 'Q0crNjlsVU9xVUVHdTlCNGkKcnNxb0ZvbVFWYlFvbFN5K3Q0YXBkSmk3a3VFRHdGRGs0Z1ppVkVm'
|
|
+ 'c3VYK25hTjVhNnBDblduaFgxVmY0Zkt3ZgprTG9iS0tYbTJ6UVZzanhsd0JBcU9FbUpHRExvUk1Y'
|
|
+ 'SDU2cUpuRVovZHFzY3phSk9IUVNpOW1GRUhMMHI1cnNFCkRUVDVBVnhkbkJmTm55R2FDSDcvekFO'
|
|
+ 'RWtvK0ZHQmoxSmRKYUpnRlRYZGJ4RG95b1BUUEQrTEpxU0s1WFlUb28KNDZ5L1QwdTlDTHZlTkE9'
|
|
+ 'PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=='
|
|
};
|
|
|
|
x509.priv = new Buffer(x509.priv, 'base64');
|
|
x509.pub = new Buffer(x509.pub, 'base64');
|
|
x509.der = new Buffer(x509.der, 'base64');
|
|
x509.pem = new Buffer(x509.pem, 'base64');
|
|
|
|
function startServer(cb) {
|
|
var server = {
|
|
POST: {
|
|
|
|
/**
|
|
* Receive "I want to pay"
|
|
*/
|
|
|
|
'/-/request': function(req, cb) {
|
|
var res = {
|
|
statusCode: 200,
|
|
headers: {},
|
|
body: {}
|
|
};
|
|
|
|
var uid = 0;
|
|
|
|
console.log('Received payment "request" from %s.', req.socket.remoteAddress);
|
|
|
|
var outputs = [];
|
|
|
|
[2000, 1000].forEach(function(value) {
|
|
var po = new PayPro();
|
|
po = po.makeOutput();
|
|
// number of satoshis to be paid
|
|
po.set('amount', value);
|
|
// a TxOut script where the payment should be sent. similar to OP_CHECKSIG
|
|
po.set('script', new Buffer([
|
|
118, // OP_DUP
|
|
169, // OP_HASH160
|
|
76, // OP_PUSHDATA1
|
|
20, // number of bytes
|
|
0xcf,
|
|
0xbe,
|
|
0x41,
|
|
0xf4,
|
|
0xa5,
|
|
0x18,
|
|
0xed,
|
|
0xc2,
|
|
0x5a,
|
|
0xf7,
|
|
0x1b,
|
|
0xaf,
|
|
0xc7,
|
|
0x2f,
|
|
0xb6,
|
|
0x1b,
|
|
0xfc,
|
|
0xfc,
|
|
0x4f,
|
|
0xcd,
|
|
136, // OP_EQUALVERIFY
|
|
172 // OP_CHECKSIG
|
|
]));
|
|
outputs.push(po.message);
|
|
});
|
|
|
|
/**
|
|
* Payment Details
|
|
*/
|
|
|
|
var mdata = new Buffer([0]);
|
|
uid++;
|
|
if (uid > 0xffff) {
|
|
throw new Error('UIDs bigger than 0xffff not supported.');
|
|
} else if (uid > 0xff) {
|
|
mdata = new Buffer([(uid >> 8) & 0xff, (uid >> 0) & 0xff])
|
|
} else {
|
|
mdata = new Buffer([0, uid])
|
|
}
|
|
var now = Date.now() / 1000 | 0;
|
|
var pd = new PayPro();
|
|
pd = pd.makePaymentDetails();
|
|
pd.set('network', 'test');
|
|
pd.set('outputs', outputs);
|
|
pd.set('time', now);
|
|
pd.set('expires', now * 60 * 60 * 24);
|
|
pd.set('memo', 'Hello, this is the server, we would like some money.');
|
|
var port = +req.headers.host.split(':')[1] || server.port;
|
|
pd.set('payment_url', 'https://localhost:' + port + '/-/pay');
|
|
pd.set('merchant_data', mdata);
|
|
|
|
/*
|
|
* PaymentRequest
|
|
*/
|
|
|
|
var cr = new PayPro();
|
|
cr = cr.makeX509Certificates();
|
|
cr.set('certificate', [x509.der]);
|
|
|
|
// We send the PaymentRequest to the customer
|
|
var pr = new PayPro();
|
|
pr = pr.makePaymentRequest();
|
|
pr.set('payment_details_version', 1);
|
|
pr.set('pki_type', 'x509+sha256');
|
|
pr.set('pki_data', cr.serialize());
|
|
pr.set('serialized_payment_details', pd.serialize());
|
|
pr.sign(x509.priv);
|
|
|
|
pr = pr.serialize();
|
|
|
|
// BIP-71 - set the content-type
|
|
res.headers['Content-Type'] = PayPro.PAYMENT_REQUEST_CONTENT_TYPE;
|
|
res.headers['Content-Length'] = pr.length + '';
|
|
res.headers['Content-Transfer-Encoding'] = 'binary';
|
|
|
|
res.body = pr;
|
|
|
|
return cb(null, res, res.body);
|
|
},
|
|
|
|
/**
|
|
* Receive Payment
|
|
*/
|
|
|
|
'/-/pay': function(req, cb) {
|
|
var body = req.body;
|
|
|
|
var res = {
|
|
statusCode: 200,
|
|
headers: {},
|
|
body: {}
|
|
};
|
|
|
|
body = PayPro.Payment.decode(body);
|
|
|
|
var pay = new PayPro();
|
|
pay = pay.makePayment(body);
|
|
var merchant_data = pay.get('merchant_data');
|
|
var transactions = pay.get('transactions');
|
|
var refund_to = pay.get('refund_to');
|
|
var memo = pay.get('memo');
|
|
|
|
console.log('Received payment from %s.', req.socket.remoteAddress);
|
|
console.log('Customer Message: %s', memo);
|
|
console.log('Payment Message:');
|
|
console.log(pay);
|
|
|
|
// We send this to the customer after receiving a Payment
|
|
// Then we propogate the transaction through bitcoin network
|
|
var ack = new PayPro();
|
|
ack = ack.makePaymentACK();
|
|
ack.set('payment', pay.message);
|
|
ack.set('memo', 'Thank you for your payment!');
|
|
|
|
ack = ack.serialize();
|
|
|
|
// BIP-71 - set the content-type
|
|
res.headers['Content-Type'] = PayPro.PAYMENT_ACK_CONTENT_TYPE;
|
|
res.headers['Content-Length'] = ack.length + '';
|
|
res.headers['Content-Transfer-Encoding'] = 'binary';
|
|
|
|
transactions = transactions.map(function(tx) {
|
|
tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
|
|
var ptx = new bitcore.Transaction();
|
|
ptx.parse(tx.buffer);
|
|
return ptx;
|
|
});
|
|
|
|
transactions.forEach(function(tx) {
|
|
var id = tx.getHash().toString('hex');
|
|
console.log('');
|
|
console.log('Sending transaction with txid: %s', id);
|
|
console.log(tx.getStandardizedObject());
|
|
});
|
|
|
|
res.body = ack;
|
|
|
|
return cb(null, res, res.body);
|
|
}
|
|
},
|
|
listen: function() {
|
|
},
|
|
close: function() {
|
|
}
|
|
};
|
|
|
|
G.$http = function(options) {
|
|
var ret = {
|
|
success: function(cb) {
|
|
this._success = cb;
|
|
return this;
|
|
},
|
|
error: function(cb) {
|
|
this._error = cb;
|
|
return this;
|
|
},
|
|
_success: function() {
|
|
;
|
|
},
|
|
_error: function(_, err) {
|
|
throw err;
|
|
}
|
|
};
|
|
var method = (options.method || 'GET').toUpperCase();
|
|
var uri = options.uri || options.url;
|
|
var path = uri.replace(/^https?:\/\/[^\/]+/, '');
|
|
var req = options;
|
|
req.headers = req.headers || {};
|
|
req.body = req.body || {};
|
|
req.socket = {
|
|
remoteAddress: 'localhost'
|
|
};
|
|
req.headers['Host'] = 'localhost:8080';
|
|
Object.keys(req.headers).forEach(function(key) {
|
|
req.headers[key] = req.headers[key] + '';
|
|
req.headers[key.toLowerCase()] = req.headers[key] + '';
|
|
});
|
|
setTimeout(function() {
|
|
server[method][path](req, function(err, res, body) {
|
|
if (err) return ret._error(null, err, null, options);
|
|
Object.keys(res.headers).forEach(function(key) {
|
|
res.headers[key] = res.headers[key] + '';
|
|
res.headers[key.toLowerCase()] = res.headers[key] + '';
|
|
});
|
|
return ret._success(body, res.statusCode, res.headers, options);
|
|
});
|
|
}, 1);
|
|
return ret;
|
|
};
|
|
|
|
setTimeout(function() {
|
|
return cb(null, server);
|
|
}, 1);
|
|
}
|
|
|
|
var server;
|
|
|
|
describe('PayPro (in Wallet) model', function() {
|
|
var config = {
|
|
// requiredCopayers: 3,
|
|
// totalCopayers: 5,
|
|
requiredCopayers: 1,
|
|
totalCopayers: 1,
|
|
spendUnconfirmed: true,
|
|
reconnectDelay: 100,
|
|
networkName: 'testnet',
|
|
};
|
|
|
|
var createW = function(netKey, N, conf) {
|
|
var c = JSON.parse(JSON.stringify(conf || config));
|
|
if (!N) N = c.totalCopayers;
|
|
|
|
if (netKey) c.netKey = netKey;
|
|
var mainPrivateKey = new copay.PrivateKey({
|
|
networkName: config.networkName
|
|
});
|
|
var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
|
|
c.privateKey = mainPrivateKey;
|
|
|
|
c.publicKeyRing = new copay.PublicKeyRing({
|
|
networkName: c.networkName,
|
|
requiredCopayers: Math.min(N, c.requiredCopayers),
|
|
totalCopayers: N,
|
|
});
|
|
c.publicKeyRing.addCopayer(mainCopayerEPK);
|
|
|
|
c.txProposals = new copay.TxProposals({
|
|
networkName: c.networkName,
|
|
});
|
|
|
|
var storage = new Storage(config.storage);
|
|
var network = new Network(config.network);
|
|
var blockchain = new Blockchain(config.blockchain);
|
|
c.storage = storage;
|
|
c.network = network;
|
|
c.blockchain = blockchain;
|
|
|
|
c.addressBook = {
|
|
'2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
|
|
label: 'John',
|
|
copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03',
|
|
createdTs: 1403102115,
|
|
hidden: false
|
|
},
|
|
'2MtP8WyiwG7ZdVWM96CVsk2M1N8zyfiVQsY': {
|
|
label: 'Jennifer',
|
|
copayerId: '032991f836543a492bd6d0bb112552bfc7c5f3b7d5388fcbcbf2fbb893b44770d7',
|
|
createdTs: 1403103115,
|
|
hidden: false
|
|
}
|
|
};
|
|
|
|
c.networkName = config.networkName;
|
|
c.verbose = config.verbose;
|
|
c.version = '0.0.1';
|
|
|
|
return new Wallet(c);
|
|
}
|
|
|
|
var cachedW = null;
|
|
var cachedWobj = null;
|
|
var cachedCreateW = function() {
|
|
if (!cachedW) {
|
|
cachedW = createW();
|
|
cachedWobj = cachedW.toObj();
|
|
cachedWobj.opts.reconnectDelay = 100;
|
|
}
|
|
var w = Wallet.fromObj(cachedWobj, cachedW.storage, cachedW.network, cachedW.blockchain);
|
|
return w;
|
|
};
|
|
|
|
var unspentTest = [{
|
|
"address": "dummy",
|
|
"scriptPubKey": "dummy",
|
|
"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
|
"vout": 1,
|
|
"amount": 10,
|
|
"confirmations": 7
|
|
}];
|
|
|
|
var createW2 = function(privateKeys, N, conf) {
|
|
if (!N) N = 3;
|
|
var netKey = 'T0FbU2JLby0=';
|
|
var w = createW(netKey, N, conf);
|
|
should.exist(w);
|
|
|
|
var pkr = w.publicKeyRing;
|
|
|
|
for (var i = 0; i < N - 1; i++) {
|
|
if (privateKeys) {
|
|
var k = privateKeys[i];
|
|
pkr.addCopayer(k ? k.deriveBIP45Branch().extendedPublicKeyString() : null);
|
|
} else {
|
|
pkr.addCopayer();
|
|
}
|
|
}
|
|
|
|
return w;
|
|
};
|
|
|
|
var cachedW2 = null;
|
|
var cachedW2obj = null;
|
|
var cachedCreateW2 = function() {
|
|
if (!cachedW2) {
|
|
cachedW2 = createW2();
|
|
cachedW2obj = cachedW2.toObj();
|
|
cachedW2obj.opts.reconnectDelay = 100;
|
|
}
|
|
var w = Wallet.fromObj(cachedW2obj, cachedW2.storage, cachedW2.network, cachedW2.blockchain);
|
|
return w;
|
|
};
|
|
|
|
it('#start the example server', function(done) {
|
|
startServer(function(err, s) {
|
|
if (err) return done(err);
|
|
server = s;
|
|
server.uri = 'https://localhost:8080/-';
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('#send a payment request', function(done) {
|
|
var w = cachedCreateW2();
|
|
should.exist(w);
|
|
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
|
|
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
|
|
w.getUnspent = function(cb) {
|
|
return setTimeout(function() {
|
|
return cb(null, unspentTest, []);
|
|
}, 1);
|
|
};
|
|
var address = 'bitcoin:mq7se9wy2egettFxPbmn99cK8v5AFq55Lx?amount=0.11&r=' + server.uri + '/request';
|
|
var commentText = 'Hello, server. I\'d like to make a payment.';
|
|
w.createTx(address, commentText, function(ntxid, ca) {
|
|
if (w.totalCopayers > 1) {
|
|
should.exist(ntxid);
|
|
console.log('Sent TX proposal to other copayers:');
|
|
console.log([ntxid, ca]);
|
|
server.close();
|
|
done();
|
|
} else {
|
|
console.log('Sending TX to merchant server:');
|
|
console.log(ntxid);
|
|
w.sendTx(ntxid, function(txid, ca) {
|
|
should.exist(txid);
|
|
console.log('TX sent:');
|
|
console.log([ntxid, ca]);
|
|
server.close();
|
|
done();
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|