commit
5aa9aed047
|
@ -29,3 +29,4 @@ node_modules
|
|||
|
||||
*.swp
|
||||
out/
|
||||
db/
|
|
@ -88,7 +88,8 @@ CopayServer.prototype.createWallet = function(opts, cb) {
|
|||
var self = this,
|
||||
pubKey;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['name', 'm', 'n', 'pubKey'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['name', 'm', 'n', 'pubKey']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
if (_.isEmpty(opts.name)) return cb(new ClientError('Invalid wallet name'));
|
||||
if (!Wallet.verifyCopayerLimits(opts.m, opts.n))
|
||||
|
@ -154,7 +155,8 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) {
|
|||
CopayServer.prototype.joinWallet = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'xPubKeySignature'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'xPubKeySignature']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
if (_.isEmpty(opts.name)) return cb(new ClientError('Invalid copayer name'));
|
||||
|
||||
|
@ -236,7 +238,8 @@ CopayServer.prototype.getAddresses = function(opts, cb) {
|
|||
CopayServer.prototype.verifyMessageSignature = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['message', 'signature'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['message', 'signature']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
if (err) return cb(err);
|
||||
|
@ -389,7 +392,8 @@ CopayServer.prototype._selectUtxos = function(txp, utxos) {
|
|||
CopayServer.prototype.createTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['toAddress', 'amount'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['toAddress', 'amount']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
Utils.runLocked(self.walletId, cb, function(cb) {
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
|
@ -496,25 +500,22 @@ CopayServer.prototype.removePendingTx = function(opts, cb) {
|
|||
|
||||
Utils.runLocked(self.walletId, cb, function(cb) {
|
||||
|
||||
self.storage.fetchTx(self.walletId, opts.id, function(err, txp) {
|
||||
self.getTx({
|
||||
id: opts.id
|
||||
}, function(err, txp) {
|
||||
if (err) return cb(err);
|
||||
if (!txp)
|
||||
return cb(new ClientError('Transaction proposal not found'));
|
||||
|
||||
if (!txp.isPending())
|
||||
return cb(new ClientError('Transaction proposal not pending'));
|
||||
|
||||
|
||||
if (txp.creatorId !== self.copayerId)
|
||||
return cb(new ClientError('Not allowed to erase this TX'));
|
||||
return cb(new ClientError('Only creators can remove pending proposals'));
|
||||
|
||||
var actors = txp.getActors();
|
||||
|
||||
if (actors.length > 1)
|
||||
return cb(new ClientError('Not allowed to erase this TX'));
|
||||
|
||||
if (actors.length == 1 && actors[0] !== self.copayerId)
|
||||
return cb(new ClientError('Not allowed to erase this TX'));
|
||||
if (actors.length > 1 || (actors.length == 1 && actors[0] !== self.copayerId))
|
||||
return cb(new ClientError('Cannot remove a proposal signed/rejected by other copayers'));
|
||||
|
||||
self.storage.removeTx(self.walletId, opts.id, cb);
|
||||
});
|
||||
|
@ -539,7 +540,8 @@ CopayServer.prototype._broadcastTx = function(txp, cb) {
|
|||
CopayServer.prototype.signTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['txProposalId', 'signatures'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['txProposalId', 'signatures']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
if (err) return cb(err);
|
||||
|
@ -548,7 +550,6 @@ CopayServer.prototype.signTx = function(opts, cb) {
|
|||
id: opts.txProposalId
|
||||
}, function(err, txp) {
|
||||
if (err) return cb(err);
|
||||
if (!txp) return cb(new ClientError('Transaction proposal not found'));
|
||||
|
||||
var action = _.find(txp.actions, {
|
||||
copayerId: self.copayerId
|
||||
|
@ -596,13 +597,14 @@ CopayServer.prototype.signTx = function(opts, cb) {
|
|||
CopayServer.prototype.rejectTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['txProposalId'])) return cb(new ClientError('Required argument missing'));
|
||||
if (!Utils.checkRequired(opts, ['txProposalId']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
self.getTx({
|
||||
id: opts.txProposalId
|
||||
}, function(err, txp) {
|
||||
if (err) return cb(err);
|
||||
if (!txp) return cb(new ClientError('Transaction proposal not found'));
|
||||
|
||||
var action = _.find(txp.actions, {
|
||||
copayerId: self.copayerId
|
||||
});
|
||||
|
|
|
@ -7,6 +7,8 @@ var Utils = {};
|
|||
Utils.runLocked = function(token, cb, task) {
|
||||
var self = this;
|
||||
|
||||
$.shouldBeDefined(token);
|
||||
|
||||
Lock.get(token, function(lock) {
|
||||
var _cb = function() {
|
||||
cb.apply(null, arguments);
|
||||
|
|
|
@ -104,7 +104,7 @@ helpers.createUtxos = function(server, wallet, amounts, cb) {
|
|||
return {
|
||||
txid: helpers.randomTXID(),
|
||||
vout: Math.floor((Math.random() * 10) + 1),
|
||||
satoshis: amount,
|
||||
satoshis: helpers.toSatoshi(amount),
|
||||
scriptPubKey: addresses[i].getScriptPubKey(wallet.m).toBuffer().toString('hex'),
|
||||
address: addresses[i++].address,
|
||||
};
|
||||
|
@ -570,7 +570,7 @@ describe('Copay server', function() {
|
|||
});
|
||||
|
||||
it('should create a tx', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([100, 200]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -625,7 +625,7 @@ describe('Copay server', function() {
|
|||
});
|
||||
|
||||
it('should fail to create tx for address invalid address', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([100, 200]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('invalid address', 80, null, copayerPriv[0].privKey);
|
||||
|
||||
|
@ -640,7 +640,7 @@ describe('Copay server', function() {
|
|||
});
|
||||
|
||||
it('should fail to create tx for address of different network', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([100, 200]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('myE38JHdxmQcTJGP1ZiX4BiGhDxMJDvLJD', 80, null, copayerPriv[0].privKey);
|
||||
|
||||
|
@ -655,7 +655,7 @@ describe('Copay server', function() {
|
|||
});
|
||||
|
||||
it('should fail to create tx when insufficient funds', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([100]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [100], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 120, null, copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -680,7 +680,7 @@ describe('Copay server', function() {
|
|||
it.skip('should fail to create tx for dust amount', function(done) {});
|
||||
|
||||
it('should create tx when there is a pending tx and enough UTXOs', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([10.1, 10.2, 10.3]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [10.1, 10.2, 10.3], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -706,7 +706,7 @@ describe('Copay server', function() {
|
|||
});
|
||||
|
||||
it('should fail to create tx when there is a pending tx and not enough UTXOs', function(done) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([10.1, 10.2, 10.3]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [10.1, 10.2, 10.3], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -734,9 +734,9 @@ describe('Copay server', function() {
|
|||
|
||||
it('should create tx using different UTXOs for simultaneous requests', function(done) {
|
||||
var N = 5;
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi(_.times(N, function() {
|
||||
helpers.createUtxos(server, wallet, _.times(N, function() {
|
||||
return 100;
|
||||
})), function(utxos) {
|
||||
}), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
server.getBalance({}, function(err, balance) {
|
||||
should.not.exist(err);
|
||||
|
@ -776,7 +776,7 @@ describe('Copay server', function() {
|
|||
copayerPriv = c;
|
||||
copayerIds = ids;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([1, 2, 3, 4, 5, 6, 7, 8]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(1, 9), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -826,7 +826,7 @@ describe('Copay server', function() {
|
|||
copayerPriv = c;
|
||||
copayerIds = ids;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([1, 2, 3, 4, 5, 6, 7, 8]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(1, 9), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -968,7 +968,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
copayerPriv = c;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([1, 2, 3, 4, 5, 6, 7, 8]), function(inutxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(1, 9), function(inutxos) {
|
||||
utxos = inutxos;
|
||||
done();
|
||||
});
|
||||
|
@ -1042,7 +1042,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
copayerPriv = c;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([1, 2, 3, 4, 5, 6, 7, 8]), function(inutxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(1, 9), function(inutxos) {
|
||||
utxos = inutxos;
|
||||
done();
|
||||
});
|
||||
|
@ -1090,7 +1090,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
copayerPriv = c;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi(_.range(10)), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(10), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.1, null, copayerPriv[0].privKey);
|
||||
async.eachSeries(_.range(10), function(i, next) {
|
||||
|
@ -1177,7 +1177,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi(_.range(2)), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(2), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = {
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
|
@ -1225,7 +1225,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi(_.range(2)), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, _.range(2), function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = {
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
|
@ -1261,7 +1261,7 @@ describe('Copay server', function() {
|
|||
wallet = w;
|
||||
copayerPriv = c;
|
||||
server.createAddress({}, function(err, address) {
|
||||
helpers.createUtxos(server, wallet, helpers.toSatoshi([100, 200]), function(utxos) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', copayerPriv[0].privKey);
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
|
@ -1310,7 +1310,7 @@ describe('Copay server', function() {
|
|||
server2.removePendingTx({
|
||||
id: txp.id
|
||||
}, function(err) {
|
||||
err.message.should.contain('Not allowed');
|
||||
err.message.should.contain('creators');
|
||||
server2.getPendingTxs({}, function(err, txs) {
|
||||
txs.length.should.equal(1);
|
||||
done();
|
||||
|
@ -1330,7 +1330,7 @@ describe('Copay server', function() {
|
|||
server.removePendingTx({
|
||||
id: txp.id
|
||||
}, function(err) {
|
||||
err.message.should.contain('Not allowed');
|
||||
err.message.should.contain('other copayers');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue