UNPKG

@bpanel/bpanel-utils

Version:
410 lines (336 loc) 11.7 kB
/*! * clients.js - client extensions of bclient to connect to bpanel app server * Copyright (c) 2018, Bcoin Devs (MIT License). * https://github.com/bcoin-org/bpanel-utils */ 'use strict'; exports.__esModule = true; var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _bclient = require('bclient'); var _bclient2 = _interopRequireDefault(_bclient); var _hsClient = require('hs-client'); var _hsClient2 = _interopRequireDefault(_hsClient); var _bcurl = require('bcurl'); var _bsert = require('bsert'); var _bsert2 = _interopRequireDefault(_bsert); var _bmultisig = require('bmultisig'); var _chain = require('./chain'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var BNodeClient = _bclient2.default.NodeClient, BWalletClient = _bclient2.default.WalletClient; var HNodeClient = _hsClient2.default.NodeClient, HWalletClient = _hsClient2.default.WalletClient; class BPClient extends _bcurl.Client { /** * Create a client for use in bPanel. * @constructor * @param {Object} options * @param {string} [options.path] - base path * @param {string} options.id - id of node client will be querying * @param {chain} options.chain - one of 'bitcoin', 'bitcoincash', * or 'handshake'. Will assume 'bitcoin' if not set * @param {NodeClient} [node] - can optionally pass a node client * @param {WalletClient} [wallet] - can optionally pass a wallet client * @param {MultisigClient} [multisig] - can optionally pass a multisig client * @returns {BPClient} */ constructor(options) { super(options); var opts = new ClientOptions(options); // keep ref to pass to generated clients this.options = (0, _extends3.default)({}, options, opts); this.path = opts.path; this.id = opts.id; this.chain = opts.chain; this.node = opts.node; this.wallet = opts.wallet; this.multisig = opts.multisig; // supported client types this.types = ['node', 'wallet', 'multisig']; this.init(); } init() { var _this = this; return (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() { return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!_this.id) { _context.next = 6; break; } _this.setNodeClient(); _this.setWalletClient(); _this.setMultisigClient(); _context.next = 6; return _this.setSPV(); case 6: return _context.abrupt('return', _this); case 7: case 'end': return _context.stop(); } } }, _callee, _this); }))(); } /* * Reset the class with new options * since the base options start as null * any options that are not explicitly reset * will be gone. * @returns {BpanelClient} */ reset(options) { return new this.constructor(options); } /* * Set a new id and chain if necessary * will update all clients as well * @param {string} id - id for client * @param {string} chain - One of 'bitcoin', * 'bitcoincash', or 'handshake' * @returns {BPClient} */ setClientInfo(id, chain) { var _this2 = this; return (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: (0, _bsert2.default)(id && typeof id === 'string'); _this2.id = id; if (chain) { (0, _bsert2.default)(typeof chain === 'string'); (0, _bsert2.default)((0, _chain.isChainSupported)(chain), chain + ' is not a supported chain'); _this2.chain = chain; } _this2.options.id = _this2.id; _this2.options.chain = _this2.chain; _this2.setNodeClient(); _this2.setWalletClient(); _this2.setMultisigClient(); _context2.next = 10; return _this2.setSPV(); case 10: _this2.emit('set clients', { id: _this2.id, chain: _this2.chain }); return _context2.abrupt('return', _this2); case 12: case 'end': return _context2.stop(); } } }, _callee2, _this2); }))(); } /** * Get an object of all clients available on server * @returns {Promise} */ getClients() { return this.get('/clients'); } /** * Get info for default client on the server * @returns {Promise} */ getDefault() { return this.get('/clients/default'); } /** * Get info from bPanel server about client of this.id * @param {string} [_id] - id of client you'd like to get * info for * @returns {Promise} */ getClientInfo(_id) { var health = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var id = _id ? _id : this.id; return this.get('/clients/' + id, { health: health }); } /* * Get a client for sending requests to a node * Returns this.node and sets it if none is set * @returns {Client} */ getNodeClient() { if (!this.node) this.setNodeClient(); return this.node; } /* * Get a client for sending requests to a wallet node * Returns this.wallet and sets it if none is set * @returns {Client} */ getWalletClient() { if (!this.wallet) this.setWalletClient(); return this.wallet; } /* * Get a client for sending requests to a multisig node * Returns this.multisig and sets it if none is set * @returns {Client} */ getMultisigClient() { if (!this.multisig) this.setMultisigClient(); return this.multisig; } /* * Set the node client for the class * @param {string} _path - Can set a custom path * @returns {void} */ setNodeClient() { var _path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var path = _path; if (!path) { (0, _bsert2.default)(this.id, 'Must have an id before setting node'); path = this.getClientPaths(this.id).node; } var options = (0, _extends3.default)({}, this.options, { path: path }); if (this.chain === 'handshake') this.node = new HNodeClient(options); // defaults to returning bcoin client else this.node = new BNodeClient(options); this.emit('set node', { id: this.id, chain: this.chain }); } /* * Set the wallet client for the class * @param {string} _path - Can set a custom path * @returns {void} */ setWalletClient() { var _path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var path = _path; if (!path) { (0, _bsert2.default)(this.id, 'Must have an id before setting node'); path = this.getClientPaths(this.id).wallet; } var options = (0, _extends3.default)({}, this.options, { path: path }); if (this.chain === 'handshake') this.wallet = new HWalletClient(options); // defaults to returning bcoin client else this.wallet = new BWalletClient(options); this.emit('set wallet', { id: this.id, chain: this.chain }); } /* * Set the wallet client for the class * @param {string} _path - Can set a custom path * @returns {void} */ setMultisigClient() { var _path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var path = _path; if (!path) { (0, _bsert2.default)(this.id, 'Must have an id before setting node'); path = this.getClientPaths(this.id).multisig; } var options = (0, _extends3.default)({}, this.options, { path: path }); this.multisig = new _bmultisig.Client(options); this.emit('set multisig', { id: this.id, chain: this.chain }); } /* * Get path for the client of a given id. Defaults to this.id * @param {string} [_id] - pass an id to get paths for another client * @returns {object} paths - object with client types mapped to endpoint * in format: `/clients/:id/:type` where type can be 'node', * 'wallet', or 'multisig' */ getClientPaths(_id) { var id = _id ? _id : this.id; return this.types.reduce(function (paths, type) { paths[type] = '/clients/' + id + '/' + type; return paths; }, {}); } /* * Until bcoin, bcash and hsd return SPV flags in `info` we need to test */ setSPV() { var _this3 = this; return (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3() { return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.prev = 0; _context3.next = 3; return _this3.node.getBlock(0); case 3: _this3.isSPV = false; _context3.next = 9; break; case 6: _context3.prev = 6; _context3.t0 = _context3['catch'](0); _this3.isSPV = true; case 9: case 'end': return _context3.stop(); } } }, _callee3, _this3, [[0, 6]]); }))(); } } /** * Client Options */ class ClientOptions { constructor(options) { this.id = ''; this.path = ''; this.chain = null; this.node = null; this.wallet = null; this.multisig = null; if (options) this.fromOptions(options); } fromOptions(options) { var id = options.id, chain = options.chain, path = options.path, node = options.node, wallet = options.wallet, multisig = options.multisig; if (id) { (0, _bsert2.default)(typeof id === 'string'); this.id = id; } if (chain) { (0, _bsert2.default)(typeof chain === 'string'); (0, _bsert2.default)((0, _chain.isChainSupported)(chain), chain + ' is not a supported chain'); this.chain = chain; } if (node) { (0, _bsert2.default)(node instanceof _bcurl.Client); // want to make sure that the client matches with the chain if (this.chain === 'bitcoin' || this.chain === 'bitcoincash') (0, _bsert2.default)(node instanceof BNodeClient); if (this.chain === 'handshake') (0, _bsert2.default)(node instanceof HNodeClient); this.node = node; } if (wallet) { (0, _bsert2.default)(wallet instanceof _bcurl.Client); // want to make sure that the client matches with the chain if (this.chain === 'bitcoin' || this.chain === 'bitcoincash') (0, _bsert2.default)(wallet instanceof BWalletClient); if (this.chain === 'handshake') (0, _bsert2.default)(wallet instanceof HWalletClient); this.wallet = wallet; } if (multisig) { (0, _bsert2.default)(multisig instanceof _bmultisig.Client); this.multisig = multisig; } if (path) { // TODO: add more robust path handling similar to bmultisig client (0, _bsert2.default)(typeof path === 'string'); this.path = path; } return this; } } exports.default = BPClient;