diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index c2e37055..7c4df38b 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -477,7 +477,7 @@ Wallet.prototype.createAddress = function createAddress(account, change, callbac */ Wallet.prototype.save = function save(callback) { - this.db.save(this, callback); + return this.db.save(this, callback); }; /** @@ -487,7 +487,17 @@ Wallet.prototype.save = function save(callback) { */ Wallet.prototype.hasAddress = function hasAddress(address, callback) { - this.db.hasAddress(this.id, address, callback); + return this.db.hasAddress(this.id, address, callback); +}; + +/** + * Get path by address hash. + * @param {Hash} address + * @param {Function} callback - Returns [Error, {@link Path}]. + */ + +Wallet.prototype.getPath = function getPath(address, callback) { + return this.db.getPath(this.id, address, callback); }; /** @@ -570,37 +580,6 @@ Wallet.prototype.fill = function fill(tx, options, callback) { }); }; -/** - * Fill transaction with coins (accesses db). - * @param {TX} tx - * @param {Function} callback - Returns [Error, {@link TX}]. - */ - -Wallet.prototype.fillCoins = function fillCoins(tx, callback) { - return this.db.fillHistory(this.id, tx, callback); -}; - -/** - * Get a coin from the wallet (accesses db). - * @param {Hash} hash - * @param {Number} index - * @param {Function} callback - Returns [Error, {@link Coin}]. - */ - -Wallet.prototype.getCoin = function getCoin(hash, index, callback) { - return this.db.getCoin(hash, index, callback); -}; - -/** - * Get a transaction from the wallet (accesses db). - * @param {Hash} hash - * @param {Function} callback - Returns [Error, {@link TX}]. - */ - -Wallet.prototype.getTX = function getTX(hash, callback) { - return this.db.getTX(hash, callback); -}; - /** * Build a transaction, fill it with outputs and inputs, * sort the members according to BIP69, set locktime, @@ -713,16 +692,6 @@ Wallet.prototype.deriveInputs = function deriveInputs(tx, callback) { }); }; -/** - * Get path by address hash. - * @param {Hash} address - * @param {Function} callback - Returns [Error, {@link Path}]. - */ - -Wallet.prototype.getPath = function getPath(address, callback) { - this.db.getPath(this.id, address, callback); -}; - /** * Map input addresses to paths. * @param {TX|Input} tx @@ -806,7 +775,8 @@ Wallet.prototype.getOutputPaths = function getOutputPaths(tx, callback) { Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx, callback) { var self = this; var accounts = {}; - var result = false; + var change = []; + var receive = []; var i, path, unlock; unlock = this.locker.lock(syncOutputDepth, [tx, callback]); @@ -854,29 +824,24 @@ Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx, callback) { if (!account) return next(); - account.setChangeDepth(depth.changeDepth + 1, function(err, res) { + account.setDepth(depth.receiveDepth + 1, depth.changeDepth + 1, function(err, rec, chng) { if (err) return next(err); - if (res) - result = true; + if (rec) + receive.push(rec); - account.setReceiveDepth(depth.receiveDepth + 1, function(err, res) { - if (err) - return next(err); + if (chng) + change.push(chng); - if (res) - result = true; - - next(); - }); + next(); }); }, true); }, function(err) { if (err) return callback(err); - return callback(null, result); + return callback(null, receive, change); }); }); }; @@ -920,27 +885,6 @@ Wallet.prototype.getRedeem = function getRedeem(hash, callback) { }); }; -/** - * Zap stale TXs from wallet (accesses db). - * @param {(Number|String)?} account - * @param {Number} age - Age threshold (unix time, default=72 hours). - * @param {Function} callback - Returns [Error]. - */ - -Wallet.prototype.zap = function zap(account, age, callback) { - var self = this; - - if (typeof age === 'function') { - callback = age; - age = account; - account = 0; - } - - this._getKey(account, callback, function(id, callback) { - self.db.zap(id, age, callback); - }); -}; - /** * Scan for active accounts and addresses. Used for importing a wallet. * @param {Function} getByAddress - Must be a function which accepts @@ -1061,6 +1005,37 @@ Wallet.prototype.sign = function sign(tx, options, callback) { }); }; +/** + * Fill transaction with coins (accesses db). + * @param {TX} tx + * @param {Function} callback - Returns [Error, {@link TX}]. + */ + +Wallet.prototype.fillCoins = function fillCoins(tx, callback) { + return this.db.fillHistory(tx, callback); +}; + +/** + * Get a coin from the wallet (accesses db). + * @param {Hash} hash + * @param {Number} index + * @param {Function} callback - Returns [Error, {@link Coin}]. + */ + +Wallet.prototype.getCoin = function getCoin(hash, index, callback) { + return this.db.getCoin(hash, index, callback); +}; + +/** + * Get a transaction from the wallet (accesses db). + * @param {Hash} hash + * @param {Function} callback - Returns [Error, {@link TX}]. + */ + +Wallet.prototype.getTX = function getTX(hash, callback) { + return this.db.getTX(hash, callback); +}; + /** * Add a transaction to the wallets TX history (accesses db). * @param {TX} tx @@ -1078,41 +1053,7 @@ Wallet.prototype.addTX = function addTX(tx, callback) { */ Wallet.prototype.getHistory = function getHistory(account, callback) { - var self = this; - this._getKey(account, callback, function(id, callback) { - self.db.getHistory(id, callback); - }); -}; - -/** - * Parse arguments and return an id - * consisting of `walletid/accountname`. - * @private - * @param {String|Number} account - * @param {Function} errback - * @param {Function} callback - Returns [String, Function]. - */ - -Wallet.prototype._getKey = function _getKey(account, errback, callback) { - var self = this; - - if (typeof account === 'function') { - errback = account; - account = null; - } - - if (account == null) - return callback(this.id, errback); - - this.db.getAccountIndex(this.id, account, function(err, index) { - if (err) - return errback(err); - - if (index === -1) - return errback(new Error('Account not found.')); - - return callback(self.id + '/' + index, errback); - }); + return this.db.getHistory(this.id, account, callback); }; /** @@ -1122,10 +1063,7 @@ Wallet.prototype._getKey = function _getKey(account, errback, callback) { */ Wallet.prototype.getCoins = function getCoins(account, callback) { - var self = this; - this._getKey(account, callback, function(id, callback) { - self.db.getCoins(id, callback); - }); + return this.db.getCoins(this.id, account, callback); }; /** @@ -1135,10 +1073,7 @@ Wallet.prototype.getCoins = function getCoins(account, callback) { */ Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) { - var self = this; - this._getKey(account, callback, function(id, callback) { - self.db.getUnconfirmed(id, callback); - }); + return this.db.getUnconfirmed(this.id, account, callback); }; /** @@ -1148,10 +1083,7 @@ Wallet.prototype.getUnconfirmed = function getUnconfirmed(account, callback) { */ Wallet.prototype.getBalance = function getBalance(account, callback) { - var self = this; - this._getKey(account, callback, function(id, callback) { - self.db.getBalance(id, callback); - }); + return this.db.getBalance(this.id, account, callback); }; /** @@ -1163,10 +1095,7 @@ Wallet.prototype.getBalance = function getBalance(account, callback) { */ Wallet.prototype.getLastTime = function getLastTime(account, callback) { - var self = this; - this._getKey(account, callback, function(id, callback) { - self.db.getLastTime(id, callback); - }); + return this.db.getLastTime(this.id, account, callback); }; /** @@ -1177,17 +1106,7 @@ Wallet.prototype.getLastTime = function getLastTime(account, callback) { */ Wallet.prototype.getLast = function getLast(account, limit, callback) { - var self = this; - - if (typeof limit === 'function') { - callback = limit; - limit = account; - account = null; - } - - this._getKey(account, callback, function(id, callback) { - self.db.getLast(id, callback); - }); + return this.db.getLast(this.id, account, limit, callback); }; /** @@ -1200,17 +1119,18 @@ Wallet.prototype.getLast = function getLast(account, limit, callback) { */ Wallet.prototype.getTimeRange = function getTimeRange(account, options, callback) { - var self = this; + return this.db.getTimeRange(this.id, account, options, callback); +}; - if (typeof options === 'function') { - callback = options; - options = account; - account = null; - } +/** + * Zap stale TXs from wallet (accesses db). + * @param {(Number|String)?} account + * @param {Number} age - Age threshold (unix time, default=72 hours). + * @param {Function} callback - Returns [Error]. + */ - this._getKey(account, callback, function(id, callback) { - self.db.getTimeRange(id, options, callback); - }); +Wallet.prototype.zap = function zap(account, age, callback) { + return this.db.zap(this.id, account, age, callback); }; /** @@ -2080,30 +2000,46 @@ Account.prototype.saveAddress = function saveAddress(address, callback) { }; /** - * Set receiving depth (depth is the index of the _next_ address). + * Set change and receiving depth (depth is the index of the _next_ address). * Allocate all addresses up to depth. Note that this also allocates * new lookahead addresses. * @param {Number} depth - * @returns {Boolean} True if new addresses were allocated. + * @param {Function} callback - Returns [Error, {@link KeyRing}, {@link KeyRing}]. */ -Account.prototype.setReceiveDepth = function setReceiveDepth(depth, callback) { +Account.prototype.setDepth = function setDepth(receiveDepth, changeDepth, callback) { var self = this; var addresses = []; - var i; + var i, receive, change; - if (!(depth > this.receiveDepth)) - return callback(null, false); + if (receiveDepth > this.receiveDepth) { + for (i = this.receiveDepth; i < receiveDepth; i++) { + receive = this.deriveReceive(i); + addresses.push(receive); + } - for (i = this.receiveDepth; i < depth; i++) { - this.receiveAddress = this.deriveReceive(i); - addresses.push(this.receiveAddress); + for (i = receiveDepth; i < receiveDepth + this.lookahead; i++) + addresses.push(this.deriveReceive(i)); + + this.receiveAddress = receive; + this.receiveDepth = receiveDepth; } - for (i = this.receiveDepth + this.lookahead; i < depth + this.lookahead; i++) - addresses.push(this.deriveReceive(i)); + if (changeDepth > this.changeDepth) { + for (i = this.changeDepth; i < changeDepth; i++) { + change = this.deriveChange(i); + addresses.push(this.changeAddress); + } - this.receiveDepth = depth; + for (i = changeDepth; i < changeDepth + this.lookahead; i++) + addresses.push(this.deriveChange(i)); + + this.changeAddress = change; + this.changeDepth = changeDepth; + } + + if (addresses.length === 0) + return callback(null, false); this.saveAddress(addresses, function(err) { if (err) @@ -2113,44 +2049,7 @@ Account.prototype.setReceiveDepth = function setReceiveDepth(depth, callback) { if (err) return callback(err); - return callback(null, true); - }); - }); -}; - -/** - * Set change depth (depth is the index of the _next_ address). - * Allocate all addresses up to depth. Note that this also allocates - * new lookahead addresses. - * @param {Number} depth - * @returns {Boolean} True if new addresses were allocated. - */ - -Account.prototype.setChangeDepth = function setChangeDepth(depth, callback) { - var self = this; - var addresses = []; - var i; - - if (!(depth > this.changeDepth)) - return callback(null, false); - - for (i = this.changeDepth; i < depth; i++) { - this.changeAddress = this.deriveChange(i); - addresses.push(this.changeAddress); - } - - for (i = this.changeDepth + this.lookahead; i < depth + this.lookahead; i++) - addresses.push(this.deriveChange(i)); - - this.changeDepth = depth; - - this.saveAddress(addresses, function(err) { - if (err) - return callback(err); - self.save(function(err) { - if (err) - return callback(err); - return callback(null, true); + return callback(null, receive, change); }); }); }; diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index ba95b66e..7ade880d 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -781,56 +781,112 @@ WalletDB.prototype.getCoin = function getCoin(hash, index, callback) { * @see {@link TXDB#getHistory}. */ -WalletDB.prototype.getHistory = function getHistory(id, callback) { - return this.tx.getHistory(id, callback); +WalletDB.prototype.getHistory = function getHistory(id, account, callback) { + var self = this; + this._getKey(id, account, callback, function(id, callback) { + self.tx.getHistory(id, callback); + }); }; /** * @see {@link TXDB#getCoins}. */ -WalletDB.prototype.getCoins = function getCoins(id, callback) { - return this.tx.getCoins(id, callback); +WalletDB.prototype.getCoins = function getCoins(id, account, callback) { + var self = this; + this._getKey(id, account, callback, function(id, callback) { + self.tx.getCoins(id, callback); + }); }; /** * @see {@link TXDB#getUnconfirmed}. */ -WalletDB.prototype.getUnconfirmed = function getUnconfirmed(id, callback) { - return this.tx.getUnconfirmed(id, callback); +WalletDB.prototype.getUnconfirmed = function getUnconfirmed(id, account, callback) { + var self = this; + this._getKey(id, account, callback, function(id, callback) { + self.tx.getUnconfirmed(id, callback); + }); }; /** * @see {@link TXDB#getBalance}. */ -WalletDB.prototype.getBalance = function getBalance(id, callback) { - return this.tx.getBalance(id, callback); +WalletDB.prototype.getBalance = function getBalance(id, account, callback) { + var self = this; + this._getKey(id, account, callback, function(id, callback) { + self.tx.getBalance(id, callback); + }); }; /** * @see {@link TXDB#getLastTime}. */ -WalletDB.prototype.getLastTime = function getLastTime(id, callback) { - return this.tx.getLastTime(id, callback); +WalletDB.prototype.getLastTime = function getLastTime(id, account, callback) { + var self = this; + + if (typeof options === 'function') { + callback = options; + options = account; + account = null; + } + + this._getKey(id, account, callback, function(id, callback) { + self.tx.getLastTime(id, callback); + }); }; /** * @see {@link TXDB#getLast}. */ -WalletDB.prototype.getLast = function getLast(id, limit, callback) { - return this.tx.getLast(id, limit, callback); +WalletDB.prototype.getLast = function getLast(id, account, limit, callback) { + var self = this; + + if (typeof limit === 'function') { + callback = limit; + limit = account; + account = null; + } + + this._getKey(id, account, callback, function(id, callback) { + self.tx.getLast(id, limit, callback); + }); +}; + +WalletDB.prototype.getTimeRange = function getTimeRange(id, account, limit, callback) { + var self = this; + + if (typeof limit === 'function') { + callback = limit; + limit = account; + account = null; + } + + this._getKey(id, account, callback, function(id, callback) { + self.tx.getTimeRange(id, options, callback); + }); }; /** * @see {@link TXDB#getRange}. */ -WalletDB.prototype.getRange = function getRange(id, options, callback) { - return this.tx.getRange(id, options, callback); +WalletDB.prototype.getRange = function getRange(id, account, options, callback) { + var self = this; + + if (typeof options === 'function') { + callback = options; + options = account; + account = null; + } + + this._getKey(id, account, callback, function(id, callback) { + self.tx.getRange(id, options, callback); + }); }; /** @@ -838,7 +894,7 @@ WalletDB.prototype.getRange = function getRange(id, options, callback) { */ WalletDB.prototype.fillHistory = function fillHistory(tx, callback) { - return this.tx.fillHistory(tx, callback); + this.tx.fillHistory(tx, callback); }; /** @@ -846,7 +902,7 @@ WalletDB.prototype.fillHistory = function fillHistory(tx, callback) { */ WalletDB.prototype.fillCoins = function fillCoins(tx, callback) { - return this.tx.fillCoins(tx, callback); + this.tx.fillCoins(tx, callback); }; /** @@ -854,8 +910,49 @@ WalletDB.prototype.fillCoins = function fillCoins(tx, callback) { * @see {@link TXDB#zap}. */ -WalletDB.prototype.zap = function zap(id, age, callback) { - return this.tx.zap(id, age, callback); +WalletDB.prototype.zap = function zap(id, account, age, callback) { + var self = this; + + if (typeof age === 'function') { + callback = age; + age = account; + account = null; + } + + this._getKey(id, account, callback, function(id, callback) { + self.tx.zap(id, age, callback); + }); +}; + +/** + * Parse arguments and return an id + * consisting of `walletid/accountname`. + * @private + * @param {String|Number} account + * @param {Function} errback + * @param {Function} callback - Returns [String, Function]. + */ + +WalletDB.prototype._getKey = function _getKey(id, account, errback, callback) { + var self = this; + + if (typeof account === 'function') { + errback = account; + account = null; + } + + if (account == null) + return callback(id, errback); + + this.getAccountIndex(id, account, function(err, index) { + if (err) + return errback(err); + + if (index === -1) + return errback(new Error('Account not found.')); + + return callback(id + '/' + index, errback); + }); }; /**