diff --git a/lib/bcoin/txdb.js b/lib/bcoin/txdb.js index db1960c1..527aefcf 100644 --- a/lib/bcoin/txdb.js +++ b/lib/bcoin/txdb.js @@ -1399,6 +1399,27 @@ TXDB.prototype.filterLocked = function filterLocked(coins) { return coins; }; +/** + * Return an array of all locked outpoints. + * @returns {Outpoint[]} + */ + +TXDB.prototype.getLocked = function getLocked() { + var keys = Object.keys(this.locked); + var outpoints = []; + var i, key, hash, index; + + for (i = 0; i < keys.length; i++) { + key = keys[i]; + hash = key.slice(0, 64); + index = +key.slice(64); + outpoint = new bcoin.outpoint(hash, index); + outpoints.push(outpoint); + } + + return outpoints; +}; + /** * Get hashes of all transactions in the database. * @param {Number?} account diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index cec5e666..ebe736ec 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -738,8 +738,48 @@ Wallet.prototype.hasAddress = function hasAddress(address, callback) { * @param {Function} callback - Returns [Error, {@link Path}]. */ -Wallet.prototype.getPath = function getPath(address, callback) { - return this.db.getPath(this.wid, address, callback); +Wallet.prototype.getAddressPath = function getAddressPath(address, callback) { + var self = this; + this.db.getAddressPath(this.wid, address, function(err, path) { + if (err) + return callback(err); + + if (!path) + return callback(); + + path.id = self.id; + + return callback(null, path); + }); +}; + +/** + * Get all wallet paths. + * @param {Number} account + * @param {Function} callback - Returns [Error, {@link Path}]. + */ + +Wallet.prototype.getPaths = function getPaths(account, callback) { + var self = this; + var out = []; + var i, path; + + this._getIndex(account, callback, function(account, callback) { + this.db.getWalletPaths(this.wid, function(err, paths) { + if (err) + return callback(err); + + for (i = 0; i < paths.length; i++) { + path = paths[i]; + if (!account || path.account === account) { + path.id = self.id; + out.push(path); + } + } + + return callback(null, out); + }); + }); }; /** @@ -1024,7 +1064,7 @@ Wallet.prototype.getKeyring = function getKeyring(hash, callback) { if (!hash) return callback(); - this.getPath(hash, function(err, path) { + this.getAddressPath(hash, function(err, path) { if (err) return callback(err); @@ -1059,7 +1099,7 @@ Wallet.prototype.getInputPaths = function getInputPaths(tx, callback) { function done() { utils.forEachSerial(hashes, function(hash, next, i) { - self.getPath(hash, function(err, path) { + self.getAddressPath(hash, function(err, path) { if (err) return next(err); @@ -1117,7 +1157,7 @@ Wallet.prototype.getOutputPaths = function getOutputPaths(tx, callback) { } utils.forEachSerial(hashes, function(hash, next, i) { - self.getPath(hash, function(err, path) { + self.getAddressPath(hash, function(err, path) { if (err) return next(err); @@ -1282,7 +1322,7 @@ Wallet.prototype.getRedeem = function getRedeem(hash, callback) { if (typeof hash === 'string') hash = new Buffer(hash, 'hex'); - this.getPath(hash.toString('hex'), function(err, path) { + this.getAddressPath(hash.toString('hex'), function(err, path) { if (err) return callback(err); @@ -2378,7 +2418,7 @@ Account.prototype._checkKeys = function _checkKeys(callback) { address = this.deriveReceive(0).getScriptAddress(); - this.db.getPaths(address.getHash('hex'), function(err, paths) { + this.db.getAddressPaths(address.getHash('hex'), function(err, paths) { if (err) return callback(err); diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index 45542830..26fc85b8 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -937,7 +937,7 @@ WalletDB.prototype.saveAddress = function saveAddress(wid, addresses, callback) self.emit('save address', address, path); - self.getPaths(hash, function(err, paths) { + self.getAddressPaths(hash, function(err, paths) { if (err) return next(err); @@ -964,7 +964,7 @@ WalletDB.prototype.saveAddress = function saveAddress(wid, addresses, callback) * @param {Function} callback */ -WalletDB.prototype.getPaths = function getPaths(hash, callback) { +WalletDB.prototype.getAddressPaths = function getAddressPaths(hash, callback) { var self = this; var paths; @@ -976,7 +976,9 @@ WalletDB.prototype.getPaths = function getPaths(hash, callback) { if (paths) return callback(null, paths); - this.db.fetch(layout.p(hash), parsePaths, function(err, paths) { + this.db.fetch(layout.p(hash), function(value) { + return parsePaths(value, hash); + }, function(err, paths) { if (err) return callback(err); @@ -998,7 +1000,7 @@ WalletDB.prototype.getPaths = function getPaths(hash, callback) { */ WalletDB.prototype.hasAddress = function hasAddress(wid, address, callback) { - this.getPaths(address, function(err, paths) { + this.getAddressPaths(address, function(err, paths) { if (err) return callback(err); @@ -1024,6 +1026,7 @@ WalletDB.prototype.getAddresses = function getAddresses(wid, callback) { this.db.iterate({ gte: layout.p(constants.NULL_HASH), lte: layout.p(constants.HIGH_HASH), + keys: true, values: true, parse: function(value, key) { var paths = parsePaths(value); @@ -1036,6 +1039,31 @@ WalletDB.prototype.getAddresses = function getAddresses(wid, callback) { }, callback); }; +/** + * Get all paths for a wallet. + * @param {WalletID} wid + * @param {Function} callback + */ + +WalletDB.prototype.getWalletPaths = function getWalletPaths(wid, callback) { + this.db.iterate({ + gte: layout.p(constants.NULL_HASH), + lte: layout.p(constants.HIGH_HASH), + keys: true, + values: true, + parse: function(value, key) { + var hash = layout.pp(key); + var paths = parsePaths(value, hash); + var path = paths[wid]; + + if (!path) + return; + + return path; + } + }, callback); +}; + /** * Get all wallet ids. * @param {Function} callback @@ -1162,7 +1190,7 @@ WalletDB.prototype.getTable = function getTable(addresses, callback) { var i, keys, values; utils.forEachSerial(addresses, function(address, next) { - self.getPaths(address, function(err, paths) { + self.getAddressPaths(address, function(err, paths) { if (err) return next(err); @@ -1499,8 +1527,8 @@ WalletDB.prototype.addTX = function addTX(tx, callback, force) { * @param {Function} callback */ -WalletDB.prototype.getPath = function getPath(wid, address, callback) { - this.getPaths(address, function(err, paths) { +WalletDB.prototype.getAddressPath = function getAddressPath(wid, address, callback) { + this.getAddressPaths(address, function(err, paths) { if (err) return callback(err); @@ -1535,6 +1563,7 @@ function Path() { // NOTE: Passed in by caller. this.id = null; + this.hash = null; } /** @@ -1849,7 +1878,7 @@ PathInfo.prototype.toJSON = function toJSON() { * Helpers */ -function parsePaths(data) { +function parsePaths(data, hash) { var p = new BufferReader(data); var out = {}; var path; @@ -1857,6 +1886,8 @@ function parsePaths(data) { while (p.left()) { path = Path.fromRaw(p); out[path.wid] = path; + if (hash) + path.hash = hash; } return out;