http test. fix path parsing.
This commit is contained in:
parent
747c1a4949
commit
a60a48da9a
@ -133,7 +133,7 @@ function Fullnode(options) {
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: this.options.httpHost || '0.0.0.0',
|
||||
apiKey: this.options.apiKey,
|
||||
auth: this.options.auth
|
||||
walletAuth: this.options.walletAuth
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -221,6 +221,12 @@ HTTPBase.prototype._open = function open(callback) {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype._close = function close(callback) {
|
||||
if (this.io) {
|
||||
this.server.once('close', callback);
|
||||
this.io.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.server.close(callback);
|
||||
};
|
||||
|
||||
|
||||
@ -36,9 +36,19 @@ function HTTPClient(options) {
|
||||
this.options = options;
|
||||
this.network = bcoin.network.get(options.network);
|
||||
|
||||
this.uri = options.uri || 'localhost:' + this.network.rpcPort;
|
||||
this.id = null;
|
||||
this.uri = options.uri || 'http://localhost:' + this.network.rpcPort;
|
||||
this.socket = null;
|
||||
this.apiKey = options.apiKey;
|
||||
this.auth = options.auth;
|
||||
|
||||
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.');
|
||||
}
|
||||
|
||||
// Open automatically.
|
||||
this.open();
|
||||
@ -63,7 +73,7 @@ HTTPClient.prototype._open = function _open(callback) {
|
||||
}
|
||||
|
||||
if (!IOClient)
|
||||
return;
|
||||
return callback();
|
||||
|
||||
this.socket = new IOClient(this.uri);
|
||||
|
||||
@ -71,70 +81,70 @@ HTTPClient.prototype._open = function _open(callback) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.socket.on('version', function(info) {
|
||||
if (info.network !== self.network.type)
|
||||
self.emit('error', new Error('Wrong network.'));
|
||||
});
|
||||
|
||||
this.socket.on('tx', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('tx', tx, map);
|
||||
});
|
||||
|
||||
this.socket.on('confirmed', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('confirmed', tx, map);
|
||||
});
|
||||
|
||||
this.socket.on('updated', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('updated', tx, map);
|
||||
});
|
||||
|
||||
this.socket.on('address', function(receive, change, map) {
|
||||
receive = receive.map(function(address) {
|
||||
return bcoin.keyring.fromJSON(address);
|
||||
});
|
||||
change = change.map(function(address) {
|
||||
return bcoin.keyring.fromJSON(address);
|
||||
});
|
||||
self.emit('address', receive, change, map);
|
||||
});
|
||||
|
||||
this.socket.on('balance', function(balance, id) {
|
||||
self.emit('balance', {
|
||||
confirmed: utils.satoshi(balance.confirmed),
|
||||
unconfirmed: utils.satoshi(balance.unconfirmed),
|
||||
total: utils.satoshi(balance.total)
|
||||
}, id);
|
||||
});
|
||||
|
||||
this.socket.on('balances', function(json) {
|
||||
var balances = {};
|
||||
Object.keys(json).forEach(function(id) {
|
||||
balances[id] = {
|
||||
confirmed: utils.satoshi(json[id].confirmed),
|
||||
unconfirmed: utils.satoshi(json[id].unconfirmed),
|
||||
total: utils.satoshi(json[id].total)
|
||||
};
|
||||
});
|
||||
self.emit('balances', balances);
|
||||
});
|
||||
|
||||
this.socket.on('connect', function() {
|
||||
self.socket.on('version', function(info) {
|
||||
assert(info.network === self.network.type, 'Wrong network.');
|
||||
});
|
||||
|
||||
self.socket.on('tx', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('tx', tx, map);
|
||||
});
|
||||
|
||||
self.socket.on('confirmed', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('confirmed', tx, map);
|
||||
});
|
||||
|
||||
self.socket.on('updated', function(tx, map) {
|
||||
try {
|
||||
tx = bcoin.tx.fromJSON(tx);
|
||||
} catch (e) {
|
||||
return self.emit('error', e);
|
||||
}
|
||||
self.emit('updated', tx, map);
|
||||
});
|
||||
|
||||
self.socket.on('balance', function(balance, id) {
|
||||
self.emit('balance', {
|
||||
confirmed: utils.satoshi(balance.confirmed),
|
||||
unconfirmed: utils.satoshi(balance.unconfirmed),
|
||||
total: utils.satoshi(balance.total)
|
||||
}, id);
|
||||
});
|
||||
|
||||
self.socket.on('address', function(receive, change, map) {
|
||||
receive = receive.map(function(address) {
|
||||
return bcoin.keyring.fromJSON(address);
|
||||
});
|
||||
change = change.map(function(address) {
|
||||
return bcoin.keyring.fromJSON(address);
|
||||
});
|
||||
self.emit('address', receive, change, map);
|
||||
});
|
||||
|
||||
self.socket.on('balances', function(json) {
|
||||
var balances = {};
|
||||
Object.keys(json).forEach(function(id) {
|
||||
balances[id] = {
|
||||
confirmed: utils.satoshi(json[id].confirmed),
|
||||
unconfirmed: utils.satoshi(json[id].unconfirmed),
|
||||
total: utils.satoshi(json[id].total)
|
||||
};
|
||||
});
|
||||
self.emit('balances', balances);
|
||||
});
|
||||
|
||||
self.loaded = true;
|
||||
self.emit('open');
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
@ -159,11 +169,11 @@ HTTPClient.prototype._close = function close(callback) {
|
||||
* @param {WalletID} id
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.join = function join(id) {
|
||||
HTTPClient.prototype.join = function join(id, token) {
|
||||
if (!this.socket)
|
||||
return;
|
||||
|
||||
this.socket.emit('join', id);
|
||||
this.socket.emit('join', id, token);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -182,8 +192,8 @@ HTTPClient.prototype.leave = function leave(id) {
|
||||
* Listen for events on all wallets.
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.all = function all() {
|
||||
this.join('!all');
|
||||
HTTPClient.prototype.all = function all(token) {
|
||||
this.join('!all', token);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -205,8 +215,7 @@ HTTPClient.prototype.none = function none() {
|
||||
|
||||
HTTPClient.prototype._request = function _request(method, endpoint, json, callback) {
|
||||
var self = this;
|
||||
var query;
|
||||
var networkType;
|
||||
var query, network, height;
|
||||
|
||||
if (!callback) {
|
||||
callback = json;
|
||||
@ -218,19 +227,36 @@ HTTPClient.prototype._request = function _request(method, endpoint, json, callba
|
||||
json = true;
|
||||
}
|
||||
|
||||
if (this.apiKey) {
|
||||
if (method === 'get') {
|
||||
query = query || {};
|
||||
query.apiKey = this.apiKey.toString('hex');
|
||||
} else {
|
||||
json = json || {};
|
||||
json.apiKey = this.apiKey.toString('hex');
|
||||
}
|
||||
}
|
||||
|
||||
request({
|
||||
method: method,
|
||||
uri: this.uri + endpoint,
|
||||
query: query,
|
||||
json: json,
|
||||
auth: this.auth,
|
||||
expect: 'json'
|
||||
}, function(err, res, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
networkType = res.headers['x-bcoin-network'];
|
||||
assert(networkType === self.network.type, 'Wrong network.');
|
||||
self.network.updateHeight(+res.headers['x-bcoin-height']);
|
||||
network = res.headers['x-bcoin-network'];
|
||||
|
||||
if (network !== self.network.type)
|
||||
return callback(new Error('Wrong network.'));
|
||||
|
||||
height = +res.headers['x-bcoin-height'];
|
||||
|
||||
if (utils.isNumber(height))
|
||||
self.network.updateHeight(height);
|
||||
|
||||
if (res.statusCode === 404)
|
||||
return callback();
|
||||
@ -820,6 +846,40 @@ HTTPClient.prototype.walletSend = function walletSend(id, options, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a new token.
|
||||
* @param {(String|Buffer)?} passphrase
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.walletRetoken = function walletRetoken(id, passphrase, callback) {
|
||||
var options = { passphrase: passphrase };
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/retoken', options, function(err, body) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
return callback(null, body.token);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Change or set master key's passphrase.
|
||||
* @param {(String|Buffer)?} old
|
||||
* @param {String|Buffer} new_
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.walletSetPassphrase = function walletSetPassphrase(id, old, new_, callback) {
|
||||
var options = { old: old, passphrase: new_ };
|
||||
|
||||
callback = utils.ensure(callback);
|
||||
|
||||
return this._post('/wallet/' + id + '/passphrase', options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a transaction, fill.
|
||||
* @param {WalletID} id
|
||||
|
||||
@ -32,6 +32,8 @@ function HTTPServer(options) {
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.options = options;
|
||||
this.node = options.node;
|
||||
|
||||
@ -221,7 +223,16 @@ HTTPServer.prototype._init = function _init() {
|
||||
if (req.password) {
|
||||
assert(utils.isHex(req.password), 'API key must be a hex string.');
|
||||
assert(req.password.length === 64, 'API key must be 32 bytes.');
|
||||
options.apiKey = new Buffer(req.password, 'hex');
|
||||
options.token = new Buffer(req.password, 'hex');
|
||||
}
|
||||
|
||||
if (req.headers['x-bcoin-api-key'])
|
||||
params.apiKey = req.headers['x-bcoin-api-key'];
|
||||
|
||||
if (params.apiKey) {
|
||||
assert(utils.isHex(params.apiKey), 'API key must be a hex string.');
|
||||
assert(params.apiKey.length === 64, 'API key must be 32 bytes.');
|
||||
options.apiKey = new Buffer(params.apiKey, 'hex');
|
||||
}
|
||||
|
||||
req.options = options;
|
||||
@ -230,21 +241,20 @@ HTTPServer.prototype._init = function _init() {
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
if (req.path.length < 2 || req.path[0] !== 'wallet') {
|
||||
if (self.apiKey) {
|
||||
if (!utils.ccmp(req.options.apiKey, self.apiKey)) {
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="node"');
|
||||
send(401, { error: 'Unauthorized.' });
|
||||
return;
|
||||
}
|
||||
if (self.apiKey) {
|
||||
if (!utils.ccmp(req.options.apiKey, self.apiKey)) {
|
||||
send(403, { error: 'Forbidden.' });
|
||||
return;
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!self.options.auth)
|
||||
if (req.path.length < 2 || req.path[0] !== 'wallet')
|
||||
return next();
|
||||
|
||||
self.walletdb.auth(req.options.id, req.options.apiKey, function(err) {
|
||||
if (!self.options.walletAuth)
|
||||
return next();
|
||||
|
||||
self.walletdb.auth(req.options.id, req.options.token, function(err) {
|
||||
if (err) {
|
||||
if (err.message === 'Wallet not found.')
|
||||
return next();
|
||||
@ -255,6 +265,7 @@ HTTPServer.prototype._init = function _init() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.logger.info('Successful auth for %s.', req.options.id);
|
||||
next();
|
||||
});
|
||||
});
|
||||
@ -515,16 +526,6 @@ HTTPServer.prototype._init = function _init() {
|
||||
});
|
||||
});
|
||||
|
||||
// Broadcast TX
|
||||
this.post('/wallet/:id/broadcast', function(req, res, next, send) {
|
||||
self.node.sendTX(req.options.tx, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
send(200, { success: true });
|
||||
});
|
||||
});
|
||||
|
||||
// Send TX
|
||||
this.post('/wallet/:id/send', function(req, res, next, send) {
|
||||
var id = req.options.id;
|
||||
@ -833,25 +834,17 @@ HTTPServer.prototype._initIO = function _initIO() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
socket.on('join', function(id, apiKey) {
|
||||
if (!self.options.auth) {
|
||||
socket.on('join', function(id, token) {
|
||||
if (!self.options.walletAuth) {
|
||||
socket.join(id);
|
||||
return;
|
||||
}
|
||||
if (id === '!all') {
|
||||
if (self.apiKey) {
|
||||
if (!utils.ccmp(apiKey, self.apiKey)) {
|
||||
self.logger.info('Auth failure for %s.', id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return socket.join(id);
|
||||
}
|
||||
self.walletdb.auth(id, apiKey, function(err) {
|
||||
self.walletdb.auth(id, token, function(err) {
|
||||
if (err) {
|
||||
self.logger.info('Auth failure for %s: %s.', id, err.message);
|
||||
return;
|
||||
}
|
||||
self.logger.info('Successful auth for %s.', id);
|
||||
socket.join(id);
|
||||
});
|
||||
});
|
||||
@ -912,17 +905,13 @@ HTTPServer.prototype._initIO = function _initIO() {
|
||||
this.walletdb.on('address', function(receive, change, map) {
|
||||
var summary = map.toJSON();
|
||||
|
||||
if (receive) {
|
||||
receive = receive.map(function(address) {
|
||||
return address.toJSON();
|
||||
});
|
||||
}
|
||||
receive = receive.map(function(address) {
|
||||
return address.toJSON();
|
||||
});
|
||||
|
||||
if (change) {
|
||||
change = change.map(function(address) {
|
||||
return address.toJSON();
|
||||
});
|
||||
}
|
||||
change = change.map(function(address) {
|
||||
return address.toJSON();
|
||||
});
|
||||
|
||||
map.getWallets().forEach(function(id) {
|
||||
self.server.io.to(id).emit('address', receive, change, summary);
|
||||
|
||||
@ -37,6 +37,8 @@ function HTTPWallet(options) {
|
||||
|
||||
this.client = new http.client(options);
|
||||
this.uri = options.uri;
|
||||
this.id = null;
|
||||
this.token = null;
|
||||
|
||||
this._init();
|
||||
}
|
||||
@ -63,8 +65,8 @@ HTTPWallet.prototype._init = function _init() {
|
||||
self.emit('updated', tx, map);
|
||||
});
|
||||
|
||||
this.client.on('balance', function(balance, map) {
|
||||
self.emit('balance', balance, map);
|
||||
this.client.on('balance', function(balance, id) {
|
||||
self.emit('balance', balance, id);
|
||||
});
|
||||
|
||||
this.client.on('address', function(receive, change, map) {
|
||||
@ -74,8 +76,6 @@ HTTPWallet.prototype._init = function _init() {
|
||||
this.client.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.client.join(this.id);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,12 +84,39 @@ HTTPWallet.prototype._init = function _init() {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.open = function open(callback) {
|
||||
HTTPWallet.prototype.open = function open(options, callback) {
|
||||
var self = this;
|
||||
|
||||
if (options.token) {
|
||||
if (typeof options.token === 'string') {
|
||||
assert(utils.isHex(options.token), 'API key must be a hex string.');
|
||||
options.token = new Buffer(options.token, 'hex');
|
||||
}
|
||||
assert(Buffer.isBuffer(options.token));
|
||||
assert(options.token.length === 32, 'API key must be 32 bytes.');
|
||||
this.id = options.id;
|
||||
this.client.auth = { username: 'x', password: options.token.toString('hex') };
|
||||
}
|
||||
|
||||
this.client.open(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.createWallet(self.options, callback);
|
||||
|
||||
if (options.token) {
|
||||
self.token = options.token;
|
||||
self.client.join(options.id, options.token.toString('hex'));
|
||||
return 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.join(self.id, wallet.token);
|
||||
callback(null, wallet);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -179,16 +206,16 @@ HTTPWallet.prototype.zap = function zap(account, age, callback) {
|
||||
* @see Wallet#createTX
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.createTX = function createTX(tx, options, outputs, callback) {
|
||||
return this.client.walletCreate(this.id, tx, options, outputs, callback);
|
||||
HTTPWallet.prototype.createTX = function createTX(options, outputs, callback) {
|
||||
return this.client.walletCreate(this.id, options, outputs, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @see HTTPClient#walletSend
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.send = function send(tx, options, callback) {
|
||||
return this.client.walletSend(this.id, tx, options, callback);
|
||||
HTTPWallet.prototype.send = function send(options, callback) {
|
||||
return this.client.walletSend(this.id, options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,6 +258,31 @@ HTTPWallet.prototype.createAccount = function createAccount(options, callback) {
|
||||
return this.client.createWalletAccount(this.id, options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @see Wallet#setPassphrase
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.setPassphrase = function setPassphrase(old, _new, callback) {
|
||||
return this.client.walletSetPassphrase(this.id, old, _new, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @see Wallet#retoken
|
||||
*/
|
||||
|
||||
HTTPWallet.prototype.retoken = function retoken(passphrase, callback) {
|
||||
var self = this;
|
||||
return this.client.walletRetoken(this.id, passphrase, function(err, token) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.client.auth = { username: 'x', password: token };
|
||||
self.token = new Buffer(token, 'hex');
|
||||
|
||||
return callback(null, token);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -81,7 +81,7 @@ function SPVNode(options) {
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: this.options.httpHost || '0.0.0.0',
|
||||
apiKey: this.options.apiKey,
|
||||
auth: this.options.auth
|
||||
walletAuth: this.options.walletAuth
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1937,6 +1937,22 @@ WalletMap.prototype.fromTX = function fromTX(table, tx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Already have a member for this account.
|
||||
// i.e. Different address, but same account.
|
||||
if (member) {
|
||||
// Increment value.
|
||||
if (io.coin)
|
||||
member.value += io.coin.value;
|
||||
else if (io.value)
|
||||
member.value += io.value;
|
||||
|
||||
// Set address and add path.
|
||||
path.address = address;
|
||||
member.paths.push(path);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a member for this account.
|
||||
assert(!member);
|
||||
member = MapMember.fromPath(path);
|
||||
@ -1966,7 +1982,8 @@ WalletMap.prototype.fromTX = function fromTX(table, tx) {
|
||||
// Update this guy last so the above if
|
||||
// clause does not return true while
|
||||
// we're still iterating over paths.
|
||||
hashes[hash] = true;
|
||||
if (paths.length > 0)
|
||||
hashes[hash] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -377,6 +377,7 @@ Wallet.prototype.unlock = function unlock(passphrase, timeout, callback) {
|
||||
* It is represented as `m/44` (public) hashed
|
||||
* and converted to an address with a prefix
|
||||
* of `0x03be04` (`WLT` in base58).
|
||||
* @private
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
@ -400,6 +401,8 @@ Wallet.prototype.getID = function getID() {
|
||||
/**
|
||||
* Generate the wallet api key if none was passed in.
|
||||
* It is represented as HASH256(m/44'->public|nonce).
|
||||
* @private
|
||||
* @param {HDPrivateKey} master
|
||||
* @param {Number} nonce
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
@ -779,6 +782,12 @@ Wallet.prototype.deriveInputs = function deriveInputs(tx, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve a single keyring by address hash.
|
||||
* @param {Hash} hash
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
Wallet.prototype.getKeyring = function getKeyring(hash, callback) {
|
||||
var self = this;
|
||||
var address;
|
||||
|
||||
@ -474,6 +474,7 @@ WalletDB.prototype.save = function save(wallet, callback) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.auth = function auth(id, token, callback) {
|
||||
var self = this;
|
||||
var wallet;
|
||||
|
||||
if (!id)
|
||||
@ -1154,14 +1155,14 @@ WalletDB.prototype.fetchWallet = function fetchWallet(id, callback, handler) {
|
||||
if (!wallet)
|
||||
return callback(new Error('No wallet.'));
|
||||
|
||||
handler(wallet, function(err, result) {
|
||||
handler(wallet, function(err, res1, res2) {
|
||||
// Kill the reference.
|
||||
wallet.destroy();
|
||||
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
callback(null, result);
|
||||
callback(null, res1, res2);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
178
test/http-test.js
Normal file
178
test/http-test.js
Normal file
@ -0,0 +1,178 @@
|
||||
'use strict';
|
||||
|
||||
var bn = require('bn.js');
|
||||
var bcoin = require('../').set('regtest');
|
||||
var constants = bcoin.protocol.constants;
|
||||
var network = bcoin.protocol.network;
|
||||
var utils = bcoin.utils;
|
||||
var assert = require('assert');
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
|
||||
var dummyInput = {
|
||||
prevout: {
|
||||
hash: constants.NULL_HASH,
|
||||
index: 0
|
||||
},
|
||||
coin: {
|
||||
version: 1,
|
||||
height: 0,
|
||||
value: constants.MAX_MONEY,
|
||||
script: new bcoin.script([]),
|
||||
coinbase: false,
|
||||
hash: constants.NULL_HASH,
|
||||
index: 0
|
||||
},
|
||||
script: new bcoin.script([]),
|
||||
witness: new bcoin.witness([]),
|
||||
sequence: 0xffffffff
|
||||
};
|
||||
|
||||
describe('HTTP', function() {
|
||||
var request = bcoin.http.request;
|
||||
var apiKey = utils.hash256(new Buffer([]));
|
||||
var w, addr, hash;
|
||||
|
||||
this.timeout(15000);
|
||||
|
||||
var node = new bcoin.fullnode({
|
||||
network: 'regtest',
|
||||
apiKey: apiKey,
|
||||
walletAuth: true
|
||||
});
|
||||
|
||||
var wallet = new bcoin.http.wallet({
|
||||
network: 'regtest',
|
||||
apiKey: apiKey
|
||||
});
|
||||
|
||||
node.on('error', function() {});
|
||||
|
||||
it('should open node', function(cb) {
|
||||
constants.tx.COINBASE_MATURITY = 0;
|
||||
node.open(cb);
|
||||
});
|
||||
|
||||
it('should create wallet', function(cb) {
|
||||
wallet.open({ id: 'test' }, function(err, wallet) {
|
||||
assert.ifError(err);
|
||||
assert.equal(wallet.id, 'test');
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get info', function(cb) {
|
||||
wallet.client.getInfo(function(err, info) {
|
||||
assert.ifError(err);
|
||||
assert.equal(info.network, node.network.type);
|
||||
assert.equal(info.version, constants.USER_VERSION);
|
||||
assert.equal(info.agent, constants.USER_AGENT);
|
||||
assert.equal(info.height, 0);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get wallet info', function(cb) {
|
||||
wallet.getInfo(function(err, wallet) {
|
||||
assert.ifError(err);
|
||||
assert.equal(wallet.id, 'test');
|
||||
addr = wallet.account.receiveAddress;
|
||||
assert.equal(typeof addr, 'string');
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
it('should get internal wallet', function(cb) {
|
||||
node.walletdb.get('test', function(err, w_) {
|
||||
assert.ifError(err);
|
||||
assert(w_);
|
||||
w = w_;
|
||||
cb();
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
it('should fill with funds', function(cb) {
|
||||
var balance, receive;
|
||||
|
||||
// Coinbase
|
||||
var t1 = bcoin.mtx()
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460);
|
||||
|
||||
t1.addInput(dummyInput);
|
||||
|
||||
wallet.once('balance', function(b, id) {
|
||||
balance = b;
|
||||
});
|
||||
|
||||
wallet.once('address', function(r, c, map) {
|
||||
receive = r[0];
|
||||
});
|
||||
|
||||
node.walletdb.addTX(t1, function(err) {
|
||||
assert.ifError(err);
|
||||
setTimeout(function() {
|
||||
return cb();
|
||||
assert(receive);
|
||||
assert.equal(receive.id, 'test');
|
||||
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);
|
||||
cb();
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should send a tx', function(cb) {
|
||||
var options = {
|
||||
rate: 10000,
|
||||
outputs: [{
|
||||
value: 10000,
|
||||
address: addr
|
||||
}]
|
||||
};
|
||||
|
||||
wallet.send(options, function(err, tx) {
|
||||
assert.ifError(err);
|
||||
assert(tx);
|
||||
assert.equal(tx.inputs.length, 1);
|
||||
assert.equal(tx.outputs.length, 2);
|
||||
assert.equal(tx.getOutputValue(), 48190);
|
||||
hash = tx.hash('hex');
|
||||
node.walletdb.addTX(tx, function(err) {
|
||||
assert.ifError(err);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get a tx', function(cb) {
|
||||
wallet.getTX(hash, function(err, tx) {
|
||||
assert.ifError(err);
|
||||
assert(tx);
|
||||
assert.equal(tx.hash('hex'), hash);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should cleanup', function(cb) {
|
||||
constants.tx.COINBASE_MATURITY = 100;
|
||||
node.close(cb);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user