more http.

This commit is contained in:
Christopher Jeffrey 2016-04-01 17:02:14 -07:00
parent d83a68523e
commit c030d2480d
5 changed files with 144 additions and 16 deletions

View File

@ -6,6 +6,7 @@
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var bcoin = require('../../bcoin'); var bcoin = require('../../bcoin');
var network = bcoin.protocol.network;
var utils = require('../utils'); var utils = require('../utils');
var request = require('./request'); var request = require('./request');
@ -13,15 +14,19 @@ var request = require('./request');
* Client * Client
*/ */
function Client(uri) { function Client(uri, options) {
if (!(this instanceof Client)) if (!(this instanceof Client))
return new Client(uri); return new Client(uri, options);
if (!options)
options = {};
EventEmitter.call(this); EventEmitter.call(this);
this.uri = uri; this.uri = uri;
this.loaded = false; this.loaded = false;
this.id = null; this.id = null;
this.options = options;
this._init(); this._init();
} }
@ -43,6 +48,13 @@ Client.prototype._init = function _init() {
this.socket = new io.Socket(this.uri); this.socket = new io.Socket(this.uri);
this.socket.on('open', function() { this.socket.on('open', function() {
self.socket.on('version', function(info) {
utils.debug('Connected to bcoin server: %s (%s)',
info.version, info.network);
if (self.options.setNetwork)
network.set(info.network);
});
self.socket.on('tx', function(tx, map) { self.socket.on('tx', function(tx, map) {
try { try {
tx = bcoin.tx.fromJSON(tx); tx = bcoin.tx.fromJSON(tx);
@ -105,10 +117,16 @@ Client.prototype.open = function open(callback) {
}; };
Client.prototype.listenWallet = function listenWallet(id) { Client.prototype.listenWallet = function listenWallet(id) {
if (!this.socket)
return;
this.socket.join(id); this.socket.join(id);
}; };
Client.prototype.unlistenWallet = function unlistenWallet(id) { Client.prototype.unlistenWallet = function unlistenWallet(id) {
if (!this.socket)
return;
this.socket.leave(id); this.socket.leave(id);
}; };
@ -134,7 +152,9 @@ Client.prototype.destroy = function destroy(callback) {
}; };
Client.prototype._request = function _request(method, endpoint, json, callback) { Client.prototype._request = function _request(method, endpoint, json, callback) {
var self = this;
var query; var query;
var networkType;
if (!callback) { if (!callback) {
callback = json; callback = json;
@ -142,13 +162,13 @@ Client.prototype._request = function _request(method, endpoint, json, callback)
} }
if (json && method === 'get') { if (json && method === 'get') {
json = null;
query = json; query = json;
json = true;
} }
request({ request({
method: method, method: method,
uri: this.uri + '/' + endpoint, uri: this.uri + endpoint,
query: query, query: query,
json: json, json: json,
expect: 'json' expect: 'json'
@ -156,6 +176,12 @@ Client.prototype._request = function _request(method, endpoint, json, callback)
if (err) if (err)
return callback(err); return callback(err);
if (self.options.setNetwork) {
networkType = res.headers['x-bcoin-network'];
if (networkType && network.type !== networkType)
network.set(networkType);
}
if (res.statusCode === 404) if (res.statusCode === 404)
return callback(); return callback();
@ -198,6 +224,7 @@ Client.prototype._getWallet = function getWallet(id, callback) {
}; };
Client.prototype.getWallet = function getWallet(id, passphrase, callback) { Client.prototype.getWallet = function getWallet(id, passphrase, callback) {
var self = this;
var provider; var provider;
return this._getWallet(id, function(err, json) { return this._getWallet(id, function(err, json) {
@ -217,7 +244,8 @@ Client.prototype.getWallet = function getWallet(id, passphrase, callback) {
}; };
Client.prototype.createWallet = function createWallet(options, callback) { Client.prototype.createWallet = function createWallet(options, callback) {
return this._createWallet(options, function(err) { var self = this;
return this._createWallet(options, function(err, json) {
if (err) if (err)
return callback(err); return callback(err);
@ -302,8 +330,8 @@ Client.prototype.getWalletBalance = function getBalance(id, callback) {
return callback(new Error('Not found.')); return callback(new Error('Not found.'));
return callback(null, { return callback(null, {
confirmed: utils.satoshi(body.balance.confirmed), confirmed: utils.satoshi(body.confirmed),
unconfirmed: utils.satoshi(body.balance.unconfirmed) unconfirmed: utils.satoshi(body.unconfirmed)
}); });
}); });
}; };
@ -563,6 +591,38 @@ Client.prototype.zapWallet = function zapWallet(id, now, age, callback) {
}); });
}; };
Client.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);
});
};
Client.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);
});
};
/** /**
* Expose * Expose
*/ */

View File

@ -99,8 +99,9 @@ HTTPServer.prototype._initRouter = function _initRouter() {
req.destroy(); req.destroy();
req.socket.destroy(); req.socket.destroy();
} catch (e) { } catch (e) {
; utils.debug(e.stack + '');
} }
utils.debug(err.stack + '');
} }
} }
@ -208,22 +209,53 @@ HTTPServer.prototype.use = function use(path, callback) {
path = null; path = null;
} }
if (Array.isArray(path)) {
path.forEach(function(path) {
this.use(path, callback);
}, this);
return;
}
this.stack.push({ path: path, callback: callback }); this.stack.push({ path: path, callback: callback });
}; };
HTTPServer.prototype.get = function get(path, callback) { HTTPServer.prototype.get = function get(path, callback) {
if (Array.isArray(path)) {
path.forEach(function(path) {
this.get(path, callback);
}, this);
return;
}
this.routes.get.push({ path: path, callback: callback }); this.routes.get.push({ path: path, callback: callback });
}; };
HTTPServer.prototype.post = function post(path, callback) { HTTPServer.prototype.post = function post(path, callback) {
if (Array.isArray(path)) {
path.forEach(function(path) {
this.post(path, callback);
}, this);
return;
}
this.routes.post.push({ path: path, callback: callback }); this.routes.post.push({ path: path, callback: callback });
}; };
HTTPServer.prototype.put = function put(path, callback) { HTTPServer.prototype.put = function put(path, callback) {
if (Array.isArray(path)) {
path.forEach(function(path) {
this.put(path, callback);
}, this);
return;
}
this.routes.put.push({ path: path, callback: callback }); this.routes.put.push({ path: path, callback: callback });
}; };
HTTPServer.prototype.del = function del(path, callback) { HTTPServer.prototype.del = function del(path, callback) {
if (Array.isArray(path)) {
path.forEach(function(path) {
this.del(path, callback);
}, this);
return;
}
this.routes.del.push({ path: path, callback: callback }); this.routes.del.push({ path: path, callback: callback });
}; };

