sendMax option on createTx
This commit is contained in:
parent
755449e32d
commit
bdff2cbc35
|
@ -164,7 +164,7 @@ TxProposal.prototype._buildTx = function() {
|
|||
var totalInputs = _.sum(self.inputs, 'satoshis');
|
||||
var totalOutputs = _.sum(self.outputs, 'satoshis');
|
||||
|
||||
if (totalInputs - totalOutputs - self.fee > 0) {
|
||||
if (totalInputs - totalOutputs - self.fee > 0 && self.changeAddress) {
|
||||
t.change(self.changeAddress.address);
|
||||
}
|
||||
|
||||
|
|
|
@ -1152,7 +1152,7 @@ WalletService.prototype.getBalance = function(opts, cb) {
|
|||
* Return info needed to send all funds in the wallet
|
||||
* @param {Object} opts
|
||||
* @param {string} opts.feePerKb - The fee per KB used to compute the TX.
|
||||
* @param {string} opts.excludeUnconfirmedUtxos - Exclude unconfirmed UTXOs from calculation.
|
||||
* @param {string} opts.excludeUnconfirmedUtxos[=false] - Optional. Do not use UTXOs of unconfirmed transactions as inputs
|
||||
* @returns {Object} sendMaxInfo
|
||||
*/
|
||||
WalletService.prototype.getSendMaxInfo = function(opts, cb) {
|
||||
|
@ -1161,7 +1161,7 @@ WalletService.prototype.getSendMaxInfo = function(opts, cb) {
|
|||
|
||||
opts = opts || {};
|
||||
|
||||
if (!Utils.checkRequired(opts, ['feePerKb', 'excludeUnconfirmedUtxos']))
|
||||
if (!Utils.checkRequired(opts, ['feePerKb']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
|
@ -1179,7 +1179,7 @@ WalletService.prototype.getSendMaxInfo = function(opts, cb) {
|
|||
};
|
||||
|
||||
var inputs = _.reject(utxos, 'locked');
|
||||
if (opts.excludeUnconfirmedUtxos) {
|
||||
if (!!opts.excludeUnconfirmedUtxos) {
|
||||
inputs = _.filter(inputs, 'confirmations');
|
||||
}
|
||||
inputs = _.sortBy(inputs, 'satoshis');
|
||||
|
@ -1628,12 +1628,14 @@ WalletService.prototype._validateOutputs = function(opts, wallet) {
|
|||
if (toAddress.network != wallet.getNetworkName()) {
|
||||
return Errors.INCORRECT_ADDRESS_NETWORK;
|
||||
}
|
||||
|
||||
if (!_.isNumber(output.amount) || _.isNaN(output.amount) || output.amount <= 0) {
|
||||
return new ClientError('Invalid amount');
|
||||
}
|
||||
if (output.amount < Bitcore.Transaction.DUST_AMOUNT) {
|
||||
return Errors.DUST_AMOUNT;
|
||||
}
|
||||
|
||||
output.valid = true;
|
||||
}
|
||||
return null;
|
||||
|
@ -1785,23 +1787,7 @@ WalletService.prototype.createTxLegacy = function(opts, cb) {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new transaction proposal.
|
||||
* @param {Object} opts
|
||||
* @param {Array} opts.outputs - List of outputs.
|
||||
* @param {string} opts.outputs[].toAddress - Destination address.
|
||||
* @param {number} opts.outputs[].amount - Amount to transfer in satoshi.
|
||||
* @param {string} opts.outputs[].message - A message to attach to this output.
|
||||
* @param {string} opts.message - A message to attach to this transaction.
|
||||
* @param {number} opts.feePerKb - The fee per kB to use for this TX.
|
||||
* @param {string} opts.payProUrl - Optional. Paypro URL for peers to verify TX
|
||||
* @param {string} opts.excludeUnconfirmedUtxos[=false] - Optional. Do not use UTXOs of unconfirmed transactions as inputs
|
||||
* @param {string} opts.validateOutputs[=true] - Optional. Perform validation on outputs.
|
||||
* @param {Array} opts.inputs - Optional. Inputs for this TX
|
||||
* @param {number} opts.fee - Optional. The fee to use for this TX (used only when opts.inputs is specified).
|
||||
* @returns {TxProposal} Transaction proposal.
|
||||
*/
|
||||
WalletService.prototype.createTx = function(opts, cb) {
|
||||
WalletService.prototype._doCreateTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['outputs']))
|
||||
|
@ -1869,6 +1855,48 @@ WalletService.prototype.createTx = function(opts, cb) {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new transaction proposal.
|
||||
* @param {Object} opts
|
||||
* @param {Array} opts.outputs - List of outputs.
|
||||
* @param {string} opts.outputs[].toAddress - Destination address.
|
||||
* @param {number} opts.outputs[].amount - Amount to transfer in satoshi.
|
||||
* @param {string} opts.outputs[].message - A message to attach to this output.
|
||||
* @param {string} opts.message - A message to attach to this transaction.
|
||||
* @param {Array} opts.inputs - Optional. Inputs for this TX
|
||||
* @param {string} opts.fee - Optional. Use an alternative fee for this TX (mutually exclusive with feePerKb)
|
||||
* @param {string} opts.feePerKb - Optional. Use an alternative fee per KB for this TX (mutually exclusive with fee)
|
||||
* @param {string} opts.sendMax - Optional. Send maximum amount of funds that make sense under the specified fee/feePerKb conditions. (defaults to false).
|
||||
* @param {string} opts.payProUrl - Optional. Paypro URL for peers to verify TX
|
||||
* @param {string} opts.excludeUnconfirmedUtxos[=false] - Optional. Do not use UTXOs of unconfirmed transactions as inputs
|
||||
* @param {string} opts.validateOutputs[=true] - Optional. Perform validation on outputs.
|
||||
* @returns {TxProposal} Transaction proposal.
|
||||
*/
|
||||
WalletService.prototype.createTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
opts = opts || [];
|
||||
async.series([
|
||||
|
||||
function(next) {
|
||||
if (!opts.sendMax) return next();
|
||||
if (!_.isArray(opts.outputs) || opts.outputs.length > 1) {
|
||||
return next(new ClientError('Only one output allowed when sendMax is specified'));
|
||||
}
|
||||
self.getSendMaxInfo(opts, function(err, info) {
|
||||
if (err) return next(err);
|
||||
opts.outputs[0].amount = info.amount;
|
||||
opts.inputs = info.inputs;
|
||||
return next();
|
||||
});
|
||||
},
|
||||
], function(err) {
|
||||
if (err) return cb(err);
|
||||
self._doCreateTx(opts, cb);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
WalletService.prototype._verifyRequestPubKey = function(requestPubKey, signature, xPubKey) {
|
||||
var pub = (new Bitcore.HDPublicKey(xPubKey)).derive(Constants.PATHS.REQUEST_KEY_AUTH).publicKey;
|
||||
return Utils.verifyMessage(requestPubKey, signature, pub.toString());
|
||||
|
|
|
@ -3113,6 +3113,33 @@ describe('Wallet service', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it.only('should be able to send max funds', function(done) {
|
||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
amount: null,
|
||||
}],
|
||||
feePerKb: 10000,
|
||||
sendMax: true,
|
||||
};
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
should.not.exist(err);
|
||||
should.exist(tx);
|
||||
// should.not.exist(tx.changeAddress);
|
||||
tx.amount.should.equal(3e8 - tx.fee);
|
||||
|
||||
var t = tx.getBitcoreTx();
|
||||
t.getFee().should.equal(tx.fee);
|
||||
should.not.exist(t.getChangeOutput());
|
||||
t.toObject().inputs.length.should.equal(tx.inputs.length);
|
||||
t.toObject().outputs[0].satoshis.should.equal(tx.amount);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Backoff time', function(done) {
|
||||
|
@ -3626,7 +3653,6 @@ describe('Wallet service', function() {
|
|||
it('should be able to get send max info on empty wallet', function(done) {
|
||||
server.getSendMaxInfo({
|
||||
feePerKb: 10000,
|
||||
excludeUnconfirmedUtxos: false,
|
||||
}, function(err, info) {
|
||||
should.not.exist(err);
|
||||
should.exist(info);
|
||||
|
@ -3641,7 +3667,6 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [0.1, 0.2, 0.3, 0.4], function() {
|
||||
server.getSendMaxInfo({
|
||||
feePerKb: 10000,
|
||||
excludeUnconfirmedUtxos: false,
|
||||
}, function(err, info) {
|
||||
should.not.exist(err);
|
||||
should.exist(info);
|
||||
|
@ -3698,7 +3723,6 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, ['u0.1', 0.2, 0.3, 0.4, 0.000001, 0.0002, 0.0003], function() {
|
||||
server.getSendMaxInfo({
|
||||
feePerKb: 0.001e8,
|
||||
excludeUnconfirmedUtxos: false,
|
||||
}, function(err, info) {
|
||||
should.not.exist(err);
|
||||
should.exist(info);
|
||||
|
@ -3708,7 +3732,6 @@ describe('Wallet service', function() {
|
|||
info.amount.should.equal(1e8 - info.fee);
|
||||
server.getSendMaxInfo({
|
||||
feePerKb: 0.0001e8,
|
||||
excludeUnconfirmedUtxos: false,
|
||||
}, function(err, info) {
|
||||
should.not.exist(err);
|
||||
should.exist(info);
|
||||
|
@ -3727,7 +3750,6 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, _.range(1, 10, 0), function() {
|
||||
server.getSendMaxInfo({
|
||||
feePerKb: 10000,
|
||||
excludeUnconfirmedUtxos: false,
|
||||
}, function(err, info) {
|
||||
should.not.exist(err);
|
||||
should.exist(info);
|
||||
|
|
Loading…
Reference in New Issue