http: api refactor.
This commit is contained in:
parent
cbed60e900
commit
2b630ad99c
15
bin/bcoin
15
bin/bcoin
@ -2,7 +2,6 @@
|
||||
|
||||
rl=0
|
||||
daemon=0
|
||||
cli=0
|
||||
cmd='node'
|
||||
|
||||
if ! type perl > /dev/null 2>& 1; then
|
||||
@ -25,7 +24,14 @@ dir=$(dirname "$file")
|
||||
|
||||
if test x"$1" = x'cli'; then
|
||||
shift
|
||||
cli=1
|
||||
exec "${dir}/cli" "$@"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test x"$1" = x'rpc'; then
|
||||
shift
|
||||
exec "${dir}/cli" rpc "$@"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for arg in "$@"; do
|
||||
@ -39,11 +45,6 @@ for arg in "$@"; do
|
||||
esac
|
||||
done
|
||||
|
||||
if test $cli -eq 1; then
|
||||
exec "${dir}/cli" "$@"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $daemon -eq 1; then
|
||||
if ! type setsid > /dev/null 2>& 1; then
|
||||
echo 'BCoin requires setsid to start as a daemon.' >& 2
|
||||
|
||||
735
bin/cli
735
bin/cli
@ -2,487 +2,564 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var argv = parseArg(process.argv);
|
||||
|
||||
var bcoin = require('../').set(argv.network);
|
||||
var network = bcoin.network.get();
|
||||
var utils = bcoin.utils;
|
||||
var config = require('../lib/bcoin/config');
|
||||
var utils = require('../lib/bcoin/utils');
|
||||
var Client = require('../lib/bcoin/http/client');
|
||||
var Wallet = require('../lib/bcoin/http/wallet');
|
||||
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) {
|
||||
;
|
||||
});
|
||||
|
||||
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 CLI() {
|
||||
this.config = config({
|
||||
config: true,
|
||||
arg: true,
|
||||
env: true,
|
||||
network: 'main'
|
||||
}).data;
|
||||
this.argv = this.config.args;
|
||||
this.client = null;
|
||||
this.wallet = null;
|
||||
}
|
||||
|
||||
function createWallet(callback) {
|
||||
var options = { id: getID() };
|
||||
CLI.prototype.log = function log(json) {
|
||||
if (typeof json === 'string')
|
||||
return console.log.apply(console, arguments);
|
||||
console.log(JSON.stringify(json, null, 2));
|
||||
};
|
||||
|
||||
if (argv.type)
|
||||
options.type = argv.type;
|
||||
CLI.prototype.createWallet = function createWallet(callback) {
|
||||
var options = { id: this.config.id };
|
||||
|
||||
if (argv.master)
|
||||
options.master = argv.master;
|
||||
if (this.config.type)
|
||||
options.type = this.config.type;
|
||||
|
||||
if (argv.keys)
|
||||
options.keys = argv.keys.split(/[,:]/);
|
||||
if (this.config.master)
|
||||
options.master = this.config.master;
|
||||
|
||||
if (argv.lookahead)
|
||||
options.lookahead = argv.lookahead >>> 0;
|
||||
if (this.config.keys)
|
||||
options.keys = this.config.keys.split(/[,:]/);
|
||||
|
||||
if (argv.m)
|
||||
options.m = argv.m >>> 0;
|
||||
if (this.config.m)
|
||||
options.m = this.config.m >>> 0;
|
||||
|
||||
if (argv.n)
|
||||
options.n = argv.n >>> 0;
|
||||
if (this.config.n)
|
||||
options.n = this.config.n >>> 0;
|
||||
|
||||
if (argv.witness != null)
|
||||
options.witness = !!argv.witness;
|
||||
if (this.config.witness != null)
|
||||
options.witness = !!this.config.witness;
|
||||
|
||||
if (argv.passphrase)
|
||||
options.passphrase = argv.passphrase;
|
||||
if (this.config.passphrase)
|
||||
options.passphrase = this.config.passphrase;
|
||||
|
||||
client.createWallet(options, function(err, wallet) {
|
||||
this.client.createWallet(options, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(wallet);
|
||||
self.log(wallet);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function addKey(callback) {
|
||||
var id = getID();
|
||||
var keys = argv.keys || argv.key;
|
||||
CLI.prototype.addKey = function addKey(callback) {
|
||||
var self = this;
|
||||
var keys = this.config.keys || this.config.key;
|
||||
if (keys)
|
||||
keys = keys.split(',');
|
||||
else
|
||||
keys = argv.args;
|
||||
client.addKey(id, argv.account, keys, function(err, wallet) {
|
||||
keys = this.argv;
|
||||
this.wallet.addKey(this.config.account, keys, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log('added');
|
||||
self.log('added');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function createAccount(callback) {
|
||||
var id = getID();
|
||||
var account = argv.args[0] || argv.account;
|
||||
client.createWalletAccount(id, account, function(err, account) {
|
||||
CLI.prototype.createAccount = function createAccount(callback) {
|
||||
var self = this;
|
||||
var account = this.argv[0] || this.config.account;
|
||||
this.wallet.createAccount(account, function(err, account) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(account);
|
||||
self.log(account);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getAccounts(callback) {
|
||||
var id = getID();
|
||||
client.getWalletAccounts(id, function(err, accounts) {
|
||||
CLI.prototype.getAccount = function getAccount(callback) {
|
||||
var self = this;
|
||||
var account = this.argv[0] || this.config.account;
|
||||
this.wallet.getAccount(account, function(err, account) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(accounts);
|
||||
self.log(account);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function removeKey(callback) {
|
||||
var id = getID();
|
||||
var keys = argv.keys || argv.key;
|
||||
CLI.prototype.getAccounts = function getAccounts(callback) {
|
||||
var self = this;
|
||||
this.wallet.getAccounts(function(err, accounts) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.log(accounts);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
CLI.prototype.removeKey = function removeKey(callback) {
|
||||
var self = this;
|
||||
var keys = this.config.keys || this.config.key;
|
||||
if (keys)
|
||||
keys = keys.split(',');
|
||||
else
|
||||
keys = argv.args;
|
||||
client.removeKey(id, argv.account, keys, function(err) {
|
||||
keys = this.argv;
|
||||
this.wallet.removeKey(this.config.account, keys, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log('removed');
|
||||
self.log('removed');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getWallet(callback) {
|
||||
var id = getID();
|
||||
var passphrase = argv.args[0];
|
||||
client.getWallet(id, argv.account, passphrase, function(err, wallet) {
|
||||
CLI.prototype.getWallet = function getWallet(callback) {
|
||||
var self = this;
|
||||
var passphrase = this.argv[0];
|
||||
this.wallet.getInfo(this.config.account, passphrase, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(wallet);
|
||||
wallet.destroy();
|
||||
self.log(wallet);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getTX(callback) {
|
||||
var hash = argv.args[0];
|
||||
if (bcoin.address.validate(hash)) {
|
||||
return client.getTXByAddress(hash, function(err, txs) {
|
||||
CLI.prototype.getTX = function getTX(callback) {
|
||||
var self = this;
|
||||
var hash = this.argv[0];
|
||||
if (utils.isBase58(hash)) {
|
||||
return this.client.getTXByAddress(hash, function(err, txs) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(txs);
|
||||
self.log(txs);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
hash = utils.revHex(hash);
|
||||
client.getTX(hash, function(err, tx) {
|
||||
this.client.getTX(hash, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!tx) {
|
||||
utils.log('TX not found.');
|
||||
self.log('TX not found.');
|
||||
return callback();
|
||||
}
|
||||
|
||||
utils.log(tx);
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getBlock(callback) {
|
||||
var hash = argv.args[0];
|
||||
CLI.prototype.getBlock = function getBlock(callback) {
|
||||
var self = this;
|
||||
var hash = this.argv[0];
|
||||
if (hash.length !== 64)
|
||||
hash = +hash;
|
||||
else
|
||||
hash = utils.revHex(hash);
|
||||
client.getBlock(hash, function(err, block) {
|
||||
this.client.getBlock(hash, function(err, block) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!block) {
|
||||
utils.log('Block not found.');
|
||||
self.log('Block not found.');
|
||||
return callback();
|
||||
}
|
||||
|
||||
utils.log(block);
|
||||
utils.log('Coinbase Data:');
|
||||
utils.log(block.txs[0].inputs[0].script.getCoinbaseFlags());
|
||||
self.log(block);
|
||||
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) {
|
||||
CLI.prototype.getCoin = function getCoin(callback) {
|
||||
var self = this;
|
||||
var hash = this.argv[0];
|
||||
var index = this.argv[1];
|
||||
if (utils.isBase58(hash)) {
|
||||
return this.client.getCoinsByAddress(hash, function(err, coins) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(coins);
|
||||
self.log(coins);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
hash = utils.revHex(hash);
|
||||
client.getCoin(hash, index, function(err, coin) {
|
||||
this.client.getCoin(hash, index, function(err, coin) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!coin) {
|
||||
utils.log('Coin not found.');
|
||||
self.log('Coin not found.');
|
||||
return callback();
|
||||
}
|
||||
|
||||
utils.log(coin);
|
||||
self.log(coin);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getWalletHistory(callback) {
|
||||
var id = getID();
|
||||
client.getWalletHistory(id, argv.account, function(err, txs) {
|
||||
CLI.prototype.getWalletHistory = function getWalletHistory(callback) {
|
||||
var self = this;
|
||||
this.wallet.getHistory(this.config.account, function(err, txs) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(txs);
|
||||
self.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);
|
||||
CLI.prototype.listenWallet = function listenWallet(callback) {
|
||||
var self = this;
|
||||
this.wallet.on('tx', function(details) {
|
||||
self.log('TX:');
|
||||
self.log(details);
|
||||
});
|
||||
client.on('updated', function(tx, map) {
|
||||
utils.log('TX updated:');
|
||||
utils.log(tx);
|
||||
utils.log(map);
|
||||
this.wallet.on('confirmed', function(details) {
|
||||
self.log('TX confirmed:');
|
||||
self.log(details);
|
||||
});
|
||||
client.on('confirmed', function(tx, map) {
|
||||
utils.log('TX updated:');
|
||||
utils.log(tx);
|
||||
utils.log(map);
|
||||
this.wallet.on('unconfirmed', function(details) {
|
||||
self.log('TX unconfirmed:');
|
||||
self.log(details);
|
||||
});
|
||||
client.on('address', function(receive, change) {
|
||||
utils.log('New addresses allocated:');
|
||||
utils.log(receive);
|
||||
utils.log(change);
|
||||
this.wallet.on('conflict', function(details) {
|
||||
self.log('TX conflict:');
|
||||
self.log(details);
|
||||
});
|
||||
client.on('balance', function(tx, map) {
|
||||
utils.log('Balance:');
|
||||
utils.log(tx);
|
||||
utils.log(map);
|
||||
this.wallet.on('address', function(receive) {
|
||||
self.log('New addresses allocated:');
|
||||
self.log(receive);
|
||||
});
|
||||
}
|
||||
this.wallet.on('balance', function(balance) {
|
||||
self.log('Balance:');
|
||||
self.log(balance);
|
||||
});
|
||||
};
|
||||
|
||||
function getBalance(callback) {
|
||||
var id = getID();
|
||||
client.getWalletBalance(id, argv.account, function(err, balance) {
|
||||
CLI.prototype.getBalance = function getBalance(callback) {
|
||||
var self = this;
|
||||
this.wallet.getBalance(this.config.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));
|
||||
self.log(balance);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getMempool(callback) {
|
||||
client.getMempool(function(err, txs) {
|
||||
CLI.prototype.getMempool = function getMempool(callback) {
|
||||
var self = this;
|
||||
this.client.getMempool(function(err, txs) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(txs);
|
||||
self.log(txs);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function sendTX(callback) {
|
||||
var id = getID();
|
||||
var options = { account: argv.account, passphrase: argv.passphrase };
|
||||
CLI.prototype.sendTX = function sendTX(callback) {
|
||||
var self = this;
|
||||
var output = {};
|
||||
if (argv.script) {
|
||||
output.script = new bcoin.script(new Buffer(argv.script, 'hex'));
|
||||
output.value = utils.satoshi(argv.value || argv.args[0]);
|
||||
if (this.config.script) {
|
||||
output.script = this.config.script;
|
||||
output.value = utils.satoshi(this.config.value || this.argv[0]);
|
||||
} else {
|
||||
output.address = argv.address || argv.args[0];
|
||||
output.value = utils.satoshi(argv.value || argv.args[1]);
|
||||
output.address = this.config.address || this.argv[0];
|
||||
output.value = utils.satoshi(this.config.value || this.argv[1]);
|
||||
}
|
||||
client.walletSend(id, {outputs:[output]}, function(err, tx) {
|
||||
var options = {
|
||||
account: this.config.account,
|
||||
passphrase: this.config.passphrase,
|
||||
outputs: [output]
|
||||
};
|
||||
this.wallet.send(options, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(tx);
|
||||
utils.log(tx.toRaw('hex'));
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function createTX(callback) {
|
||||
var id = getID();
|
||||
var options = { account: argv.account, passphrase: argv.passphrase };
|
||||
CLI.prototype.createTX = function createTX(callback) {
|
||||
var self = this;
|
||||
var options = { account: this.config.account, passphrase: this.config.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]);
|
||||
if (this.config.script) {
|
||||
output.script = this.config.script;
|
||||
output.value = utils.satoshi(this.config.value || this.argv[0]);
|
||||
} else {
|
||||
output.address = argv.address || argv.args[0];
|
||||
output.value = utils.satoshi(argv.value || argv.args[1]);
|
||||
output.address = this.config.address || this.argv[0];
|
||||
output.value = utils.satoshi(this.config.value || this.argv[1]);
|
||||
}
|
||||
client.walletCreate(id, options, [output], function(err, tx) {
|
||||
options.outputs = [output];
|
||||
this.wallet.createTX(options, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(tx);
|
||||
utils.log(tx.toRaw('hex'));
|
||||
self.log(tx);
|
||||
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) {
|
||||
CLI.prototype.signTX = function signTX(callback) {
|
||||
var self = this;
|
||||
var options = { passphrase: this.config.passphrase };
|
||||
var tx = options.tx || this.argv[0];
|
||||
this.wallet.sign(tx, options, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(tx);
|
||||
utils.log(tx.toRaw('hex'));
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function zap(callback) {
|
||||
var id = getID();
|
||||
var age = (argv.age >>> 0) || 72 * 60 * 60;
|
||||
client.walletZap(id, argv.account, age, function(err) {
|
||||
CLI.prototype.zap = function zap(callback) {
|
||||
var self = this;
|
||||
var age = (this.config.age >>> 0) || 72 * 60 * 60;
|
||||
this.wallet.zap(this.config.account, age, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log('Zapped!');
|
||||
self.log('Zapped!');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function broadcast(callback) {
|
||||
var tx = bcoin.tx.fromRaw(argv.args[0] || argv.tx, 'hex');
|
||||
client.broadcast(tx, function(err, tx) {
|
||||
CLI.prototype.broadcast = function broadcast(callback) {
|
||||
var self = this;
|
||||
var tx = this.argv[0] || this.config.tx;
|
||||
this.client.broadcast(tx, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log('Broadcasted:');
|
||||
utils.log(tx);
|
||||
self.log('Broadcasted:');
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function view(callback) {
|
||||
var tx = bcoin.tx.fromRaw(argv.args[0] || argv.tx, 'hex');
|
||||
client.walletFill(tx, function(err, tx) {
|
||||
CLI.prototype.viewTX = function viewTX(callback) {
|
||||
var self = this;
|
||||
var tx = this.argv[0] || this.config.tx;
|
||||
this.wallet.fill(tx, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
utils.log(tx);
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
CLI.prototype.getDetails = function getDetails(callback) {
|
||||
var self = this;
|
||||
var hash = this.argv[0];
|
||||
this.wallet.getTX(hash, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.log(tx);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
CLI.prototype.rpc = function rpc(callback) {
|
||||
var self = this;
|
||||
var method = this.argv.shift();
|
||||
var params = [];
|
||||
var i, arg, param;
|
||||
|
||||
for (i = 0; i < this.argv.length; i++) {
|
||||
arg = this.argv[i];
|
||||
try {
|
||||
param = JSON.parse(arg);
|
||||
} catch (e) {
|
||||
param = arg;
|
||||
}
|
||||
params.push(param);
|
||||
}
|
||||
|
||||
this.client.rpc.call(method, params, function(err, result) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.log(result);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
CLI.prototype.handleWallet = function handleWallet(callback) {
|
||||
var self = this;
|
||||
|
||||
var options = {
|
||||
id: this.config.id,
|
||||
token: this.config.token
|
||||
};
|
||||
|
||||
this.wallet = new Wallet({
|
||||
uri: this.config.url || this.config.uri,
|
||||
apiKey: this.config.apiKey
|
||||
});
|
||||
|
||||
this.wallet.open(options, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
switch (self.argv.shift()) {
|
||||
case 'listen':
|
||||
return self.listenWallet(callback);
|
||||
case 'get':
|
||||
return self.getWallet(callback);
|
||||
case 'addkey':
|
||||
return self.addKey(callback);
|
||||
case 'rmkey':
|
||||
return self.removeKey(callback);
|
||||
case 'balance':
|
||||
return self.getBalance(callback);
|
||||
case 'history':
|
||||
return self.getWalletHistory(callback);
|
||||
case 'account':
|
||||
if (self.argv[0] === 'create') {
|
||||
self.argv.shift();
|
||||
return self.createAccount(callback);
|
||||
}
|
||||
return self.getAccount(callback);
|
||||
case 'accounts':
|
||||
return self.getAccounts(callback);
|
||||
case 'sign':
|
||||
return self.signTX(callback);
|
||||
case 'mktx':
|
||||
return self.createTX(callback);
|
||||
case 'send':
|
||||
return self.sendTX(callback);
|
||||
case 'zap':
|
||||
return self.zap(callback);
|
||||
case 'tx':
|
||||
return self.getDetails(callback);
|
||||
case 'view':
|
||||
return self.viewTX(callback);
|
||||
default:
|
||||
self.log('Unrecognized command.');
|
||||
self.log('Commands:');
|
||||
self.log(' $ wallet [id] --keys [hdkeys]'
|
||||
+ ' --type [pubkeyhash/multisig] -m [m-value]'
|
||||
+ ' -n [n-value] --witness: View or create wallet by ID.');
|
||||
self.log(' $ listen [id]: Listen for wallet events.');
|
||||
self.log(' $ getwallet [id]: View wallet by ID.');
|
||||
self.log(' $ addkey [id] --keys [hdkeys]: Add keys to wallet.');
|
||||
self.log(' $ rmkey [id] --keys [hdkeys]: Remove keys from wallet.');
|
||||
self.log(' $ balance [id]: Get wallet balance.');
|
||||
self.log(' $ history [id]: View wallet TX history.');
|
||||
self.log(' $ accounts [id]: List account names.');
|
||||
self.log(' $ account [id] [acct]: Get account details.');
|
||||
self.log(' $ send [id] [address] [value] --script [code]: Send transaction.');
|
||||
self.log(' $ create [id] [address] [value] --script [code]: Create transaction.');
|
||||
self.log(' $ sign [id] [tx-hex]: Sign transaction.');
|
||||
self.log(' $ zap [id] --age [age]: Zap pending wallet TXs.');
|
||||
self.log(' $ broadcast [tx-hex]: Broadcast transaction.');
|
||||
self.log(' $ view [tx-hex]: View transaction.');
|
||||
self.log(' $ mempool: Get mempool snapshot.');
|
||||
self.log(' $ tx [hash/address]: View transactions.');
|
||||
self.log(' $ coin [hash+index/address]: View coins.');
|
||||
self.log(' $ block [hash/height]: View block.');
|
||||
self.log('Other Options:');
|
||||
self.log(' --passphrase [passphrase]: For signing and account creation.');
|
||||
self.log(' --account [acctname]: Account name.');
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
CLI.prototype.handleNode = function handleNode(callback) {
|
||||
var self = this;
|
||||
|
||||
this.client = new Client({
|
||||
uri: this.config.url || this.config.uri,
|
||||
apiKey: this.config.apiKey
|
||||
});
|
||||
|
||||
this.client.getInfo(function(err, info) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
switch (self.argv.shift()) {
|
||||
case 'mkwallet':
|
||||
return self.createWallet(callback);
|
||||
case 'broadcast':
|
||||
return self.broadcast(callback);
|
||||
case 'mempool':
|
||||
return self.getMempool(callback);
|
||||
case 'tx':
|
||||
return self.getTX(callback);
|
||||
case 'coin':
|
||||
return self.getCoin(callback);
|
||||
case 'block':
|
||||
return self.getBlock(callback);
|
||||
case 'rpc':
|
||||
return self.rpc(callback);
|
||||
default:
|
||||
self.log('Unrecognized command.');
|
||||
self.log('Commands:');
|
||||
self.log(' $ wallet [id] --keys [hdkeys]'
|
||||
+ ' --type [pubkeyhash/multisig] -m [m-value]'
|
||||
+ ' -n [n-value] --witness: View or create wallet by ID.');
|
||||
self.log(' $ listen [id]: Listen for wallet events.');
|
||||
self.log(' $ getwallet [id]: View wallet by ID.');
|
||||
self.log(' $ addkey [id] --keys [hdkeys]: Add keys to wallet.');
|
||||
self.log(' $ rmkey [id] --keys [hdkeys]: Remove keys from wallet.');
|
||||
self.log(' $ balance [id]: Get wallet balance.');
|
||||
self.log(' $ history [id]: View wallet TX history.');
|
||||
self.log(' $ accounts [id]: List account names.');
|
||||
self.log(' $ account [id] [acct]: Get account details.');
|
||||
self.log(' $ send [id] [address] [value] --script [code]: Send transaction.');
|
||||
self.log(' $ create [id] [address] [value] --script [code]: Create transaction.');
|
||||
self.log(' $ sign [id] [tx-hex]: Sign transaction.');
|
||||
self.log(' $ zap [id] --age [age]: Zap pending wallet TXs.');
|
||||
self.log(' $ broadcast [tx-hex]: Broadcast transaction.');
|
||||
self.log(' $ view [tx-hex]: View transaction.');
|
||||
self.log(' $ mempool: Get mempool snapshot.');
|
||||
self.log(' $ tx [hash/address]: View transactions.');
|
||||
self.log(' $ coin [hash+index/address]: View coins.');
|
||||
self.log(' $ block [hash/height]: View block.');
|
||||
self.log('Other Options:');
|
||||
self.log(' --passphrase [passphrase]: For signing and account creation.');
|
||||
self.log(' --account [acctname]: Account name.');
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
CLI.prototype.open = function open(callback) {
|
||||
switch (this.argv[0]) {
|
||||
case 'w':
|
||||
case 'wallet':
|
||||
this.argv.shift();
|
||||
if (this.argv[0] === 'create') {
|
||||
this.argv[0] = 'mkwallet';
|
||||
return this.handleNode(callback);
|
||||
}
|
||||
return this.handleWallet(callback);
|
||||
default:
|
||||
return this.handleNode(callback);
|
||||
}
|
||||
};
|
||||
|
||||
CLI.prototype.destroy = function destroy(callback) {
|
||||
if (this.wallet)
|
||||
this.wallet.destroy();
|
||||
if (this.client)
|
||||
this.client.destroy();
|
||||
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();
|
||||
}
|
||||
var cli = new CLI();
|
||||
cli.open(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
cli.destroy(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) {
|
||||
main(function(err) {
|
||||
if (err) {
|
||||
console.error(err.stack + '');
|
||||
//return process.exit(1);
|
||||
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();
|
||||
});
|
||||
return process.exit(0);
|
||||
});
|
||||
|
||||
@ -172,6 +172,8 @@ config.parseData = function parseData(data) {
|
||||
options.walletAuth = bool(data.walletauth);
|
||||
options.noAuth = bool(data.noauth);
|
||||
|
||||
options.data = data;
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
@ -245,13 +247,13 @@ config.parseText = function parseText(text) {
|
||||
*/
|
||||
|
||||
config.parseArg = function parseArg(argv) {
|
||||
var data = {};
|
||||
var i, arg, key, value, alias;
|
||||
var data = { args: [] };
|
||||
var i, arg, key, value, alias, equals;
|
||||
|
||||
if (!argv)
|
||||
argv = process.argv;
|
||||
|
||||
argv = argv.slice();
|
||||
argv = argv.slice(2);
|
||||
|
||||
while (argv.length) {
|
||||
arg = argv.shift();
|
||||
@ -264,8 +266,10 @@ config.parseArg = function parseArg(argv) {
|
||||
if (arg.length > 1) {
|
||||
// e.g. --opt=val
|
||||
value = arg.slice(1).join('=').trim();
|
||||
equals = true;
|
||||
} else {
|
||||
value = 'true';
|
||||
equals = false;
|
||||
}
|
||||
|
||||
key = key.replace(/\-/g, '');
|
||||
@ -292,19 +296,23 @@ config.parseArg = function parseArg(argv) {
|
||||
if (alias)
|
||||
key = alias;
|
||||
data[key] = 'true';
|
||||
equals = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// e.g. foo
|
||||
if (key) {
|
||||
value = arg.trim();
|
||||
value = arg.trim();
|
||||
|
||||
if (value.length === 0)
|
||||
continue;
|
||||
if (value.length === 0)
|
||||
continue;
|
||||
|
||||
if (key && !equals) {
|
||||
data[key] = value;
|
||||
key = null;
|
||||
} else {
|
||||
data.args.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,8 +7,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var bcoin = require('../env');
|
||||
var Network = require('../network');
|
||||
var AsyncObject = require('../async');
|
||||
var RPCClient = require('./rpcclient');
|
||||
var utils = require('../utils');
|
||||
var assert = utils.assert;
|
||||
var request = require('./request');
|
||||
@ -34,12 +35,13 @@ function HTTPClient(options) {
|
||||
AsyncObject.call(this);
|
||||
|
||||
this.options = options;
|
||||
this.network = bcoin.network.get(options.network);
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
this.uri = options.uri || 'http://localhost:' + this.network.rpcPort;
|
||||
this.socket = null;
|
||||
this.apiKey = options.apiKey;
|
||||
this.auth = options.auth;
|
||||
this.rpc = new RPCClient(options);
|
||||
|
||||
if (this.apiKey) {
|
||||
if (typeof this.apiKey === 'string') {
|
||||
@ -110,9 +112,6 @@ HTTPClient.prototype._open = function _open(callback) {
|
||||
});
|
||||
|
||||
this.socket.on('wallet address', function(receive) {
|
||||
receive = receive.map(function(address) {
|
||||
return bcoin.keyring.fromJSON(address);
|
||||
});
|
||||
self.emit('address', receive);
|
||||
});
|
||||
|
||||
@ -126,7 +125,8 @@ HTTPClient.prototype._open = function _open(callback) {
|
||||
});
|
||||
|
||||
this.socket.on('connect', function() {
|
||||
self.socket.emit('auth', self.apiKey.toString('hex'), function(err) {
|
||||
var apiKey = self.apiKey ? self.apiKey.toString('hex') : null;
|
||||
self.socket.emit('auth', apiKey, function(err) {
|
||||
if (err)
|
||||
return callback(new Error(err.error));
|
||||
callback();
|
||||
@ -350,23 +350,7 @@ HTTPClient.prototype.getWalletHistory = function getWalletHistory(id, account, c
|
||||
|
||||
options = { account: account };
|
||||
|
||||
return this._get('/wallet/' + id + '/tx/history', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/tx/history', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -385,23 +369,7 @@ HTTPClient.prototype.getWalletCoins = function getWalletCoins(id, account, callb
|
||||
|
||||
options = { account: account };
|
||||
|
||||
return this._get('/wallet/' + id + '/coin', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.coin.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/coin', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -420,23 +388,7 @@ HTTPClient.prototype.getWalletUnconfirmed = function getUnconfirmed(id, account,
|
||||
|
||||
options = { account: account };
|
||||
|
||||
return this._get('/wallet/' + id + '/tx/unconfirmed', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/tx/unconfirmed', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -455,20 +407,7 @@ HTTPClient.prototype.getWalletBalance = function getBalance(id, account, callbac
|
||||
|
||||
options = { account: account };
|
||||
|
||||
return this._get('/wallet/' + id + '/balance', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(new Error('Not found.'));
|
||||
|
||||
return callback(null, {
|
||||
id: body.id,
|
||||
confirmed: utils.satoshi(body.confirmed),
|
||||
unconfirmed: utils.satoshi(body.unconfirmed),
|
||||
total: utils.satoshi(body.total)
|
||||
});
|
||||
});
|
||||
return this._get('/wallet/' + id + '/balance', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -488,23 +427,7 @@ HTTPClient.prototype.getWalletLast = function getWalletLast(id, account, limit,
|
||||
|
||||
options = { account: account, limit: limit };
|
||||
|
||||
return this._get('/wallet/' + id + '/tx/last', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/tx/last', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -533,23 +456,7 @@ HTTPClient.prototype.getWalletRange = function getWalletRange(id, account, optio
|
||||
reverse: options.reverse
|
||||
};
|
||||
|
||||
return this._get('/wallet/' + id + '/tx/range', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/tx/range', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -571,23 +478,7 @@ HTTPClient.prototype.getWalletTX = function getTX(id, account, hash, callback) {
|
||||
|
||||
options = { account: account };
|
||||
|
||||
hash = utils.revHex(hash);
|
||||
|
||||
return this._get('/wallet/' + id + '/tx/' + hash, options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/wallet/' + id + '/tx/' + hash, options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -611,24 +502,9 @@ HTTPClient.prototype.getWalletCoin = function getCoin(id, account, hash, index,
|
||||
|
||||
options = { account: account };
|
||||
|
||||
hash = utils.revHex(hash);
|
||||
path = '/wallet/' + id + '/coin/' + hash + '/' + index;
|
||||
|
||||
return this._get(path, options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
try {
|
||||
body = bcoin.coin.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get(path, options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -641,23 +517,7 @@ HTTPClient.prototype.getWalletCoin = function getCoin(id, account, hash, index,
|
||||
HTTPClient.prototype.getCoinsByAddress = function getCoinsByAddress(address, callback) {
|
||||
var body = { addresses: address };
|
||||
|
||||
return this._post('/coin/address', body, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.coin.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/coin/address', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -669,23 +529,7 @@ HTTPClient.prototype.getCoinsByAddress = function getCoinsByAddress(address, cal
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
hash = utils.revHex(hash);
|
||||
|
||||
return this._get('/coin/' + hash + '/' + index, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
try {
|
||||
body = bcoin.coin.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/coin/' + hash + '/' + index, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -698,23 +542,7 @@ HTTPClient.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
HTTPClient.prototype.getTXByAddress = function getTXByAddress(address, callback) {
|
||||
var body = { addresses: address };
|
||||
|
||||
return this._post('/tx/address', body, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/tx/address', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -724,23 +552,7 @@ HTTPClient.prototype.getTXByAddress = function getTXByAddress(address, callback)
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.getTX = function getTX(hash, callback) {
|
||||
hash = utils.revHex(hash);
|
||||
|
||||
return this._get('/tx/' + hash, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/tx/' + hash, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -750,24 +562,7 @@ HTTPClient.prototype.getTX = function getTX(hash, callback) {
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.getBlock = function getBlock(hash, callback) {
|
||||
if (typeof hash !== 'number')
|
||||
hash = utils.revHex(hash);
|
||||
|
||||
return this._get('/block/' + hash, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
try {
|
||||
body = bcoin.block.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/block/' + hash, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -781,11 +576,7 @@ HTTPClient.prototype.broadcast = function broadcast(tx, callback) {
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/broadcast', body, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
return callback();
|
||||
});
|
||||
return this._post('/broadcast', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -816,18 +607,7 @@ HTTPClient.prototype.walletSend = function walletSend(id, options, callback) {
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/send', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/wallet/' + id + '/send', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -890,18 +670,7 @@ HTTPClient.prototype.walletCreate = function walletCreate(id, options, callback)
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/create', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/wallet/' + id + '/create', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -926,18 +695,7 @@ HTTPClient.prototype.walletSign = function walletCreate(id, tx, options, callbac
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/sign', body, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/wallet/' + id + '/sign', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -951,18 +709,7 @@ HTTPClient.prototype.walletFill = function walletFill(tx, callback) {
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/_/fill', body, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
try {
|
||||
body = bcoin.tx.fromJSON(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post('/wallet/_/fill', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -990,11 +737,7 @@ HTTPClient.prototype.walletZap = function walletZap(id, account, age, callback)
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/zap', body, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
return callback();
|
||||
});
|
||||
return this._post('/wallet/' + id + '/zap', body, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1020,11 +763,7 @@ HTTPClient.prototype.addKey = function addKey(id, account, key, callback) {
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._put('/wallet/' + id + '/key', options, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
return callback();
|
||||
});
|
||||
return this._put('/wallet/' + id + '/key', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1050,11 +789,7 @@ HTTPClient.prototype.removeKey = function removeKey(id, account, key, callback)
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._del('/wallet/' + id + '/key', options, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
return callback();
|
||||
});
|
||||
return this._del('/wallet/' + id + '/key', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1065,15 +800,7 @@ HTTPClient.prototype.removeKey = function removeKey(id, account, key, callback)
|
||||
|
||||
HTTPClient.prototype.getWalletAccounts = function getWalletAccounts(id, callback) {
|
||||
var path = '/wallet/' + id + '/account';
|
||||
return this._get(path, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get(path, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1099,15 +826,7 @@ HTTPClient.prototype.createWalletAccount = function createWalletAccount(id, opti
|
||||
|
||||
path = '/wallet/' + id + '/account';
|
||||
|
||||
return this._post(path, options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._post(path, options, callback);
|
||||
};
|
||||
|
||||
|
||||
@ -1117,23 +836,7 @@ HTTPClient.prototype.createWalletAccount = function createWalletAccount(id, opti
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.getMempool = function getMempool(callback) {
|
||||
return this._get('/mempool', function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(null, []);
|
||||
|
||||
try {
|
||||
body = body.map(function(data) {
|
||||
return bcoin.tx.fromJSON(data);
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/mempool', callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1142,15 +845,7 @@ HTTPClient.prototype.getMempool = function getMempool(callback) {
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.getInfo = function getInfo(callback) {
|
||||
return this._get('/', function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback(new Error('Info not available.'));
|
||||
|
||||
return callback(null, body);
|
||||
});
|
||||
return this._get('/', callback);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -2909,7 +2909,7 @@ RPC.prototype._toWalletTX = function _toWalletTX(tx, callback) {
|
||||
var self = this;
|
||||
var i, det, receive, member, sent, received, json;
|
||||
|
||||
this.wallet.tx.toDetails(tx, function(err, details) {
|
||||
this.wallet.toDetails(tx, function(err, details) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
@ -3240,7 +3240,7 @@ RPC.prototype._toListTX = function _toListTX(tx, callback) {
|
||||
var i, receive, member, det, sent, received, index;
|
||||
var sendMember, recMember, sendIndex, recIndex, json;
|
||||
|
||||
this.wallet.tx.toDetails(tx, function(err, details) {
|
||||
this.wallet.toDetails(tx, function(err, details) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
|
||||
95
lib/bcoin/http/rpcclient.js
Normal file
95
lib/bcoin/http/rpcclient.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*!
|
||||
* rpcclient.js - json rpc client for bcoin
|
||||
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var Network = require('../network');
|
||||
var utils = require('../utils');
|
||||
var assert = utils.assert;
|
||||
var request = require('./request');
|
||||
|
||||
/**
|
||||
* BCoin RPC client.
|
||||
* @exports RPCClient
|
||||
* @constructor
|
||||
* @param {String} uri
|
||||
* @param {Object?} options
|
||||
*/
|
||||
|
||||
function RPCClient(options) {
|
||||
if (!(this instanceof RPCClient))
|
||||
return new RPCClient(options);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
if (typeof options === 'string')
|
||||
options = { uri: options };
|
||||
|
||||
this.options = options;
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
this.uri = options.uri || 'http://localhost:' + this.network.rpcPort;
|
||||
this.apiKey = options.apiKey;
|
||||
this.id = 0;
|
||||
|
||||
if (this.apiKey) {
|
||||
if (typeof this.apiKey === 'string') {
|
||||
assert(utils.isHex(this.apiKey), 'API key must be a hex string.');
|
||||
this.apiKey = new Buffer(this.apiKey, 'hex');
|
||||
}
|
||||
assert(Buffer.isBuffer(this.apiKey));
|
||||
assert(this.apiKey.length === 32, 'API key must be 32 bytes.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an http request to endpoint.
|
||||
* @private
|
||||
* @param {String} method
|
||||
* @param {String} endpoint - Path.
|
||||
* @param {Object} json - Body or query depending on method.
|
||||
* @param {Function} callback - Returns [Error, Object?].
|
||||
*/
|
||||
|
||||
RPCClient.prototype.call = function call(method, params, callback) {
|
||||
var self = this;
|
||||
|
||||
request({
|
||||
method: 'POST',
|
||||
uri: this.uri,
|
||||
json: {
|
||||
method: method,
|
||||
params: params,
|
||||
id: this.id++
|
||||
},
|
||||
auth: {
|
||||
username: 'bitcoinrpc',
|
||||
password: this.apiKey ? this.apiKey.toString('hex') : ''
|
||||
},
|
||||
expect: 'json'
|
||||
}, function(err, res, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!body)
|
||||
return callback();
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
if (body.error)
|
||||
return callback(new Error(body.error.message));
|
||||
return callback(new Error('Status code: ' + res.statusCode));
|
||||
}
|
||||
|
||||
return callback(null, body.result);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = RPCClient;
|
||||
@ -278,13 +278,22 @@ HTTPServer.prototype._init = function _init() {
|
||||
if (req.path.length < 2 || req.path[0] !== 'wallet')
|
||||
return next();
|
||||
|
||||
if (!self.options.walletAuth)
|
||||
return next();
|
||||
if (!self.options.walletAuth) {
|
||||
return self.walletdb.get(req.options.id, function(err, wallet) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
self.walletdb.auth(req.options.id, req.options.token, function(err) {
|
||||
if (!wallet)
|
||||
return send(404);
|
||||
|
||||
req.wallet = wallet;
|
||||
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
self.walletdb.auth(req.options.id, req.options.token, function(err, wallet) {
|
||||
if (err) {
|
||||
if (err.message === 'Wallet not found.')
|
||||
return next();
|
||||
self.logger.info('Auth failure for %s: %s.',
|
||||
req.options.id, err.message);
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="wallet"');
|
||||
@ -292,6 +301,10 @@ HTTPServer.prototype._init = function _init() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wallet)
|
||||
return send(404);
|
||||
|
||||
req.wallet = wallet;
|
||||
self.logger.info('Successful auth for %s.', req.options.id);
|
||||
next();
|
||||
});
|
||||
@ -525,27 +538,16 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Get wallet
|
||||
this.get('/wallet/:id', function(req, res, next, send) {
|
||||
self.walletdb.getInfo(req.options.id, function(err, wallet) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!wallet)
|
||||
return send(404);
|
||||
|
||||
send(200, wallet.toJSON());
|
||||
});
|
||||
send(200, req.wallet.toJSON());
|
||||
});
|
||||
|
||||
// Create/get wallet
|
||||
// Create wallet
|
||||
this.post('/wallet/:id?', function(req, res, next, send) {
|
||||
var json;
|
||||
self.walletdb.ensure(req.options, function(err, wallet) {
|
||||
self.walletdb.create(req.options, function(err, wallet) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!wallet)
|
||||
return send(404);
|
||||
|
||||
json = wallet.toJSON();
|
||||
wallet.destroy();
|
||||
|
||||
@ -555,7 +557,7 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// List accounts
|
||||
this.get('/wallet/:id/account', function(req, res, next, send) {
|
||||
self.walletdb.getAccounts(req.options.id, function(err, accounts) {
|
||||
req.wallet.getAccounts(function(err, accounts) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -568,10 +570,7 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Create/get account
|
||||
this.post('/wallet/:id/account/:account?', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
options.name = options.account || options.name;
|
||||
self.walletdb.ensureAccount(id, options, function(err, account) {
|
||||
req.wallet.createAccount(req.options, function(err, account) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -584,11 +583,10 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Change passphrase
|
||||
this.post('/wallet/:id/passphrase', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
var old = options.old;
|
||||
var new_ = options.passphrase;
|
||||
self.walletdb.setPassphrase(id, old, new_, function(err) {
|
||||
req.wallet.setPassphrase(old, new_, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -598,9 +596,8 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Generate new token
|
||||
this.post('/wallet/:id/retoken', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
self.walletdb.retoken(id, options.passphrase, function(err, token) {
|
||||
req.wallet.retoken(options.passphrase, function(err, token) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -610,10 +607,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Send TX
|
||||
this.post('/wallet/:id/send', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
|
||||
self.walletdb.send(id, options, function(err, tx) {
|
||||
req.wallet.send(options, function(err, tx) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -623,14 +619,13 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Create TX
|
||||
this.post('/wallet/:id/create', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
|
||||
self.walletdb.createTX(id, options, function(err, tx) {
|
||||
req.wallet.createTX(options, function(err, tx) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
self.walletdb.sign(id, tx, options, function(err) {
|
||||
req.wallet.sign(tx, options, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -641,11 +636,10 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Sign TX
|
||||
this.post('/wallet/:id/sign', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var options = req.options;
|
||||
var tx = req.options.tx;
|
||||
|
||||
self.walletdb.sign(id, tx, options, function(err) {
|
||||
req.wallet.sign(tx, options, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -655,10 +649,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Fill TX
|
||||
this.post('/wallet/:id/fill', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var tx = req.options.tx;
|
||||
|
||||
self.walletdb.fillHistory(id, tx, function(err) {
|
||||
req.wallet.fillHistory(tx, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -668,11 +661,10 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Zap Wallet TXs
|
||||
this.post('/wallet/:id/zap', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
var age = req.options.age;
|
||||
|
||||
self.walletdb.zap(id, account, age, function(err) {
|
||||
req.wallet.zap(account, age, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -682,10 +674,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Add key
|
||||
this.put('/wallet/:id/key', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
self.walletdb.addKey(id, account, key, function(err) {
|
||||
req.wallet.addKey(account, key, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -695,10 +686,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Remove key
|
||||
this.del('/wallet/:id/key', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
self.walletdb.removeKey(id, account, key, function(err) {
|
||||
req.wallet.removeKey(account, key, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -708,9 +698,8 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Create address
|
||||
this.post('/wallet/:id/address', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
self.walletdb.createAddress(id, account, false, function(err, address) {
|
||||
req.wallet.createAddress(account, false, function(err, address) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -720,28 +709,22 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet Balance
|
||||
this.get('/wallet/:id/balance', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
self.walletdb.getBalance(id, account, function(err, balance) {
|
||||
req.wallet.getBalance(account, function(err, balance) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!balance)
|
||||
return send(404);
|
||||
|
||||
send(200, {
|
||||
confirmed: utils.btc(balance.confirmed),
|
||||
unconfirmed: utils.btc(balance.unconfirmed),
|
||||
total: utils.btc(balance.total)
|
||||
});
|
||||
send(200, balance.toJSON());
|
||||
});
|
||||
});
|
||||
|
||||
// Wallet UTXOs
|
||||
this.get('/wallet/:id/coin', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
self.walletdb.getCoins(id, account, function(err, coins) {
|
||||
req.wallet.getCoins(account, function(err, coins) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -756,10 +739,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet Coin
|
||||
this.get('/wallet/:id/coin/:hash/:index', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var hash = req.options.hash;
|
||||
var index = req.options.index;
|
||||
self.walletdb.getCoin(id, hash, index, function(err, coin) {
|
||||
req.wallet.getCoin(hash, index, function(err, coin) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -772,18 +754,15 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet TXs
|
||||
this.get('/wallet/:id/tx/history', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
self.walletdb.getHistory(id, account, function(err, txs) {
|
||||
req.wallet.getHistory(account, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!txs.length)
|
||||
return send(404);
|
||||
|
||||
utils.forEachSerial(txs, function(tx, next) {
|
||||
self.walletdb.fillHistory(id, tx, next);
|
||||
}, function(err) {
|
||||
req.wallet.toDetails(txs, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -796,18 +775,15 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet Pending TXs
|
||||
this.get('/wallet/:id/tx/unconfirmed', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
self.walletdb.getUnconfirmed(id, account, function(err, txs) {
|
||||
req.wallet.getUnconfirmed(account, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!txs.length)
|
||||
return send(404);
|
||||
|
||||
utils.forEachSerial(txs, function(tx, next) {
|
||||
self.walletdb.fillHistory(id, tx, next);
|
||||
}, function(err) {
|
||||
req.wallet.toDetails(txs, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -820,19 +796,16 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet TXs within time range
|
||||
this.get('/wallet/:id/tx/range', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
var options = req.options;
|
||||
self.walletdb.getRange(id, account, options, function(err, txs) {
|
||||
req.walletdb.getRange(account, options, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!txs.length)
|
||||
return send(404);
|
||||
|
||||
utils.forEachSerial(txs, function(tx, next) {
|
||||
self.walletdb.fillHistory(id, tx, next);
|
||||
}, function(err) {
|
||||
req.wallet.toDetails(txs, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -845,19 +818,16 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet TXs within time range
|
||||
this.get('/wallet/:id/tx/last', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var account = req.options.account;
|
||||
var limit = req.options.limit;
|
||||
self.walletdb.getRange(id, account, limit, function(err, txs) {
|
||||
req.wallet.getRange(account, limit, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!txs.length)
|
||||
return send(404);
|
||||
|
||||
utils.forEachSerial(txs, function(tx, next) {
|
||||
self.walletdb.fillHistory(id, tx, next);
|
||||
}, function(err) {
|
||||
req.wallet.toDetails(txs, function(err, txs) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
@ -870,16 +840,15 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
// Wallet TX
|
||||
this.get('/wallet/:id/tx/:hash', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
var hash = req.options.hash;
|
||||
self.walletdb.getTX(id, hash, function(err, tx) {
|
||||
req.wallet.getTX(hash, function(err, tx) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!tx)
|
||||
return send(404);
|
||||
|
||||
self.walletdb.fillHistory(id, tx, function(err) {
|
||||
req.wallet.toDetails(tx, function(err, tx) {
|
||||
if (err)
|
||||
return next(err);
|
||||
send(200, tx.toJSON());
|
||||
@ -954,11 +923,15 @@ HTTPServer.prototype._initIO = function _initIO() {
|
||||
return callback();
|
||||
}
|
||||
|
||||
self.walletdb.auth(id, token, function(err) {
|
||||
self.walletdb.auth(id, token, function(err, wallet) {
|
||||
if (err) {
|
||||
self.logger.info('Wallet auth failure for %s: %s.', id, err.message);
|
||||
return callback({ error: 'Bad token.' });
|
||||
}
|
||||
|
||||
if (!wallet)
|
||||
return callback({ error: 'Wallet does not exist.' });
|
||||
|
||||
self.logger.info('Successful wallet auth for %s.', id);
|
||||
socket.join(id);
|
||||
return callback();
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var bcoin = require('../env');
|
||||
var Network = require('../network');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var utils = require('../utils');
|
||||
@ -33,7 +33,7 @@ function HTTPWallet(options) {
|
||||
options = { uri: options };
|
||||
|
||||
this.options = options;
|
||||
this.network = bcoin.network.get(options.network);
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
this.client = new http.client(options);
|
||||
this.uri = options.uri;
|
||||
@ -83,7 +83,7 @@ HTTPWallet.prototype._init = function _init() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the client and ensure a wallet.
|
||||
* Open the client and get a wallet.
|
||||
* @alias HTTPWallet#open
|
||||
* @param {Function} callback
|
||||
*/
|
||||
@ -94,6 +94,38 @@ HTTPWallet.prototype.open = function open(options, callback) {
|
||||
if (Buffer.isBuffer(options.token))
|
||||
options.token = options.token.toString('hex');
|
||||
|
||||
this.id = options.id;
|
||||
|
||||
if (options.token) {
|
||||
this.client.auth = { username: 'x', password: options.token };
|
||||
this.token = new Buffer(options.token, 'hex');
|
||||
}
|
||||
|
||||
this.client.open(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.client.getWallet(self.id, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.client.joinWallet(self.id, wallet.token, function(err) {
|
||||
if (err)
|
||||
return callback(new Error(err.error));
|
||||
callback(null, wallet);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the client and create a wallet.
|
||||
* @alias HTTPWallet#open
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.create = function create(options, callback) {
|
||||
var self = this;
|
||||
|
||||
this.client.open(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
@ -101,14 +133,11 @@ HTTPWallet.prototype.open = function open(options, callback) {
|
||||
self.client.createWallet(options, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.id = wallet.id;
|
||||
self.client.auth = { username: 'x', password: wallet.token };
|
||||
self.token = new Buffer(wallet.token, 'hex');
|
||||
self.client.joinWallet(self.id, wallet.token, function(err) {
|
||||
if (err)
|
||||
return callback(new Error(err.error));
|
||||
callback(null, wallet);
|
||||
});
|
||||
|
||||
self.open({
|
||||
id: wallet.id,
|
||||
token: wallet.token
|
||||
}, callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -511,6 +511,30 @@ Wallet.prototype.createAccount = function createAccount(options, callback, force
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure an account. Requires passphrase if master key is encrypted.
|
||||
* @param {Object} options - See {@link Account} options.
|
||||
* @param {Function} callback - Returns [Error, {@link Account}].
|
||||
*/
|
||||
|
||||
Wallet.prototype.ensureAccount = function ensureAccount(options, callback) {
|
||||
var self = this;
|
||||
var account = options.account;
|
||||
|
||||
if (typeof options.name === 'string')
|
||||
account = options.name;
|
||||
|
||||
this.hasAccount(account, function(err, exists) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (exists)
|
||||
return self.getAccount(account, callback);
|
||||
|
||||
self.createAccount(options, callback);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* List account names and indexes from the db.
|
||||
* @param {Function} callback - Returns [Error, Array].
|
||||
@ -1349,6 +1373,36 @@ Wallet.prototype.fillCoins = function fillCoins(tx, callback) {
|
||||
return this.tx.fillCoins(tx, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill transaction with historical coins (accesses db).
|
||||
* @param {TX} tx
|
||||
* @param {Function} callback - Returns [Error, {@link TX}].
|
||||
*/
|
||||
|
||||
Wallet.prototype.fillHistory = function fillHistory(tx, callback) {
|
||||
return this.tx.fillHistory(tx, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill transaction with historical coins (accesses db).
|
||||
* @param {TX} tx
|
||||
* @param {Function} callback - Returns [Error, {@link TX}].
|
||||
*/
|
||||
|
||||
Wallet.prototype.toDetails = function toDetails(tx, callback) {
|
||||
return this.tx.toDetails(tx, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill transaction with historical coins (accesses db).
|
||||
* @param {TX} tx
|
||||
* @param {Function} callback - Returns [Error, {@link TX}].
|
||||
*/
|
||||
|
||||
Wallet.prototype.getDetails = function getDetails(tx, callback) {
|
||||
return this.tx.getDetails(tx, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a coin from the wallet (accesses db).
|
||||
* @param {Hash} hash
|
||||
|
||||
@ -438,12 +438,12 @@ WalletDB.prototype.save = function save(wallet) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.auth = function auth(id, token, callback) {
|
||||
this._get(id, function(err, wallet) {
|
||||
this.get(id, function(err, wallet) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!wallet)
|
||||
return callback(new Error('Wallet not found.'));
|
||||
return callback();
|
||||
|
||||
if (typeof token === 'string') {
|
||||
if (!utils.isHex(token))
|
||||
@ -455,7 +455,7 @@ WalletDB.prototype.auth = function auth(id, token, callback) {
|
||||
if (!utils.ccmp(token, wallet.token))
|
||||
return callback(new Error('Authentication error.'));
|
||||
|
||||
return callback();
|
||||
return callback(null, wallet);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ describe('HTTP', function() {
|
||||
});
|
||||
|
||||
it('should create wallet', function(cb) {
|
||||
wallet.open({ id: 'test' }, function(err, wallet) {
|
||||
wallet.create({ id: 'test' }, function(err, wallet) {
|
||||
assert.ifError(err);
|
||||
assert.equal(wallet.id, 'test');
|
||||
cb();
|
||||
@ -113,9 +113,9 @@ describe('HTTP', function() {
|
||||
assert.equal(receive.type, 'pubkeyhash');
|
||||
assert.equal(receive.change, 0);
|
||||
assert(balance);
|
||||
assert.equal(balance.confirmed, 0);
|
||||
assert.equal(balance.unconfirmed, 201840);
|
||||
assert.equal(balance.total, 201840);
|
||||
assert.equal(utils.satoshi(balance.confirmed), 0);
|
||||
assert.equal(utils.satoshi(balance.unconfirmed), 201840);
|
||||
assert.equal(utils.satoshi(balance.total), 201840);
|
||||
assert(details);
|
||||
assert.equal(details.hash, t1.rhash);
|
||||
cb();
|
||||
@ -126,9 +126,9 @@ describe('HTTP', function() {
|
||||
it('should get balance', function(cb) {
|
||||
wallet.getBalance(function(err, balance) {
|
||||
assert.ifError(err);
|
||||
assert.equal(balance.confirmed, 0);
|
||||
assert.equal(balance.unconfirmed, 201840);
|
||||
assert.equal(balance.total, 201840);
|
||||
assert.equal(utils.satoshi(balance.confirmed), 0);
|
||||
assert.equal(utils.satoshi(balance.unconfirmed), 201840);
|
||||
assert.equal(utils.satoshi(balance.total), 201840);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
@ -147,8 +147,8 @@ describe('HTTP', function() {
|
||||
assert(tx);
|
||||
assert.equal(tx.inputs.length, 1);
|
||||
assert.equal(tx.outputs.length, 2);
|
||||
assert.equal(tx.getOutputValue(), 48190);
|
||||
hash = tx.hash('hex');
|
||||
assert.equal(utils.satoshi(tx.outputs[0].value) + utils.satoshi(tx.outputs[1].value), 48190);
|
||||
hash = tx.hash;
|
||||
cb();
|
||||
});
|
||||
});
|
||||
@ -157,7 +157,7 @@ describe('HTTP', function() {
|
||||
wallet.getTX(hash, function(err, tx) {
|
||||
assert.ifError(err);
|
||||
assert(tx);
|
||||
assert.equal(tx.hash('hex'), hash);
|
||||
assert.equal(tx.hash, hash);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
@ -175,7 +175,7 @@ describe('HTTP', function() {
|
||||
it('should get balance', function(cb) {
|
||||
wallet.getBalance(function(err, balance) {
|
||||
assert.ifError(err);
|
||||
assert.equal(balance.total, 199570);
|
||||
assert.equal(utils.satoshi(balance.total), 199570);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user