View File

@ -84,6 +84,11 @@ function request(options, callback, stream) {
type = 'binary'; type = 'binary';
} }
if (type === 'json' && typeof body === 'object')
body = JSON.stringify(body);
else if (type === 'form' && typeof body === 'object')
body = qs.stringify(body);
if (type === 'form') if (type === 'form')
type = 'application/x-www-form-urlencoded; charset=utf-8'; type = 'application/x-www-form-urlencoded; charset=utf-8';
else if (type === 'json') else if (type === 'json')
@ -93,11 +98,6 @@ function request(options, callback, stream) {
else if (type === 'binary') else if (type === 'binary')
type = 'application/octet-stream'; type = 'application/octet-stream';
if (type === 'json' && typeof body === 'object')
body = JSON.stringify(body);
else if (type === 'form' && typeof body === 'object')
body = qs.stringify(body);
if (typeof body === 'string') if (typeof body === 'string')
body = new Buffer(body, 'utf8'); body = new Buffer(body, 'utf8');

View File

@ -6,6 +6,8 @@
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var bcoin = require('../../bcoin'); var bcoin = require('../../bcoin');
var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network;
var HTTPServer = require('./http'); var HTTPServer = require('./http');
var utils = require('../utils'); var utils = require('../utils');
var assert = utils.assert; var assert = utils.assert;
@ -47,6 +49,9 @@ NodeServer.prototype._init = function _init() {
return res.end(); return res.end();
} }
res.setHeader('X-Bcoin-Network', network.type);
res.setHeader('X-Bcoin-Version', constants.userAgent);
next(); next();
}); });
@ -164,7 +169,7 @@ NodeServer.prototype._init = function _init() {
// Bulk read UTXOs // Bulk read UTXOs
this.post('/coin/address', function(req, res, next, send) { this.post('/coin/address', function(req, res, next, send) {
self.node.getCoinsByAddress(req.body.addresses, function(err, coins) { self.node.getCoinsByAddress(req.options.addresses, function(err, coins) {
if (err) if (err)
return next(err); return next(err);
@ -207,7 +212,7 @@ NodeServer.prototype._init = function _init() {
// Bulk read TXs // Bulk read TXs
this.post('/tx/address', function(req, res, next, send) { this.post('/tx/address', function(req, res, next, send) {
self.node.getTXByAddress(req.body.addresses, function(err, txs) { self.node.getTXByAddress(req.options.addresses, function(err, txs) {
if (err) if (err)
return next(err); return next(err);
@ -248,7 +253,7 @@ NodeServer.prototype._init = function _init() {
}); });
// Create/get wallet // Create/get wallet
this.post('/wallet/:id', function(req, res, next, send) { this.post(['/wallet', '/wallet/:id'], function(req, res, next, send) {
self.walletdb.create(req.options, function(err, wallet) { self.walletdb.create(req.options, function(err, wallet) {
var json; var json;
@ -507,7 +512,13 @@ NodeServer.prototype._initIO = function _initIO() {
socket.on('error', function(err) { socket.on('error', function(err) {
self.emit('error', err); self.emit('error', err);
}); });
self.emit('websocket', socket); self.emit('websocket', socket);
socket.emit('version', {
version: constants.userAgent,
network: network.type
});
}); });
this.walletdb.on('tx', function(tx, map) { this.walletdb.on('tx', function(tx, map) {

View File

@ -1012,6 +1012,31 @@ Wallet.prototype.__defineGetter__('address', function() {
return this.getAddress(); return this.getAddress();
}); });
Wallet.prototype.inspect = function inspect() {
return {
id: this.id,
type: this.type,
network: network.type,
m: this.m,
n: this.n,
keyAddress: this.keyAddress,
scriptAddress: this.scriptAddress,
programAddress: this.programAddress,
witness: this.witness,
derivation: this.derivation,
copayBIP45: this.copayBIP45,
accountIndex: this.accountIndex,
receiveDepth: this.receiveDepth,
changeDepth: this.changeDepth,
master: this.master.toJSON(this.options.passphrase),
accountKey: this.accountKey.xpubkey,
addressMap: this.addressMap,
keys: this.keys.map(function(key) {
return key.xpubkey;
})
};
};
Wallet.prototype.toJSON = function toJSON() { Wallet.prototype.toJSON = function toJSON() {
return { return {
v: 3, v: 3,