diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index db21473..5769091 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -480,6 +480,14 @@ Transaction.prototype._newTransaction = function() { /* Transaction creation interface */ +/** + * @typedef {Object} Transaction~fromObject + * @property {string} prevTxId + * @property {number} outputIndex + * @property {(Buffer|string|Script)} script + * @property {number} satoshis + */ + /** * Add an input to this transaction. This is a high level interface * to add an input, for more control, use @{link Transaction#addInput}. @@ -517,7 +525,7 @@ Transaction.prototype._newTransaction = function() { * ['03000...', '02000...'], 2); * ``` * - * @param {Object} utxo + * @param {(Array.|Transaction~fromObject)} utxo * @param {Array=} pubkeys * @param {number=} threshold */ @@ -691,17 +699,31 @@ Transaction.prototype.getChangeOutput = function() { return null; }; +/** + * @typedef {Object} Transaction~toObject + * @property {(string|Address)} address + * @property {number} satoshis + */ + /** * Add an output to the transaction. * * Beware that this resets all the signatures for inputs (in further versions, * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset). * - * @param {string|Address} address + * @param {(string|Address|Array.)} address * @param {number} amount in satoshis * @return {Transaction} this, for chaining */ Transaction.prototype.to = function(address, amount) { + if (_.isArray(address)) { + var self = this; + _.each(address, function(to) { + self.to(to.address, to.satoshis); + }); + return this; + } + $.checkArgument( JSUtil.isNaturalNumber(amount), 'Amount is expected to be a positive integer' diff --git a/test/transaction/transaction.js b/test/transaction/transaction.js index 3e8c6d1..b484f02 100644 --- a/test/transaction/transaction.js +++ b/test/transaction/transaction.js @@ -41,7 +41,8 @@ describe('Transaction', function() { 'outputIndex': 0, 'script': testScript, 'satoshis': testAmount - }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); + }) + .to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); it('can serialize to a plain javascript object', function() { var object = testTransaction.toObject(); @@ -168,7 +169,7 @@ describe('Transaction', function() { it('works for normal p2pkh', function() { var transaction = new Transaction() .from(simpleUtxoWith100000Satoshis) - .to(toAddress, 50000) + .to([{address: toAddress, satoshis: 50000}]) .change(changeAddress) .sign(privateKey); transaction.isFullySigned().should.equal(true); @@ -506,7 +507,8 @@ describe('Transaction', function() { 'outputIndex': 0, 'script': testScript, 'satoshis': testAmount - }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); + }) + .to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); tx.outputs[0]._satoshis = 100; tx.outputs[0]._satoshisBN = new BN('fffffffffffffff', 16); @@ -521,7 +523,8 @@ describe('Transaction', function() { 'outputIndex': 0, 'script': testScript, 'satoshis': testAmount - }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); + }) + .to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); tx.outputs[0]._satoshis = -100; tx.outputs[0]._satoshisBN = new BN(-100, 10); @@ -537,7 +540,8 @@ describe('Transaction', function() { 'outputIndex': 0, 'script': testScript, 'satoshis': testAmount - }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); + }) + .to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); tx.toBuffer = sinon.stub().returns({ length: 10000000 @@ -556,7 +560,8 @@ describe('Transaction', function() { 'outputIndex': 0, 'script': testScript, 'satoshis': testAmount - }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); + }) + .to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); tx.isCoinbase = sinon.stub().returns(false); tx.inputs[0].isNull = sinon.stub().returns(true); @@ -692,8 +697,10 @@ describe('Transaction', function() { }); it('an output can be removed by index', function() { var transaction = new Transaction() - .to(toAddress, 40000000) - .to(toAddress, 40000000); + .to([ + {address: toAddress, satoshis: 40000000}, + {address: toAddress, satoshis: 40000000} + ]) transaction.outputs.length.should.equal(2); transaction.outputAmount.should.equal(80000000); transaction.removeOutput(0); @@ -845,8 +852,10 @@ describe('Transaction', function() { beforeEach(function() { transaction = new Transaction() .from(simpleUtxoWith1BTC) - .to(toAddress, tenth) - .to(toAddress, fourth) + .to([ + {address: toAddress, satoshis: tenth}, + {address: toAddress, satoshis: fourth} + ]) .to(toAddress, half) .change(changeAddress); out1 = transaction.outputs[0]; @@ -905,8 +914,10 @@ describe('Transaction', function() { var tx = new Transaction() .from(simpleUtxoWith1BTC) .to(toAddress, tenth) - .to(toAddress, fourth) - .to(toAddress, half) + .to([ + {address: toAddress, satoshis: fourth}, + {address: toAddress, satoshis: half} + ]) .change(changeAddress); tx.clearOutputs(); tx.outputs.length.should.equal(1);