|
|
@ -2,12 +2,15 @@ |
|
|
|
|
|
|
|
var _ = require('lodash'); |
|
|
|
var async = require('async'); |
|
|
|
var inspect = require('util').inspect; |
|
|
|
|
|
|
|
var chai = require('chai'); |
|
|
|
var sinon = require('sinon'); |
|
|
|
var should = chai.should(); |
|
|
|
var levelup = require('levelup'); |
|
|
|
var memdown = require('memdown'); |
|
|
|
var log = require('npmlog'); |
|
|
|
log.debug = log.verbose; |
|
|
|
var Bitcore = require('bitcore'); |
|
|
|
|
|
|
|
var Utils = require('../../lib/utils'); |
|
|
@ -91,7 +94,7 @@ helpers.toSatoshi = function(btc) { |
|
|
|
helpers.stubUtxos = function(server, wallet, amounts, cb) { |
|
|
|
var amounts = [].concat(amounts); |
|
|
|
|
|
|
|
async.map(_.range(Math.ceil(amounts.length / 2)), function(i, next) { |
|
|
|
async.map(_.range(1, Math.ceil(amounts.length / 2) + 1), function(i, next) { |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
next(err, address); |
|
|
|
}); |
|
|
@ -126,6 +129,9 @@ helpers.stubBroadcastFail = function() { |
|
|
|
blockExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); |
|
|
|
}; |
|
|
|
|
|
|
|
helpers.stubHistory = function(txs) { |
|
|
|
blockExplorer.getTransactions = sinon.stub().callsArgWith(1, null, txs); |
|
|
|
}; |
|
|
|
|
|
|
|
helpers.clientSign = function(txp, xprivHex) { |
|
|
|
//Derive proper key to sign, for each input
|
|
|
@ -175,6 +181,19 @@ helpers.createProposalOpts = function(toAddress, amount, message, signingKey) { |
|
|
|
return opts; |
|
|
|
}; |
|
|
|
|
|
|
|
helpers.createAddresses = function(server, wallet, main, change, cb) { |
|
|
|
async.map(_.range(main + change), function(i, next) { |
|
|
|
var address = wallet.createAddress(i >= main); |
|
|
|
server.storage.storeAddressAndWallet(wallet, address, function(err) { |
|
|
|
if (err) return next(err); |
|
|
|
next(null, address); |
|
|
|
}); |
|
|
|
}, function(err, addresses) { |
|
|
|
if (err) throw new Error('Could not generate addresses'); |
|
|
|
return cb(_.take(addresses, main), _.takeRight(addresses, change)); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
var db, storage, blockExplorer; |
|
|
|
|
|
|
|
|
|
|
@ -650,9 +669,7 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(2, 3, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
done(); |
|
|
|
}); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
@ -661,7 +678,7 @@ describe('Copay server', function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
tx.should.exist; |
|
|
|
should.exist(tx); |
|
|
|
tx.message.should.equal('some message'); |
|
|
|
tx.isAccepted().should.equal.false; |
|
|
|
tx.isRejected().should.equal.false; |
|
|
@ -791,11 +808,11 @@ describe('Copay server', function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
tx.should.exist; |
|
|
|
should.exist(tx); |
|
|
|
var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 8, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts2, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
tx.should.exist; |
|
|
|
should.exist(tx); |
|
|
|
server.getPendingTxs({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
txs.length.should.equal(2); |
|
|
@ -816,7 +833,7 @@ describe('Copay server', function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
tx.should.exist; |
|
|
|
should.exist(tx); |
|
|
|
var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 24, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts2, function(err, tx) { |
|
|
|
err.code.should.equal('INSUFFICIENTFUNDS'); |
|
|
@ -839,9 +856,7 @@ describe('Copay server', function() { |
|
|
|
|
|
|
|
it('should create tx using different UTXOs for simultaneous requests', function(done) { |
|
|
|
var N = 5; |
|
|
|
helpers.stubUtxos(server, wallet, _.times(N, function() { |
|
|
|
return 100; |
|
|
|
}), function(utxos) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(100, 100 + N, 0), function(utxos) { |
|
|
|
server.getBalance({}, function(err, balance) { |
|
|
|
should.not.exist(err); |
|
|
|
balance.totalAmount.should.equal(helpers.toSatoshi(N * 100)); |
|
|
@ -877,15 +892,13 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(2, 3, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
tx.should.exist; |
|
|
|
txid = tx.id; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(tx); |
|
|
|
txid = tx.id; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -926,15 +939,13 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(2, 3, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(tx); |
|
|
|
txid = tx.id; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(tx); |
|
|
|
txid = tx.id; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1084,10 +1095,8 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(1, 1, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
done(); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1163,11 +1172,9 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(2, 3, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
helpers.stubBroadcast('999'); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(1, 9), function() { |
|
|
|
helpers.stubBroadcast('999'); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1363,17 +1370,15 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(1, 1, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(10), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.1, null, TestData.copayers[0].privKey); |
|
|
|
async.eachSeries(_.range(10), function(i, next) { |
|
|
|
clock.tick(10000); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function(err) { |
|
|
|
return done(err); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(10), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.1, null, TestData.copayers[0].privKey); |
|
|
|
async.eachSeries(_.range(10), function(i, next) { |
|
|
|
clock.tick(10000); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function(err) { |
|
|
|
return done(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1449,17 +1454,15 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(1, 1, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, helpers.toSatoshi(_.range(4)), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.01, null, TestData.copayers[0].privKey); |
|
|
|
async.eachSeries(_.range(3), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function(err) { |
|
|
|
return done(err); |
|
|
|
helpers.stubUtxos(server, wallet, helpers.toSatoshi(_.range(4)), function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.01, null, TestData.copayers[0].privKey); |
|
|
|
async.eachSeries(_.range(3), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function(err) { |
|
|
|
return done(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1583,18 +1586,16 @@ describe('Copay server', function() { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
|
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(2), function() { |
|
|
|
var txOpts = { |
|
|
|
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', |
|
|
|
amount: helpers.toSatoshi(0.1), |
|
|
|
}; |
|
|
|
async.eachSeries(_.range(2), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, done); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(2), function() { |
|
|
|
var txOpts = { |
|
|
|
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', |
|
|
|
amount: helpers.toSatoshi(0.1), |
|
|
|
}; |
|
|
|
async.eachSeries(_.range(2), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, done); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1632,27 +1633,25 @@ describe('Copay server', function() { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
|
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, _.range(2), function() { |
|
|
|
var txOpts = { |
|
|
|
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', |
|
|
|
amount: helpers.toSatoshi(0.1), |
|
|
|
}; |
|
|
|
async.eachSeries(_.range(2), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function() { |
|
|
|
server.removeWallet({}, function(err) { |
|
|
|
db = []; |
|
|
|
server.storage._dump(function() { |
|
|
|
var after = _.clone(db); |
|
|
|
after.should.deep.equal(before); |
|
|
|
done(); |
|
|
|
}, cat); |
|
|
|
}); |
|
|
|
}, cat); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, _.range(2), function() { |
|
|
|
var txOpts = { |
|
|
|
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', |
|
|
|
amount: helpers.toSatoshi(0.1), |
|
|
|
}; |
|
|
|
async.eachSeries(_.range(2), function(i, next) { |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
next(); |
|
|
|
}); |
|
|
|
}, function() { |
|
|
|
server.removeWallet({}, function(err) { |
|
|
|
db = []; |
|
|
|
server.storage._dump(function() { |
|
|
|
var after = _.clone(db); |
|
|
|
after.should.deep.equal(before); |
|
|
|
done(); |
|
|
|
}, cat); |
|
|
|
}); |
|
|
|
}, cat); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, cat); |
|
|
@ -1666,14 +1665,12 @@ describe('Copay server', function() { |
|
|
|
helpers.createAndJoinWallet(2, 3, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
server.createAddress({}, function(err, address) { |
|
|
|
helpers.stubUtxos(server, wallet, [100, 200], function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
server.getPendingTxs({}, function(err, txs) { |
|
|
|
txp = txs[0]; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
helpers.stubUtxos(server, wallet, [100, 200], function() { |
|
|
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
server.getPendingTxs({}, function(err, txs) { |
|
|
|
txp = txs[0]; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1742,4 +1739,169 @@ describe('Copay server', function() { |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
describe('#getTxHistory', function() { |
|
|
|
var server, wallet, mainAddresses, changeAddresses; |
|
|
|
beforeEach(function(done) { |
|
|
|
helpers.createAndJoinWallet(1, 1, function(s, w) { |
|
|
|
server = s; |
|
|
|
wallet = w; |
|
|
|
helpers.createAddresses(server, wallet, 1, 1, function(main, change) { |
|
|
|
mainAddresses = main; |
|
|
|
changeAddresses = change; |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should get tx history from insight', function(done) { |
|
|
|
helpers.stubHistory(TestData.history); |
|
|
|
server.getTxHistory({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(txs); |
|
|
|
txs.length.should.equal(2); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
it('should get tx history for incoming txs', function(done) { |
|
|
|
server._normalizeTxHistory = sinon.stub().returnsArg(0); |
|
|
|
var txs = [{ |
|
|
|
txid: '1', |
|
|
|
confirmations: 1, |
|
|
|
fees: 100, |
|
|
|
minedTs: 1, |
|
|
|
inputs: [{ |
|
|
|
address: 'external', |
|
|
|
amount: 500, |
|
|
|
}], |
|
|
|
outputs: [{ |
|
|
|
address: mainAddresses[0].address, |
|
|
|
amount: 200, |
|
|
|
}], |
|
|
|
}]; |
|
|
|
helpers.stubHistory(txs); |
|
|
|
server.getTxHistory({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(txs); |
|
|
|
txs.length.should.equal(1); |
|
|
|
var tx = txs[0]; |
|
|
|
tx.action.should.equal('received'); |
|
|
|
tx.amount.should.equal(200); |
|
|
|
tx.fees.should.equal(100); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
it('should get tx history for outgoing txs', function(done) { |
|
|
|
server._normalizeTxHistory = sinon.stub().returnsArg(0); |
|
|
|
var txs = [{ |
|
|
|
txid: '1', |
|
|
|
confirmations: 1, |
|
|
|
fees: 100, |
|
|
|
minedTs: 1, |
|
|
|
inputs: [{ |
|
|
|
address: mainAddresses[0].address, |
|
|
|
amount: 500, |
|
|
|
}], |
|
|
|
outputs: [{ |
|
|
|
address: 'external', |
|
|
|
amount: 400, |
|
|
|
}], |
|
|
|
}]; |
|
|
|
helpers.stubHistory(txs); |
|
|
|
server.getTxHistory({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(txs); |
|
|
|
txs.length.should.equal(1); |
|
|
|
var tx = txs[0]; |
|
|
|
tx.action.should.equal('sent'); |
|
|
|
tx.amount.should.equal(400); |
|
|
|
tx.fees.should.equal(100); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
it('should get tx history for outgoing txs + change', function(done) { |
|
|
|
server._normalizeTxHistory = sinon.stub().returnsArg(0); |
|
|
|
var txs = [{ |
|
|
|
txid: '1', |
|
|
|
confirmations: 1, |
|
|
|
fees: 100, |
|
|
|
minedTs: 1, |
|
|
|
inputs: [{ |
|
|
|
address: mainAddresses[0].address, |
|
|
|
amount: 500, |
|
|
|
}], |
|
|
|
outputs: [{ |
|
|
|
address: 'external', |
|
|
|
amount: 300, |
|
|
|
}, { |
|
|
|
address: changeAddresses[0].address, |
|
|
|
amount: 100, |
|
|
|
}], |
|
|
|
}]; |
|
|
|
helpers.stubHistory(txs); |
|
|
|
server.getTxHistory({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(txs); |
|
|
|
txs.length.should.equal(1); |
|
|
|
var tx = txs[0]; |
|
|
|
tx.action.should.equal('sent'); |
|
|
|
tx.amount.should.equal(300); |
|
|
|
tx.fees.should.equal(100); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
it('should get tx history with accepted proposal', function(done) { |
|
|
|
server._normalizeTxHistory = sinon.stub().returnsArg(0); |
|
|
|
|
|
|
|
helpers.stubUtxos(server, wallet, [100, 200], function(utxos) { |
|
|
|
var txOpts = helpers.createProposalOpts(mainAddresses[0].address, 80, 'some message', TestData.copayers[0].privKey); |
|
|
|
server.createTx(txOpts, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(tx); |
|
|
|
|
|
|
|
helpers.stubBroadcast('1122334455'); |
|
|
|
var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); |
|
|
|
server.signTx({ |
|
|
|
txProposalId: tx.id, |
|
|
|
signatures: signatures, |
|
|
|
}, function(err, tx) { |
|
|
|
should.not.exist(err); |
|
|
|
var txs = [{ |
|
|
|
txid: '1122334455', |
|
|
|
confirmations: 1, |
|
|
|
fees: 5460, |
|
|
|
minedTs: 1, |
|
|
|
inputs: [{ |
|
|
|
address: tx.inputs[0].address, |
|
|
|
amount: utxos[0].satoshis, |
|
|
|
}], |
|
|
|
outputs: [{ |
|
|
|
address: 'external', |
|
|
|
amount: helpers.toSatoshi(80) - 5460, |
|
|
|
}, { |
|
|
|
address: changeAddresses[0].address, |
|
|
|
amount: helpers.toSatoshi(20) - 5460, |
|
|
|
}], |
|
|
|
}]; |
|
|
|
helpers.stubHistory(txs); |
|
|
|
|
|
|
|
server.getTxHistory({}, function(err, txs) { |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(txs); |
|
|
|
txs.length.should.equal(1); |
|
|
|
var tx = txs[0]; |
|
|
|
tx.action.should.equal('sent'); |
|
|
|
tx.amount.should.equal(helpers.toSatoshi(80)); |
|
|
|
tx.message.should.equal('some message'); |
|
|
|
tx.actions.length.should.equal(1); |
|
|
|
tx.actions[0].type.should.equal('accept'); |
|
|
|
tx.actions[0].copayerName.should.equal('copayer 1'); |
|
|
|
done(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|