mirror of https://github.com/BTCPrivate/copay.git
paypro: add hideous test for payment protocol.
This commit is contained in:
parent
e06fda5128
commit
f6e9d647b4
|
@ -0,0 +1,459 @@
|
||||||
|
'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 addCopayers = function(w) {
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
w.publicKeyRing.addCopayer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var chai = chai || require('chai');
|
||||||
|
var should = chai.should();
|
||||||
|
|
||||||
|
var FakeStorage = require('./mocks/FakeLocalStorage');
|
||||||
|
//var copay = copay || require('../copay');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var FakeNetwork = require('./mocks/FakeNetwork');
|
||||||
|
var FakeBlockchain = require('./mocks/FakeBlockchain');
|
||||||
|
var FakeStorage = require('./mocks/FakeStorage');
|
||||||
|
var WalletFactory = require('../js/models/core/WalletFactory');
|
||||||
|
var Passphrase = require('../js/models/core/Passphrase');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var G = typeof window !== 'undefined' ? window : global;
|
||||||
|
G.SSL_UNTRUSTED = true;
|
||||||
|
|
||||||
|
if (!is_browser) {
|
||||||
|
// Disable strictSSL
|
||||||
|
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
|
||||||
|
|
||||||
|
var _request = require('request');
|
||||||
|
G.$http = function(options) {
|
||||||
|
var ret = {
|
||||||
|
success: function(cb) {
|
||||||
|
this._success = cb;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
error: function(cb) {
|
||||||
|
this._error = cb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (options.responseType === 'arraybuffer') {
|
||||||
|
delete options.responseType;
|
||||||
|
options.encoding = null;
|
||||||
|
}
|
||||||
|
_request(options, function(err, res, body) {
|
||||||
|
if (err) return ret._error(null, null, null, options);
|
||||||
|
return ret._success(body, res.statusCode, res.headers, options);
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function startServer_() {
|
||||||
|
if (is_browser) {
|
||||||
|
return cb(null, {
|
||||||
|
close: function() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawn = require('child_process').spawn;
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
//var bc = path.dirname(require.resolve('bitcore/package.json'));
|
||||||
|
//var bc = path.dirname(require.resolve(__dirname + '/../node_modules/bitcore/package.json'));
|
||||||
|
var bc = path.dirname(require.resolve(__dirname + '/../../bitcore/package.json'));
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
env: process.env,
|
||||||
|
setsid: false,
|
||||||
|
customFds: [-1, -1, -1]
|
||||||
|
};
|
||||||
|
|
||||||
|
var ps = spawn('node',
|
||||||
|
[bc + '/examples/PayPro/index.js', '-p', '8080'],
|
||||||
|
options);
|
||||||
|
|
||||||
|
ps.close = function() {
|
||||||
|
ps.once('error', function() {
|
||||||
|
server.kill('SIGKILL');
|
||||||
|
});
|
||||||
|
ps.kill('SIGTERM');
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
ps.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cb(null, ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startServer(cb) {
|
||||||
|
if (is_browser) {
|
||||||
|
return cb(null, {
|
||||||
|
close: function() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var bc = path.dirname(require.resolve(__dirname + '/../../bitcore/package.json'));
|
||||||
|
var example = bc + '/examples/PayPro/server.js';
|
||||||
|
var server = require(example);
|
||||||
|
|
||||||
|
server.listen(8080, function(addr) {
|
||||||
|
return cb(null, server);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// var server = startServer();
|
||||||
|
// server.uri = 'https://localhost:8080/-';
|
||||||
|
|
||||||
|
var server;
|
||||||
|
|
||||||
|
/*
|
||||||
|
describe('PayPro (in Wallet) model', function() {
|
||||||
|
var config = {
|
||||||
|
Network: FakeNetwork,
|
||||||
|
Blockchain: FakeBlockchain,
|
||||||
|
Storage: FakeStorage,
|
||||||
|
wallet: {
|
||||||
|
// requiredCopayers: 3,
|
||||||
|
// totalCopayers: 5,
|
||||||
|
requiredCopayers: 1,
|
||||||
|
totalCopayers: 1,
|
||||||
|
spendUnconfirmed: 1,
|
||||||
|
reconnectDelay: 100,
|
||||||
|
},
|
||||||
|
blockchain: {
|
||||||
|
host: 'test.insight.is',
|
||||||
|
port: 80
|
||||||
|
},
|
||||||
|
networkName: 'testnet',
|
||||||
|
passphrase: 'test',
|
||||||
|
storageObj: new FakeStorage(),
|
||||||
|
networkObj: new FakeNetwork(),
|
||||||
|
blockchainObj: new FakeBlockchain(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
config.storageObj.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should start the example server', function(done) {
|
||||||
|
startServer(function(err, s) {
|
||||||
|
if (err) return done(err);
|
||||||
|
server = s;
|
||||||
|
server.uri = 'https://localhost:8080/-';
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to create wallets', function(done) {
|
||||||
|
var wf = new WalletFactory(config, '0.0.1');
|
||||||
|
var w = wf.create();
|
||||||
|
|
||||||
|
var unspentTest = [{
|
||||||
|
'address': null,
|
||||||
|
"scriptPubKey": null,
|
||||||
|
"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
||||||
|
"vout": 1,
|
||||||
|
"amount": 10,
|
||||||
|
"confirmations": 7
|
||||||
|
|
||||||
|
, hashToScriptMap: {
|
||||||
|
'2N6fdPg2QL7V36XKe7a8wkkA5HCy7fNYmZF': '5321027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d5092102ab32ba51402a139873aeb919c738f5a945f3956f8f8c6ba296677bd29e85d7e821036f119b72e09f76c11ebe2cf754d64eac2cb42c9e623455d54aaa89d70c11f9c82103bcbd3f8ab2c849ea9eae434733cee8b75120d26233def56011b3682ca12081d72103f37f81dc534163b9f73ecf36b91e6c3fb8ae370c24618f91bb1d972e86ceeee255ae'
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
|
||||||
|
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
var unspentTest = [{
|
||||||
|
address: '2N6fdPg2QL7V36XKe7a8wkkA5HCy7fNYmZF',
|
||||||
|
scriptPubKey: 'a91493372782bab70f4eefdefefea8ece0df44f9596887',
|
||||||
|
txid: '2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1',
|
||||||
|
vout: 1,
|
||||||
|
amount: 10,
|
||||||
|
confirmations: 7,
|
||||||
|
scriptSig: ['00493046022100b8249a4fc326c4c33882e9d5468a1c6faa01e8c6cef0a24970122e804abdd860022100dbf6ee3b07d3aad8f73997e62ad20654a08aa63a7609792d02f3d5d088e69ad9014cad5321027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d5092102ab32ba51402a139873aeb919c738f5a945f3956f8f8c6ba296677bd29e85d7e821036f119b72e09f76c11ebe2cf754d64eac2cb42c9e623455d54aaa89d70c11f9c82103bcbd3f8ab2c849ea9eae434733cee8b75120d26233def56011b3682ca12081d72103f37f81dc534163b9f73ecf36b91e6c3fb8ae370c24618f91bb1d972e86ceeee255ae'],
|
||||||
|
hashToScriptMap: {
|
||||||
|
'2N6fdPg2QL7V36XKe7a8wkkA5HCy7fNYmZF': '5321027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d5092102ab32ba51402a139873aeb919c738f5a945f3956f8f8c6ba296677bd29e85d7e821036f119b72e09f76c11ebe2cf754d64eac2cb42c9e623455d54aaa89d70c11f9c82103bcbd3f8ab2c849ea9eae434733cee8b75120d26233def56011b3682ca12081d72103f37f81dc534163b9f73ecf36b91e6c3fb8ae370c24618f91bb1d972e86ceeee255ae'
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
// Addresses
|
||||||
|
var addrs = [
|
||||||
|
'mzTQ66VKcybz9BD1LAqEwMFp9NrBGS82sY',
|
||||||
|
'mmu9k3KzsDMEm9JxmJmZaLhovAoRKW3zr4',
|
||||||
|
'myqss64GNZuWuFyg5LTaoTCyWEpKH56Fgz'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Private keys in WIF format (see TransactionBuilder.js for other options)
|
||||||
|
var keys = [
|
||||||
|
'cVvr5YmWVAkVeZWAawd2djwXM4QvNuwMdCw1vFQZBM1SPFrtE8W8',
|
||||||
|
'cPyx1hXbe3cGQcHZbW3GNSshCYZCriidQ7afR2EBsV6ReiYhSkNF'
|
||||||
|
// 'cUB9quDzq1Bj7pocenmofzNQnb1wJNZ5V3cua6pWKzNL1eQtaDqQ'
|
||||||
|
];
|
||||||
|
|
||||||
|
var unspent = [{
|
||||||
|
// http://blockexplorer.com/testnet/rawtx/1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22
|
||||||
|
'txid': '1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22',
|
||||||
|
'vout': 1,
|
||||||
|
'address': addrs[0],
|
||||||
|
'scriptPubKey': '76a94c14cfbe41f4a518edc25af71bafc72fb61bfcfc4fcd88ac',
|
||||||
|
'amount': 1.60000000,
|
||||||
|
'confirmations': 9
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// http://blockexplorer.com/testnet/rawtx/0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804
|
||||||
|
'txid': '0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804',
|
||||||
|
'vout': 1,
|
||||||
|
'address': addrs[1],
|
||||||
|
'scriptPubKey': '76a94c14460376539c219c5e3274d86f16b40e806b37817688ac',
|
||||||
|
'amount': 1.60000000,
|
||||||
|
'confirmations': 9
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
should.exist(w);
|
||||||
|
|
||||||
|
w.getUnspent = function(cb) {
|
||||||
|
return setTimeout(function() {
|
||||||
|
return cb(null, unspentTest, []);
|
||||||
|
}, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
var address = 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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
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('should start the example server', function(done) {
|
||||||
|
startServer(function(err, s) {
|
||||||
|
if (err) return done(err);
|
||||||
|
server = s;
|
||||||
|
server.uri = 'https://localhost:8080/-';
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('#create a payment transaction', function() {
|
||||||
|
var w = cachedCreateW2();
|
||||||
|
var comment = 'This is a comment';
|
||||||
|
|
||||||
|
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
|
||||||
|
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
|
||||||
|
|
||||||
|
var ntxid = w.createTxSync(
|
||||||
|
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
|
||||||
|
'123456789',
|
||||||
|
comment,
|
||||||
|
unspentTest
|
||||||
|
);
|
||||||
|
|
||||||
|
var t = w.txProposals;
|
||||||
|
var txp = t.txps[ntxid];
|
||||||
|
var tx = txp.builder.build();
|
||||||
|
should.exist(tx);
|
||||||
|
txp.comment.should.equal(comment);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should 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 = 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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue