bitcore-wallet/bin/wallet-send

149 lines
3.6 KiB
JavaScript
Executable File

#!/usr/bin/env node
var program = require('commander');
var utils = require('./cli-utils');
var _ = require('lodash');
var bwc = require('bitcore-wallet-client');
var Bitcore_ = {
bch: bwc.BitcoreCash,
btc: bwc.Bitcore,
};
program = utils.configureCommander(program);
program
.option('--fee <fee-per-kb>', 'Fee per kB to use. Default 100bits.')
.usage('[options] <address> <amount> [note]')
.description('Create a proposal for sending bitcoins to a destination address.\n The amount can be specified in bit, btc or sat (the default).');
program.on('--help', function() {
console.log(' Examples:');
console.log('');
console.log(' $ wallet-send n2HRFgtoihgAhx1qAEXcdBMjoMvAx7AcDc 500bit');
console.log(' $ wallet-send mgWeRvUC6d1LRPKtdDbvYEpaUEmApS4XrY 0.2btc "dinner with friends"');
console.log(' $ wallet-send https://paypro.url/1234 # will ask for confirmation ');
console.log('');
});
program.parse(process.argv);
var args = program.args;
if (!args[0])
program.help();
function confirmDiag(amountStr, note, cb) {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(`Confirm send ${amountStr} to ${note}? (y/N)`, (answer) => {
rl.close();
return cb(answer =='y');
});
};
function send(client, address, amount, fee, note, uri) {
var amount, feePerKb;
try {
feePerKb = !_.isUndefined(fee) ? utils.parseAmount(fee) : 100e2;
} catch (ex) {
utils.die(ex);
}
client.createTxProposal({
outputs: [{
toAddress: address,
amount: amount,
}],
message: note,
feePerKb: feePerKb,
payProUrl: uri,
}, function(err, txp) {
utils.die(err);
client.publishTxProposal({
txp: txp
}, function(err) {
utils.die(err);
console.log(' * Tx created: ID %s [%s] RequiredSignatures:',
utils.shortID(txp.id), txp.status, txp.requiredSignatures);
});
});
};
var arg1 = args[0];
var uri;
utils.getClient(program, {
mustExist: true
}, function(client) {
var coin = client.credentials.coin;
var bitcore = Bitcore_[coin];
var uri, addr, amount, note;
// no backwards compat uri
if ((/^bitcoin(cash)?:\?r=[\w+]/).exec(arg1)) {
var coin2 = 'btc';
if (arg1.indexOf('bitcoincash') === 0) coin2 = 'bch';
if (coin != coin2) utils.die('Wallet / Payment Coin mismatch');
uri = arg1.replace(/bitcoin(cash)?:\?r=/, '');
} else {
// BIP21
try {
var parsed = new bitcore.URI(arg1);
if (!parsed.r) {
addr = parsed.address ? parsed.address.toString() : '';
note = parsed.message;
amount = parsed.amount ? parsed.amount : '';
} else {
uri = parsed.r;
}
} catch (e) {
utils.die(e);
}
}
//Send to URI or addr
if (uri) {
console.log('Fetching Payment from: ' + uri);
client.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
if (err) {
utils.die(' Failed to fetch payment: ' + err);
} else if (!paypro.verified) {
utils.die('Failed to verify payment protocol signatures');
}
var amountStr = utils.renderAmount(paypro.amount, coin);
confirmDiag(amountStr, paypro.memo, function(confirmed) {
if (!confirmed) utils.die('User canceled');
send(client, paypro.toAddress, paypro.amount, program.fee, paypro.memo, uri);
});
});
} else {
// Grab data from CLI if not set before
addr = addr || arg1;
amount = amount || utils.parseAmount(args[1]);
note = note || args[2];
send(client, addr, amount, program.fee, note);
}
});