bitcore-wallet/bin/wallet-support

180 lines
5.8 KiB
JavaScript
Executable File

#!/usr/bin/env node
var _ = require('lodash');
var program = require('commander');
var utils = require('./cli-utils');
var moment = require('moment');
var async = require('async');
program = utils.configureCommander(program);
var N = 100;
program
.option('-t, --testnet', 'Query testnet wallet')
.option('-h, --history', 'Include full tx history')
.option('-f, --full', 'Dont trim output to ' + N + ' items')
.usage('<identifier>')
.parse(process.argv);
var args = program.args;
if (!args[0])
program.help();
var identifier = args[0];
var network = program.testnet ? 'testnet' : 'livenet';
var trim = program.full ? false : true;
var format = (amount, coin) => {
return utils.renderAmount(amount, coin);
};
utils.getClient(program, {
mustExist: true
}, (client) => {
client.getStatusByIdentifier({
identifier: identifier
}, (err, status) => {
utils.die(err);
if (!status) {
console.log('Could not find wallet associated to ' + identifier);
process.exit(0);
}
console.log('Found wallet associated to ' + identifier + '. Querying wallet info...');
utils.getClient(program, {
mustExist: true,
walletId: status.wallet.id,
}, (client) => {
async.parallel([
function(done) {
client.getSendMaxInfo({
returnInputs: true
}, done);
},
function(done) {
client.getMainAddresses({
doNotVerify: true
}, done);
},
function(done) {
client.getTxHistory({}, done);
},
], (err, res) => {
utils.die(err);
displayStatus(status);
if (trim) {
if ((res[1] && res[1].length>N) || (res[2] && res[2].length> N))
console.log('\n Trimming results to %s items', N );
if (res[1] && res[1].length > N)
res[1] = res[1].reverse().splice(0,N);
if (res[2] && res[2].length > N)
res[2] = res[2].splice(0,N);
};
displaySendMaxInfo(res[0], status.wallet);
displayAddresses(res[1], status.wallet);
displayHistory(res[2], status.wallet);
});
});
});
});
function displayStatus(status) {
var w = status.wallet;
console.log('\n* Wallet info');
console.log(' ID: %s Coin:', w.id, w.coin);
console.log(' %s %d-of-%d%s [%s %s] wallet (status: %s)', w.network.toUpperCase(), w.m, w.n, w.singleAddress ? ' single-address' : '', w.derivationStrategy, w.addressType, w.status);
console.log(' Created on: %s', moment(w.createdOn * 1000));
if (w.status != 'complete') {
console.log(' Missing ' + (w.n - w.copayers.length) + ' copayers');
}
var x = status.balance;
console.log('\n* Balance')
console.log(' Total: %s (%s locked)', format(x.totalAmount, w.coin), format(x.lockedAmount, w.coin));
console.log(' Confirmed: %s (%s locked)', format(x.totalConfirmedAmount, w.coin), format(x.lockedConfirmedAmount, w.coin));
console.log(' Available: %s (%s confirmed / %s unconfirmed)', format(x.availableAmount, w.coin), format(x.availableConfirmedAmount, w.coin), format(x.availableAmount - x.availableConfirmedAmount, w.coin));
if (!_.isEmpty(x.byAddress)) {
console.log(' By address:');
}
_.each(x.byAddress, function(item) {
console.log(' %s (%s): %s', item.address, item.path, format(item.amount, w.coin));
});
if (!_.isEmpty(status.pendingTxps)) {
console.log("\n* Pending tx proposals");
_.each(status.pendingTxps, function(x) {
var missingSignatures = x.requiredSignatures - _.filter(_.values(x.actions), function(a) {
return a.type == 'accept';
}).length;
console.log(" [%s] %s (fee/kb %s) => %s (status: %s)", new moment(x.createdOn * 1000), format(x.amount, w.coin), format(x.feePerKb, w.coin), x.outputs[0].toAddress, missingSignatures > 0 ? 'missing ' + missingSignatures + ' signatures' : 'ready to broadcast');
});
} else {
console.log('\n* No pending tx proposals.');
}
};
function displaySendMaxInfo(info, wallet) {
if (info.amount == 0) return;
console.log('\n* Send max');
console.log(' Maximum spendable amount at "normal" fee level (%s per kb): %s', format(info.feePerKb, wallet.coin), format(info.amount, wallet.coin));
if (info.utxosBelowFee > 0) {
console.log(' %s UTXOs for a total amount of %s are currently below fee required to spend them', info.utxosBelowFee, info.amountBelowFee);
}
if (info.utxosAboveMaxSize > 0) {
console.log(' %s UTXOs for a total amount of %s exceed the max allowed tx size', info.utxosAboveMaxSize, info.amountAboveMaxSize);
}
if (!_.isEmpty(info.inputs)) {
console.log(' Available UTXOs:');
}
_.each(info.inputs, function(utxo) {
console.log(' %s%s %s', format(utxo.satoshis, wallet.coin), utxo.locked ? ' (locked)' : '', utxo.confirmations > 0 ? utxo.confirmations + ' confirmations' : 'unconfirmed');
});
};
function displayAddresses(addresses) {
if (_.isEmpty(addresses)) {
console.log('\n* No addresses.');
return;
}
console.log('\n* Main addresses (not including change addresses)');
_.each(addresses, function(a) {
console.log(' [%s] %s (%s)', moment(a.createdOn * 1000), a.address, a.path);
});
};
function displayHistory(history, wallet) {
if (_.isEmpty(history)) {
console.log('\n* No tx history.');
return;
}
console.log("\n* Tx history")
_.each(history, function(tx) {
var time = moment(tx.time * 1000);
var amount = format(tx.amount, wallet.coin);
var confirmations = tx.confirmations || 0;
switch (tx.action) {
case 'received':
direction = '<=';
break;
case 'moved':
direction = '==';
break;
case 'sent':
direction = '=>';
break;
}
console.log(" [%s] %s %s %s %s (fee/kb %s) (%s confirmations)", time, tx.txid, direction, tx.action, amount, format(tx.feePerKb, wallet.coin), confirmations);
});
};