fcoin/bin/bcoin-cli
2016-07-15 18:20:55 -07:00

489 lines
12 KiB
JavaScript
Executable File

#!/usr/bin/env node
'use strict';
var argv = parseArg(process.argv);
var bcoin = require('../').set(argv.network);
var network = bcoin.network.get();
var utils = bcoin.utils;
var assert = utils.assert;
var Client = bcoin.http.client;
var client = new Client(
argv.url
|| process.env.BCOIN_URL
|| 'http://localhost:' + network.rpcPort
);
client.on('error', function(err) {
bcoin.error(err);
});
function getID() {
if (argv.id)
return argv.id;
if (process.env.BCOIN_WALLET_ID)
return process.env.BCOIN_WALLET_ID;
return argv.args.shift();
}
function createWallet(callback) {
var options = { id: getID() };
if (argv.type)
options.type = argv.type;
if (argv.master)
options.master = argv.master;
if (argv.keys)
options.keys = argv.keys.split(/[,:]/);
if (argv.lookahead)
options.lookahead = argv.lookahead >>> 0;
if (argv.m)
options.m = argv.m >>> 0;
if (argv.n)
options.n = argv.n >>> 0;
if (argv.witness != null)
options.witness = !!argv.witness;
if (argv.passphrase)
options.passphrase = argv.passphrase;
client.createWallet(options, function(err, wallet) {
if (err)
return callback(err);
utils.log(wallet);
callback();
});
}
function addKey(callback) {
var id = getID();
var keys = argv.keys || argv.key;
if (keys)
keys = keys.split(',');
else
keys = argv.args;
client.addKey(id, argv.account, keys, function(err, wallet) {
if (err)
return callback(err);
utils.log('added');
callback();
});
}
function createAccount(callback) {
var id = getID();
var account = argv.args[0] || argv.account;
client.createWalletAccount(id, account, function(err, account) {
if (err)
return callback(err);
utils.log(account);
callback();
});
}
function getAccounts(callback) {
var id = getID();
client.getWalletAccounts(id, function(err, accounts) {
if (err)
return callback(err);
utils.log(accounts);
callback();
});
}
function removeKey(callback) {
var id = getID();
var keys = argv.keys || argv.key;
if (keys)
keys = keys.split(',');
else
keys = argv.args;
client.removeKey(id, argv.account, keys, function(err) {
if (err)
return callback(err);
utils.log('removed');
callback();
});
}
function getWallet(callback) {
var id = getID();
var passphrase = argv.args[0];
client.getWallet(id, argv.account, passphrase, function(err, wallet) {
if (err)
return callback(err);
utils.log(wallet);
wallet.destroy();
callback();
});
}
function getTX(callback) {
var hash = argv.args[0];
if (bcoin.address.validate(hash)) {
return client.getTXByAddress(hash, function(err, txs) {
if (err)
return callback(err);
utils.log(txs);
callback();
});
}
hash = utils.revHex(hash);
client.getTX(hash, function(err, tx) {
if (err)
return callback(err);
if (!tx) {
utils.log('TX not found.');
return callback();
}
utils.log(tx);
callback();
});
}
function getBlock(callback) {
var hash = argv.args[0];
if (hash.length !== 64)
hash = +hash;
else
hash = utils.revHex(hash);
client.getBlock(hash, function(err, block) {
if (err)
return callback(err);
if (!block) {
utils.log('Block not found.');
return callback();
}
utils.log(block);
utils.log('Coinbase Data:');
utils.log(block.txs[0].inputs[0].script.getCoinbaseFlags());
callback();
});
}
function getCoin(callback) {
var hash = argv.args[0];
var index = argv.args[1];
if (bcoin.address.validate(hash)) {
return client.getCoinsByAddress(hash, function(err, coins) {
if (err)
return callback(err);
utils.log(coins);
callback();
});
}
hash = utils.revHex(hash);
client.getCoin(hash, index, function(err, coin) {
if (err)
return callback(err);
if (!coin) {
utils.log('Coin not found.');
return callback();
}
utils.log(coin);
callback();
});
}
function getWalletHistory(callback) {
var id = getID();
client.getWalletHistory(id, argv.account, function(err, txs) {
if (err)
return callback(err);
utils.log(txs);
callback();
});
}
function listenWallet(callback) {
var id = getID();
client.join(id);
client.on('tx', function(tx, map) {
utils.log('TX:');
utils.log(tx);
utils.log(map);
});
client.on('updated', function(tx, map) {
utils.log('TX updated:');
utils.log(tx);
utils.log(map);
});
client.on('confirmed', function(tx, map) {
utils.log('TX updated:');
utils.log(tx);
utils.log(map);
});
client.on('address', function(receive, change) {
utils.log('New addresses allocated:');
utils.log(receive);
utils.log(change);
});
client.on('balance', function(tx, map) {
utils.log('Balance:');
utils.log(tx);
utils.log(map);
});
}
function getBalance(callback) {
var id = getID();
client.getWalletBalance(id, argv.account, function(err, balance) {
if (err)
return callback(err);
utils.log('Confirmed: %s', utils.btc(balance.confirmed));
utils.log('Unconfirmed: %s', utils.btc(balance.unconfirmed));
utils.log('Total: %s', utils.btc(balance.total));
callback();
});
}
function getMempool(callback) {
client.getMempool(function(err, txs) {
if (err)
return callback(err);
utils.log(txs);
callback();
});
}
function sendTX(callback) {
var id = getID();
var options = { account: argv.account, passphrase: argv.passphrase };
var output = {};
if (argv.script) {
output.script = new bcoin.script(new Buffer(argv.script, 'hex'));
output.value = utils.satoshi(argv.value || argv.args[0]);
} else {
output.address = argv.address || argv.args[0];
output.value = utils.satoshi(argv.value || argv.args[1]);
}
client.walletSend(id, {outputs:[output]}, function(err, tx) {
if (err)
return callback(err);
utils.log(tx);
utils.log(tx.toRaw('hex'));
callback();
});
}
function createTX(callback) {
var id = getID();
var options = { account: argv.account, passphrase: argv.passphrase };
var output = {};
if (argv.script) {
output.script = new bcoin.script(new Buffer(argv.script, 'hex'));
output.value = utils.satoshi(argv.value || argv.args[0]);
} else {
output.address = argv.address || argv.args[0];
output.value = utils.satoshi(argv.value || argv.args[1]);
}
client.walletCreate(id, options, [output], function(err, tx) {
if (err)
return callback(err);
utils.log(tx);
utils.log(tx.toRaw('hex'));
callback();
});
}
function signTX(callback) {
var id = getID();
var options = { passphrase: argv.passphrase };
var tx = bcoin.tx.fromRaw(options.tx || argv.args[0], 'hex');
client.walletSign(id, tx, options, function(err, tx) {
if (err)
return callback(err);
utils.log(tx);
utils.log(tx.toRaw('hex'));
callback();
});
}
function zap(callback) {
var id = getID();
var age = (argv.age >>> 0) || 72 * 60 * 60;
client.walletZap(id, argv.account, age, function(err) {
if (err)
return callback(err);
utils.log('Zapped!');
callback();
});
}
function broadcast(callback) {
var tx = bcoin.tx.fromRaw(argv.args[0] || argv.tx, 'hex');
client.broadcast(tx, function(err, tx) {
if (err)
return callback(err);
utils.log('Broadcasted:');
utils.log(tx);
callback();
});
}
function view(callback) {
var tx = bcoin.tx.fromRaw(argv.args[0] || argv.tx, 'hex');
client.walletFill(tx, function(err, tx) {
if (err)
return callback(err);
utils.log(tx);
callback();
});
}
function main(callback) {
switch (argv.args.shift()) {
case 'wallet':
return createWallet(callback);
case 'listen':
return listenWallet(callback);
case 'getwallet':
return getWallet(callback);
case 'addkey':
return addKey(callback);
case 'rmkey':
return removeKey(callback);
case 'balance':
return getBalance(callback);
case 'history':
return getWalletHistory(callback);
case 'account':
return createAccount(callback);
case 'accounts':
return getAccounts(callback);
case 'sign':
return signTX(callback);
case 'create':
return createTX(callback);
case 'send':
return sendTX(callback);
case 'zap':
return zap(callback);
case 'broadcast':
return broadcast(callback);
case 'view':
return view(callback);
case 'mempool':
return getMempool(callback);
case 'tx':
return getTX(callback);
case 'coin':
return getCoin(callback);
case 'block':
return getBlock(callback);
default:
utils.log('Unrecognized command.');
utils.log('Commands:');
utils.log(' $ wallet [id] --keys [hdkeys]'
+ ' --type [pubkeyhash/multisig] -m [m-value]'
+ ' -n [n-value] --witness: View or create wallet by ID.');
utils.log(' $ listen [id]: Listen for wallet events.');
utils.log(' $ getwallet [id]: View wallet by ID.');
utils.log(' $ addkey [id] --keys [hdkeys]: Add keys to wallet.');
utils.log(' $ rmkey [id] --keys [hdkeys]: Remove keys from wallet.');
utils.log(' $ balance [id]: Get wallet balance.');
utils.log(' $ history [id]: View wallet TX history.');
utils.log(' $ accounts [id]: List account names.');
utils.log(' $ account [id] [acct]: Get account details.');
utils.log(' $ send [id] [address] [value] --script [code]: Send transaction.');
utils.log(' $ create [id] [address] [value] --script [code]: Create transaction.');
utils.log(' $ sign [id] [tx-hex]: Sign transaction.');
utils.log(' $ zap [id] --age [age]: Zap pending wallet TXs.');
utils.log(' $ broadcast [tx-hex]: Broadcast transaction.');
utils.log(' $ view [tx-hex]: View transaction.');
utils.log(' $ mempool: Get mempool snapshot.');
utils.log(' $ tx [hash/address]: View transactions.');
utils.log(' $ coin [hash+index/address]: View coins.');
utils.log(' $ block [hash/height]: View block.');
utils.log('Other Options:');
utils.log(' --passphrase [passphrase]: For signing and account creation.');
utils.log(' --account [acctname]: Account name.');
return callback();
}
}
function parseArg(argv) {
var args = [];
var options = {};
var arg, negate;
argv = argv.slice();
function getarg() {
var arg = argv.shift();
if (arg.indexOf('--') === 0) {
// e.g. --opt
arg = arg.split('=');
if (arg.length > 1) {
// e.g. --opt=val
argv.unshift(arg.slice(1).join('='));
}
arg = arg[0];
} else if (arg[0] === '-') {
if (arg.length > 2) {
// e.g. -abc
argv = arg.substring(1).split('').map(function(ch) {
return '-' + ch;
}).concat(argv);
arg = argv.shift();
} else {
// e.g. -a
}
} else {
// e.g. foo
}
return arg;
}
while (argv.length) {
arg = getarg();
if (arg.indexOf('--') === 0) {
negate = arg.indexOf('--no-') === 0;
opt = arg.replace(/^--(no-)?/, '');
options[opt] = !argv[0] || argv[0][0] === '-'
? (negate ? false : true)
: argv.shift();
} else {
args.push(arg);
}
}
options.args = args.slice(2);
return options;
}
client.getInfo(function(err, info) {
if (err) {
console.error(err.stack + '');
//return process.exit(1);
}
if (!argv.args[0])
utils.log(info);
main(function(err) {
if (err) {
console.error(err.stack + '');
return process.exit(1);
}
client.destroy();
});
});