http: use bclient.

This commit is contained in:
Christopher Jeffrey 2017-10-23 13:18:17 -07:00
parent f6ca348566
commit a6dc571c2d
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
7 changed files with 14 additions and 899 deletions

View File

@ -4,8 +4,7 @@
const Config = require('../lib/node/config');
const util = require('../lib/utils/util');
const Client = require('../lib/http/client');
const Wallet = require('../lib/http/wallet');
const {NodeClient, WalletClient} = require('bclient');
const ports = {
main: 8332,
@ -540,7 +539,7 @@ CLI.prototype.rpc = async function rpc() {
};
CLI.prototype.handleWallet = async function handleWallet() {
this.wallet = new Wallet({
this.wallet = new WalletClient({
url: this.config.str(['url', 'uri']),
apiKey: this.config.str('api-key'),
host: this.config.str('http-host'),
@ -702,7 +701,7 @@ CLI.prototype.handleWallet = async function handleWallet() {
};
CLI.prototype.handleNode = async function handleNode() {
this.client = new Client({
this.client = new NodeClient({
url: this.config.str(['url', 'uri']),
apiKey: this.config.str('api-key'),
host: this.config.str('http-host'),

View File

@ -1,294 +0,0 @@
/*!
* client.js - http client for wallets
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
const assert = require('assert');
const {Client} = require('bcurl');
class HTTPClient extends Client {
/**
* Bcoin HTTP client.
* @alias module:http.Client
* @constructor
* @param {String} uri
* @param {Object?} options
*/
constructor(options) {
super(options);
}
/**
* Auth with server.
* @returns {Promise}
*/
async auth() {
return this.call('auth', this.password);
}
/**
* Make an RPC call.
* @returns {Promise}
*/
execute(name, params) {
return super.execute('/', name, params);
}
/**
* Get a mempool snapshot.
* @returns {Promise} - Returns {@link Hash}[].
*/
getMempool() {
return this.get('/mempool');
}
/**
* Get some info about the server (network and version).
* @returns {Promise} - Returns Object.
*/
getInfo() {
return this.get('/');
}
/**
* Get coins that pertain to an address from the mempool or chain database.
* Takes into account spent coins in the mempool.
* @param {String} address
* @returns {Promise} - Returns {@link Coin}[].
*/
getCoinsByAddress(address) {
assert(typeof address === 'string');
return this.get(`/coin/address/${address}`);
}
/**
* Get coins that pertain to addresses from the mempool or chain database.
* Takes into account spent coins in the mempool.
* @param {String[]} addresses
* @returns {Promise} - Returns {@link Coin}[].
*/
getCoinsByAddresses(addresses) {
assert(Array.isArray(addresses));
return this.post('/coin/address', { addresses });
}
/**
* Retrieve a coin from the mempool or chain database.
* Takes into account spent coins in the mempool.
* @param {Hash} hash
* @param {Number} index
* @returns {Promise} - Returns {@link Coin}.
*/
getCoin(hash, index) {
assert(typeof hash === 'string');
assert((index >>> 0) === index);
return this.get(`/coin/${hash}/${index}`);
}
/**
* Retrieve transactions pertaining to an
* address from the mempool or chain database.
* @param {String} address
* @returns {Promise} - Returns {@link TX}[].
*/
getTXByAddress(address) {
assert(typeof address === 'string');
return this.get(`/tx/address/${address}`);
}
/**
* Retrieve transactions pertaining to
* addresses from the mempool or chain database.
* @param {String[]} addresses
* @returns {Promise} - Returns {@link TX}[].
*/
getTXByAddresses(addresses) {
assert(Array.isArray(addresses));
return this.post('/tx/address', { addresses });
}
/**
* Retrieve a transaction from the mempool or chain database.
* @param {Hash} hash
* @returns {Promise} - Returns {@link TX}.
*/
getTX(hash) {
assert(typeof hash === 'string');
return this.get(`/tx/${hash}`);
}
/**
* Retrieve a block from the chain database.
* @param {Hash|Number} block
* @returns {Promise} - Returns {@link Block}.
*/
getBlock(block) {
assert(typeof block === 'string' || typeof block === 'number');
return this.get(`/block/${block}`);
}
/**
* Add a transaction to the mempool and broadcast it.
* @param {TX} tx
* @returns {Promise}
*/
broadcast(tx) {
assert(typeof tx === 'string');
return this.post('/broadcast', { tx });
}
/**
* Reset the chain.
* @param {Number} height
* @returns {Promise}
*/
reset(height) {
return this.post('/reset', { height });
}
/**
* Watch the blockchain.
* @private
* @returns {Promise}
*/
watchChain() {
return this.call('watch chain');
}
/**
* Watch the blockchain.
* @private
* @returns {Promise}
*/
watchMempool() {
return this.call('watch mempool');
}
/**
* Get chain tip.
* @returns {Promise}
*/
getTip() {
return this.call('get tip');
}
/**
* Get chain entry.
* @param {Hash} hash
* @returns {Promise}
*/
getEntry(block) {
return this.call('get entry', block);
}
/**
* Get hashes.
* @param {Number} [start=-1]
* @param {Number} [end=-1]
* @returns {Promise}
*/
getHashes(start, end) {
return this.call('get hashes', start, end);
}
/**
* Send a transaction. Do not wait for promise.
* @param {TX} tx
* @returns {Promise}
*/
send(tx) {
assert(Buffer.isBuffer(tx));
return this.call('send', tx);
}
/**
* Set bloom filter.
* @param {Bloom} filter
* @returns {Promise}
*/
setFilter(filter) {
assert(Buffer.isBuffer(filter));
return this.call('set filter', filter);
}
/**
* Add data to filter.
* @param {Buffer} data
* @returns {Promise}
*/
addFilter(chunks) {
if (!Array.isArray(chunks))
chunks = [chunks];
return this.call('add filter', chunks);
}
/**
* Reset filter.
* @returns {Promise}
*/
resetFilter() {
return this.call('reset filter');
}
/**
* Esimate smart fee.
* @param {Number?} blocks
* @returns {Promise}
*/
estimateFee(blocks) {
assert(blocks == null || typeof blocks === 'number');
return this.call('estimate fee', blocks);
}
/**
* Rescan for any missed transactions.
* @param {Number|Hash} start - Start block.
* @param {Bloom} filter
* @param {Function} iter - Iterator.
* @returns {Promise}
*/
rescan(start) {
if (start == null)
start = 0;
assert(typeof start === 'number' || typeof start === 'string');
return this.call('rescan', start);
}
}
/*
* Expose
*/
module.exports = HTTPClient;

View File

@ -11,7 +11,5 @@
* @module http
*/
exports.Client = require('./client');
exports.RPC = require('./rpc');
exports.Server = require('./server');
exports.Wallet = require('./wallet');

View File

@ -1,591 +0,0 @@
/*!
* wallet.js - http wallet for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
const assert = require('assert');
const {Client} = require('bcurl');
class HTTPWallet extends Client {
/**
* HTTPWallet
* @alias module:http.Wallet
* @constructor
* @param {String} uri
*/
constructor(options) {
super(options);
}
/**
* Open the client, wait for socket to connect.
* @returns {Promise}
*/
async init() {
await super.open();
this.listen('wallet tx', (details) => {
this.emit('tx', details);
});
this.listen('wallet confirmed', (details) => {
this.emit('confirmed', details);
});
this.listen('wallet unconfirmed', (details) => {
this.emit('unconfirmed', details);
});
this.listen('wallet conflict', (details) => {
this.emit('conflict', details);
});
this.listen('wallet updated', (details) => {
this.emit('updated', details);
});
this.listen('wallet address', (receive) => {
this.emit('address', receive);
});
this.listen('wallet balance', (balance) => {
this.emit('balance', balance);
});
}
/**
* Open the client and get a wallet.
* @returns {Promise}
*/
async open(options = {}) {
if (options.id != null) {
assert(typeof options.id === 'string');
this.id = options.id;
}
if (options.token != null) {
assert(typeof options.token === 'string');
this.token = options.token;
}
if (!this.id)
throw new Error('No ID provided.');
await this.init();
await this.call('wallet join', this.id, this.token);
}
/**
* Open the client and create a wallet.
* @returns {Promise}
*/
async create(options) {
const wallet = await this.createWallet(options);
assert(wallet);
assert(typeof wallet.id === 'string');
assert(typeof wallet.token === 'string');
this.id = wallet.id;
this.token = wallet.token;
await this.init();
await this.call('wallet join', this.id, this.token);
return wallet;
}
/**
* Auth with server.
* @returns {Promise}
*/
async auth() {
return this.call('wallet auth', this.password);
}
/**
* Make an RPC call.
* @returns {Promise}
*/
execute(name, params) {
return super.execute('/', name, params);
}
/**
* Rescan the chain.
* @param {Number} height
* @returns {Promise}
*/
rescan(height) {
return this.post('/wallet/_admin/rescan', { height });
}
/**
* Resend pending transactions.
* @returns {Promise}
*/
resend() {
return this.post('/wallet/_admin/resend');
}
/**
* Backup the walletdb.
* @param {String} path
* @returns {Promise}
*/
backup(path) {
return this.post('/wallet/_admin/backup', { path });
}
/**
* Get list of all wallet IDs.
* @returns {Promise}
*/
getWallets() {
return this.get('/wallet/_admin/wallets');
}
/**
* Create a wallet.
* @param {Object} options
* @returns {Promise}
*/
createWallet(options) {
assert(options.id, 'Must pass an id parameter');
return this.put(`/wallet/${options.id}`, options);
}
/**
* Get wallet transaction history.
* @returns {Promise}
*/
getHistory(account) {
return this.get(`/wallet/${this.id}/tx/history`, { account });
}
/**
* Get wallet coins.
* @returns {Promise}
*/
getCoins(account) {
return this.get(`/wallet/${this.id}/coin`, { account });
}
/**
* Get all unconfirmed transactions.
* @returns {Promise}
*/
getPending(account) {
return this.get(`/wallet/${this.id}/tx/unconfirmed`, { account });
}
/**
* Calculate wallet balance.
* @returns {Promise}
*/
getBalance(account) {
return this.get(`/wallet/${this.id}/balance`, { account });
}
/**
* Get last N wallet transactions.
* @param {Number} limit - Max number of transactions.
* @returns {Promise}
*/
getLast(account, limit) {
return this.get(`/wallet/${this.id}/tx/last`, { account, limit });
}
/**
* Get wallet transactions by timestamp range.
* @param {Object} options
* @param {Number} options.start - Start time.
* @param {Number} options.end - End time.
* @param {Number?} options.limit - Max number of records.
* @param {Boolean?} options.reverse - Reverse order.
* @returns {Promise}
*/
getRange(account, options) {
return this.get(`/wallet/${this.id}/tx/range`, {
account: account,
start: options.start,
end: options.end ,
limit: options.limit,
reverse: options.reverse
});
}
/**
* Get transaction (only possible if the transaction
* is available in the wallet history).
* @param {Hash} hash
* @returns {Promise}
*/
getTX(hash) {
return this.get(`/wallet/${this.id}/tx/${hash}`);
}
/**
* Get wallet blocks.
* @param {Number} height
* @returns {Promise}
*/
getBlocks() {
return this.get(`/wallet/${this.id}/block`);
}
/**
* Get wallet block.
* @param {Number} height
* @returns {Promise}
*/
getBlock(height) {
return this.get(`/wallet/${this.id}/block/${height}`);
}
/**
* Get unspent coin (only possible if the transaction
* is available in the wallet history).
* @param {Hash} hash
* @param {Number} index
* @returns {Promise}
*/
getCoin(hash, index) {
return this.get(`/wallet/${this.id}/coin/${hash}/${index}`);
}
/**
* @param {Number} now - Current time.
* @param {Number} age - Age delta (delete transactions older than `now - age`).
* @returns {Promise}
*/
zap(account, age) {
return this.post(`/wallet/${this.id}/zap`, { account, age });
}
/**
* Create a transaction, fill.
* @param {Object} options
* @returns {Promise}
*/
createTX(options) {
return this.post(`/wallet/${this.id}/create`, options);
}
/**
* Create a transaction, fill, sign, and broadcast.
* @param {Object} options
* @param {String} options.address
* @param {Amount} options.value
* @returns {Promise}
*/
send(options) {
return this.post(`/wallet/${this.id}/send`, options);
}
/**
* Sign a transaction.
* @param {Object} options
* @returns {Promise}
*/
sign(options) {
return this.post(`/wallet/${this.id}/sign`, options);
}
/**
* Get the raw wallet JSON.
* @returns {Promise}
*/
getInfo() {
return this.get(`/wallet/${this.id}`);
}
/**
* Get wallet accounts.
* @returns {Promise} - Returns Array.
*/
getAccounts() {
return this.get(`/wallet/${this.id}/account`);
}
/**
* Get wallet master key.
* @returns {Promise}
*/
getMaster() {
return this.get(`/wallet/${this.id}/master`);
}
/**
* Get wallet account.
* @param {String} account
* @returns {Promise}
*/
getAccount(account) {
return this.get(`/wallet/${this.id}/account/${account}`);
}
/**
* Create account.
* @param {String} name
* @param {Object} options
* @returns {Promise}
*/
createAccount(name, options) {
return this.put(`/wallet/${this.id}/account/${name}`, options);
}
/**
* Create address.
* @param {Object} options
* @returns {Promise}
*/
createAddress(account) {
return this.post(`/wallet/${this.id}/address`, { account });
}
/**
* Create change address.
* @param {Object} options
* @returns {Promise}
*/
createChange(account) {
return this.post(`/wallet/${this.id}/change`, { account });
}
/**
* Create nested address.
* @param {Object} options
* @returns {Promise}
*/
createNested(account) {
return this.post(`/wallet/${this.id}/nested`, { account });
}
/**
* Change or set master key's passphrase.
* @param {String|Buffer} passphrase
* @param {(String|Buffer)?} old
* @returns {Promise}
*/
setPassphrase(passphrase, old) {
return this.post(`/wallet/${this.id}/passphrase`, { passphrase, old });
}
/**
* Generate a new token.
* @param {(String|Buffer)?} passphrase
* @returns {Promise}
*/
async retoken(passphrase) {
const body = await this.post(`/wallet/${this.id}/retoken`, {
passphrase
});
assert(body);
assert(typeof body.token === 'string');
this.token = body.token;
return body.token;
}
/**
* Import private key.
* @param {Number|String} account
* @param {String} key
* @returns {Promise}
*/
importPrivate(account, privateKey, passphrase) {
return this.post(`/wallet/${this.id}/import`, {
account,
privateKey,
passphrase
});
}
/**
* Import public key.
* @param {Number|String} account
* @param {String} key
* @returns {Promise}
*/
importPublic(account, publicKey) {
return this.post(`/wallet/${this.id}/import`, {
account,
publicKey
});
}
/**
* Import address.
* @param {Number|String} account
* @param {String} address
* @returns {Promise}
*/
importAddress(account, address) {
return this.post(`/wallet/${this.id}/import`, { account, address });
}
/**
* Lock a coin.
* @param {String} hash
* @param {Number} index
* @returns {Promise}
*/
lockCoin(hash, index) {
return this.put(`/wallet/${this.id}/locked/${hash}/${index}`);
}
/**
* Unlock a coin.
* @param {String} hash
* @param {Number} index
* @returns {Promise}
*/
unlockCoin(hash, index) {
return this.del(`/wallet/${this.id}/locked/${hash}/${index}`);
}
/**
* Get locked coins.
* @returns {Promise}
*/
getLocked() {
return this.get(`/wallet/${this.id}/locked`);
}
/**
* Lock wallet.
* @returns {Promise}
*/
lock() {
return this.post(`/wallet/${this.id}/lock`);
}
/**
* Unlock wallet.
* @param {String} passphrase
* @param {Number} timeout
* @returns {Promise}
*/
unlock(passphrase, timeout) {
return this.post(`/wallet/${this.id}/unlock`, {
passphrase,
timeout
});
}
/**
* Get wallet key.
* @param {String} address
* @returns {Promise}
*/
getKey(address) {
return this.get(`/wallet/${this.id}/key/${address}`);
}
/**
* Get wallet key WIF dump.
* @param {String} address
* @param {String?} passphrase
* @returns {Promise}
*/
getWIF(address, passphrase) {
return this.get(`/wallet/${this.id}/wif/${address}`, { passphrase });
}
/**
* Add a public account/purpose key to the wallet for multisig.
* @param {(String|Number)?} account
* @param {Base58String} key - Account (bip44) or
* Purpose (bip45) key (can be in base58 form).
* @returns {Promise}
*/
addSharedKey(account, accountKey) {
return this.put(`/wallet/${this.id}/shared-key`, {
account,
accountKey
});
}
/**
* Remove a public account/purpose key to the wallet for multisig.
* @param {(String|Number)?} account
* @param {Base58String} key - Account (bip44) or Purpose
* (bip45) key (can be in base58 form).
* @returns {Promise}
*/
removeSharedKey(account, accountKey) {
return this.del(`/wallet/${this.id}/shared-key`, {
account,
accountKey
});
}
/**
* Resend wallet transactions.
* @returns {Promise}
*/
resend() {
return this.post(`/wallet/${this.id}/resend`);
}
}
/*
* Expose
*/
module.exports = HTTPWallet;

View File

@ -7,12 +7,12 @@
'use strict';
const HTTPClient = require('../http/client');
const {NodeClient} = require('bclient');
const TX = require('../primitives/tx');
const digest = require('../crypto/digest');
const util = require('../utils/util');
class WalletClient extends HTTPClient {
class WalletClient extends NodeClient {
constructor(options) {
super(options);
}

View File

@ -25,14 +25,15 @@
"dependencies": {
"bn.js": "4.11.8",
"elliptic": "6.4.0",
"n64": "0.0.18"
"n64": "0.0.18",
"breq": "^0.0.1",
"bclient": "^0.0.1",
"bweb": "^0.0.1"
},
"optionalDependencies": {
"bcoin-native": "0.0.23",
"leveldown": "1.7.2",
"secp256k1": "3.3.0",
"socket.io": "2.0.3",
"socket.io-client": "2.0.3"
"secp256k1": "3.3.0"
},
"devDependencies": {
"babel-core": "^6.25.0",

View File

@ -26,12 +26,14 @@ const node = new FullNode({
plugins: [require('../lib/wallet/plugin')]
});
const client = new HTTP.Client({
const {NodeClient, WalletClient} = require('bclient');
const client = new NodeClient({
port: network.rpcPort,
apiKey: 'foo'
});
const wallet = new HTTP.Wallet({
const wallet = new WalletClient({
port: network.rpcPort,
apiKey: 'foo'
});