From 3beae441bb90450a9213cf920b9450f9dc7e7fce Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 13 Nov 2016 11:28:26 -0800 Subject: [PATCH] http: refactor cli usage of http clients. --- bin/cli | 43 +++++++++++++--------- lib/http/client.js | 89 ++++++++++++++++++++++++++++++++++------------ lib/http/server.js | 14 +++++++- lib/http/wallet.js | 56 +++++++++++++++++++++-------- 4 files changed, 146 insertions(+), 56 deletions(-) diff --git a/bin/cli b/bin/cli index 95587962..396353d5 100755 --- a/bin/cli +++ b/bin/cli @@ -119,6 +119,12 @@ CLI.prototype.createAddress = co(function* createAddress() { this.log(addr); }); +CLI.prototype.createChange = co(function* createChange() { + var account = this.argv[0]; + var addr = yield this.wallet.createChange(account); + this.log(addr); +}); + CLI.prototype.createNested = co(function* createNested() { var account = this.argv[0]; var addr = yield this.wallet.createNested(account); @@ -208,34 +214,43 @@ CLI.prototype.getWalletCoins = co(function* getWalletCoins() { this.log(coins); }); -CLI.prototype.listenWallet = function listenWallet() { +CLI.prototype.listenWallet = co(function* listenWallet() { var self = this; + + yield this.wallet.open(); + this.wallet.on('tx', function(details) { self.log('TX:'); self.log(details); }); + this.wallet.on('confirmed', function(details) { self.log('TX confirmed:'); self.log(details); }); + this.wallet.on('unconfirmed', function(details) { self.log('TX unconfirmed:'); self.log(details); }); + this.wallet.on('conflict', function(details) { self.log('TX conflict:'); self.log(details); }); + 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); }); - return new Promise(function() {}); -}; + + return yield this.wallet.onDisconnect(); +}); CLI.prototype.getBalance = co(function* getBalance() { var balance = yield this.wallet.getBalance(this.config.account); @@ -430,19 +445,14 @@ CLI.prototype.rpc = co(function* rpc() { }); CLI.prototype.handleWallet = co(function* handleWallet() { - var options = { - id: this.config.id || 'primary', - token: this.config.token - }; - this.wallet = new Wallet({ uri: this.config.url || this.config.uri, apiKey: this.config.apikey, - network: this.config.network + network: this.config.network, + id: this.config.id || 'primary', + token: this.config.token }); - yield this.wallet.open(options); - switch (this.argv.shift()) { case 'listen': return yield this.listenWallet(); @@ -484,6 +494,8 @@ CLI.prototype.handleWallet = co(function* handleWallet() { return yield this.getAccount(); case 'address': return yield this.createAddress(); + case 'change': + return yield this.createChange(); case 'nested': return yield this.createNested(); case 'retoken': @@ -534,6 +546,7 @@ CLI.prototype.handleWallet = co(function* handleWallet() { this.log(' $ account create [account-name]: Create account.'); this.log(' $ account get [account-name]: Get account details.'); this.log(' $ address: Derive new address.'); + this.log(' $ change: Derive new change address.'); this.log(' $ nested: Derive new nested address.'); this.log(' $ retoken: Create new api key.'); this.log(' $ send [address] [value]: Send transaction.'); @@ -559,16 +572,12 @@ CLI.prototype.handleWallet = co(function* handleWallet() { }); CLI.prototype.handleNode = co(function* handleNode() { - var info; - this.client = new Client({ uri: this.config.url || this.config.uri, apiKey: this.config.apikey, network: this.config.network }); - info = yield this.client.getInfo(); - switch (this.argv.shift()) { case 'info': return yield this.getInfo(); @@ -626,9 +635,9 @@ CLI.prototype.open = co(function* open() { }); CLI.prototype.destroy = function destroy() { - if (this.wallet && !this.wallet.client.loading) + if (this.wallet) this.wallet.client.destroy(); - if (this.client && !this.client.loading) + if (this.client) this.client.destroy(); return Promise.resolve(); }; diff --git a/lib/http/client.js b/lib/http/client.js index 5ed9ecf7..9e2d9a4b 100644 --- a/lib/http/client.js +++ b/lib/http/client.js @@ -42,9 +42,6 @@ function HTTPClient(options) { this.apiKey = options.apiKey; this.auth = options.auth; this.rpc = new RPCClient(options); - - // Open automatically. - // this.open(); } utils.inherits(HTTPClient, AsyncObject); @@ -114,24 +111,6 @@ HTTPClient.prototype._open = co(function* _open() { yield this._sendAuth(); }); -HTTPClient.prototype._onConnect = function _onConnect() { - var self = this; - return new Promise(function(resolve, reject) { - self.socket.once('connect', resolve); - }); -}; - -HTTPClient.prototype._sendAuth = function _sendAuth() { - var self = this; - return new Promise(function(resolve, reject) { - self.socket.emit('auth', self.apiKey, function(err) { - if (err) - return reject(new Error(err.error)); - resolve(); - }); - }); -}; - /** * Close the client, wait for the socket to close. * @alias HTTPClient#close @@ -148,6 +127,49 @@ HTTPClient.prototype._close = function close() { return Promise.resolve(); }; +/** + * Wait for websocket connection. + * @private + * @returns {Promise} + */ + +HTTPClient.prototype._onConnect = function _onConnect() { + var self = this; + return new Promise(function(resolve, reject) { + self.socket.once('connect', resolve); + }); +}; + +/** + * Wait for websocket auth. + * @private + * @returns {Promise} + */ + +HTTPClient.prototype._sendAuth = function _sendAuth() { + var self = this; + return new Promise(function(resolve, reject) { + self.socket.emit('auth', self.apiKey, function(err) { + if (err) + return reject(new Error(err.error)); + resolve(); + }); + }); +}; + +/** + * Wait for websocket disconnection. + * @private + * @returns {Promise} + */ + +HTTPClient.prototype.onDisconnect = function onDisconnect() { + var self = this; + return new Promise(function(resolve, reject) { + self.socket.once('disconnect', resolve); + }); +}; + /** * Make an http request to endpoint. * @private @@ -185,7 +207,7 @@ HTTPClient.prototype._request = co(function* _request(method, endpoint, json) { network = res.headers['x-bcoin-network']; - if (network !== this.network.type) + if (network && network !== this.network.type) throw new Error('Wrong network.'); height = +res.headers['x-bcoin-height']; @@ -935,7 +957,28 @@ HTTPClient.prototype.createAddress = function createAddress(id, options) { }; /** - * Create address. + * Create change address. + * @param {WalletID} id + * @param {Object} options + * @returns {Promise} + */ + +HTTPClient.prototype.createChange = function createChange(id, options) { + var path; + + if (!options) + options = {}; + + if (typeof options === 'string') + options = { account: options }; + + path = '/wallet/' + id + '/change'; + + return this._post(path, options); +}; + +/** + * Create nested address. * @param {WalletID} id * @param {Object} options * @returns {Promise} diff --git a/lib/http/server.js b/lib/http/server.js index 9768a874..b02d642c 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -555,6 +555,10 @@ HTTPServer.prototype._init = function _init() { this.get('/', function(req, res, send, next) { var totalTX = this.mempool ? this.mempool.totalTX : 0; var size = this.mempool ? this.mempool.getSize() : 0; + var uptime = 0; + + if (process.uptime) + uptime = process.uptime(); send(200, { version: constants.USER_VERSION, @@ -569,7 +573,7 @@ HTTPServer.prototype._init = function _init() { progress: this.chain.getProgress(), mempoolTX: totalTX, mempoolSize: size, - uptime: Math.floor(process.uptime()), + uptime: Math.floor(uptime), systemTime: utils.now(), adjustedTime: time.now(), timeOffset: time.offset, @@ -999,6 +1003,14 @@ HTTPServer.prototype._init = function _init() { send(200, address.toJSON()); })); + // Create change address + this.post('/wallet/:id/change', con(function* (req, res, send, next) { + var options = req.options; + var acct = options.name || options.account; + var address = yield req.wallet.createChange(acct); + send(200, address.toJSON()); + })); + // Create nested address this.post('/wallet/:id/nested', con(function* (req, res, send, next) { var options = req.options; diff --git a/lib/http/wallet.js b/lib/http/wallet.js index fb49fc5a..f1e3c73a 100644 --- a/lib/http/wallet.js +++ b/lib/http/wallet.js @@ -7,9 +7,9 @@ 'use strict'; -var Network = require('../protocol/network'); +var assert = require('assert'); var EventEmitter = require('events').EventEmitter; - +var Network = require('../protocol/network'); var utils = require('../utils/utils'); var co = require('../utils/co'); var Client = require('./client'); @@ -41,6 +41,16 @@ function HTTPWallet(options) { this.id = null; this.token = null; + if (options.id) + this.id = options.id; + + if (options.token) { + this.token = options.token; + if (Buffer.isBuffer(this.token)) + this.token = this.token.toString('hex'); + this.client.token = this.token; + } + this._init(); } @@ -90,24 +100,22 @@ HTTPWallet.prototype._init = function _init() { */ HTTPWallet.prototype.open = co(function* open(options) { - var wallet; + if (options) { + if (options.id) + this.id = options.id; - this.id = options.id; - - if (options.token) { - this.token = options.token; - if (Buffer.isBuffer(this.token)) - this.token = this.token.toString('hex'); - this.client.token = this.token; + if (options.token) { + this.token = options.token; + if (Buffer.isBuffer(this.token)) + this.token = this.token.toString('hex'); + this.client.token = this.token; + } } + assert(this.id, 'No ID provided.'); + yield this.client.open(); - - wallet = yield this.client.getWallet(this.id); - yield this.client.join(this.id, this.token); - - return wallet; }); /** @@ -142,6 +150,16 @@ HTTPWallet.prototype.close = function close() { return this.client.close(); }; +/** + * Wait for websocket disconnection. + * @private + * @returns {Promise} + */ + +HTTPWallet.prototype.onDisconnect = function onDisconnect() { + return this.client.onDisconnect(); +}; + /** * @see Wallet#getHistory */ @@ -310,6 +328,14 @@ HTTPWallet.prototype.createAddress = function createAddress(account) { return this.client.createAddress(this.id, account); }; +/** + * @see Wallet#createAddress + */ + +HTTPWallet.prototype.createChange = function createChange(account) { + return this.client.createChange(this.id, account); +}; + /** * @see Wallet#createAddress */