diff --git a/lib/bcoin/txdb.js b/lib/bcoin/txdb.js index 43b688de..4cadaaa4 100644 --- a/lib/bcoin/txdb.js +++ b/lib/bcoin/txdb.js @@ -198,46 +198,32 @@ TXDB.prototype.getMap = function getMap(tx, callback) { TXDB.prototype.mapAddresses = function mapAddresses(address, callback) { var self = this; var table = { count: 0 }; - var values = []; - var i, keys; + var i, keys, values; - if (Array.isArray(address)) { - return utils.forEachSerial(address, function(address, next) { - self.mapAddresses(address, function(err, res) { - if (err) - return next(err); - - assert(res[address]); - table[address] = res[address]; - table.count += res.count; - - next(); - }); - }, function(err) { + return utils.forEachSerial(address, function(address, next) { + self.wdb.getAddress(address, function(err, paths) { if (err) - return callback(err); + return next(err); - return callback(null, table); + if (!paths) + return next(); + + keys = Object.keys(paths); + values = []; + + for (i = 0; i < keys.length; i++) + values.push(paths[keys[i]]); + + assert(!table[address]); + table[address] = values; + table.count += values.length; + + return next(); }); - } - - this.wdb.getAddress(address, function(err, paths) { + }, function(err) { if (err) return callback(err); - if (!paths) { - table[address] = []; - return callback(null, table); - } - - keys = Object.keys(paths); - - for (i = 0; i < keys.length; i++) - values.push(paths[keys[i]]); - - table[address] = values; - table.count += values.length; - return callback(null, table); }); }; diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index aa03b603..59fa4c81 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -28,8 +28,6 @@ var BufferWriter = require('./writer'); * address. * @param {Number?} options.changeDepth - The index of the _next_ change * address. - * @param {Number?} options.lookahead - Amount of lookahead addresses - * (default=5). * @param {String?} options.type - Type of wallet (pubkeyhash, multisig) * (default=pubkeyhash). * @param {Boolean?} options.compressed - Whether to use compressed @@ -41,7 +39,7 @@ var BufferWriter = require('./writer'); */ function Wallet(options) { - var i, key; + var master; if (!(this instanceof Wallet)) return new Wallet(options); @@ -51,35 +49,41 @@ function Wallet(options) { if (!options) options = {}; - options = utils.merge({}, options); + master = options.master; this.options = options; this.network = bcoin.network.get(options.network); this.db = options.db; - if (!this.db) - this.db = new bcoin.walletdb({ name: 'wtmp', db: 'memory' }); + if (!master) + master = bcoin.hd.fromMnemonic(null, this.network); - if (!options.master) - options.master = bcoin.hd.fromMnemonic(null, this.network); + if (!bcoin.hd.isHD(master) && !MasterKey.isMasterKey(master)) + master = bcoin.hd.fromAny(master, this.network); - if (!bcoin.hd.isHD(options.master) && !MasterKey.isMasterKey(options.master)) - options.master = bcoin.hd.fromAny(options.master, this.network); - - if (!MasterKey.isMasterKey(options.master)) - options.master = MasterKey.fromKey(options.master); + if (!MasterKey.isMasterKey(master)) + master = MasterKey.fromKey(master); this.id = options.id || null; - this.master = options.master || null; + this.master = master; + this.initialized = options.initialized || false; this.accountDepth = options.accountDepth || 0; + this.loaded = false; this.loading = false; this.account = null; - this.initialized = options.initialized || false; if (!this.id) this.id = this.getID(); + if (!this.db) { + this.db = new bcoin.walletdb({ + network: this.network, + name: this.id, + db: 'memory' + }); + } + // Non-alphanumeric IDs will break leveldb sorting. assert(/^[a-zA-Z0-9]+$/.test(this.id), 'Wallet IDs must be alphanumeric.'); } @@ -131,26 +135,6 @@ Wallet.prototype.open = function open(callback) { * @param {Function} callback */ -Wallet.prototype.__defineGetter__('receiveDepth', function() { - return this.account.receiveDepth; -}); - -Wallet.prototype.__defineGetter__('changeDepth', function() { - return this.account.changeDepth; -}); - -Wallet.prototype.__defineGetter__('accountKey', function() { - return this.account.accountKey; -}); - -Wallet.prototype.__defineGetter__('receiveAddress', function() { - return this.account.receiveAddress; -}); - -Wallet.prototype.__defineGetter__('changeAddress', function() { - return this.account.changeAddress; -}); - Wallet.prototype.close = Wallet.prototype.destroy = function destroy(callback) { callback = utils.ensure(callback); @@ -182,7 +166,7 @@ Wallet.prototype.destroy = function destroy(callback) { Wallet.prototype.init = function init(callback) { var self = this; - var options; + var options = this.options; function done(err, account) { if (err) @@ -193,13 +177,13 @@ Wallet.prototype.init = function init(callback) { self.account = account; - if (self.options.passphrase) - self.master.encrypt(self.options.passphrase); + if (options.passphrase) + self.master.encrypt(options.passphrase); - if (Buffer.isBuffer(self.options.passphrase)) - self.options.passphrase.fill(0); + if (Buffer.isBuffer(options.passphrase)) + options.passphrase.fill(0); - self.options.passphrase = null; + options.passphrase = null; return callback(); } @@ -213,9 +197,6 @@ Wallet.prototype.init = function init(callback) { self.initialized = true; - options = utils.merge({}, self.options); - options.name = 'default'; - self.createAccount(options, done); }); }; @@ -311,12 +292,18 @@ Wallet.prototype.createAccount = function createAccount(options, callback) { key = master.deriveAccount44(this.accountDepth); - options = utils.merge({}, options, { + options = { + network: this.network, wid: this.id, - accountIndex: this.accountDepth, + name: this.accountDepth === 0 ? 'default' : options.name, + witness: options.witness, accountKey: key.hdPublicKey, - initialized: false - }); + accountIndex: this.accountDepth, + type: options.type, + keys: options.keys, + m: options.m, + n: options.n + }; this.db.createAccount(options, function(err, account) { if (err) @@ -1308,6 +1295,26 @@ Wallet.prototype.__defineGetter__('address', function() { return this.getAddress(); }); +Wallet.prototype.__defineGetter__('receiveDepth', function() { + return this.account.receiveDepth; +}); + +Wallet.prototype.__defineGetter__('changeDepth', function() { + return this.account.changeDepth; +}); + +Wallet.prototype.__defineGetter__('accountKey', function() { + return this.account.accountKey; +}); + +Wallet.prototype.__defineGetter__('receiveAddress', function() { + return this.account.receiveAddress; +}); + +Wallet.prototype.__defineGetter__('changeAddress', function() { + return this.account.changeAddress; +}); + /** * Convert the wallet to a more inspection-friendly object. * @returns {Object} @@ -1456,8 +1463,6 @@ Wallet.isWallet = function isWallet(obj) { * address. * @param {Number?} options.changeDepth - The index of the _next_ change * address. - * @param {Number?} options.lookahead - Amount of lookahead addresses - * (default=5). * @param {String?} options.type - Type of wallet (pubkeyhash, multisig) * (default=pubkeyhash). * @param {Number?} options.m - `m` value for multisig. @@ -1474,35 +1479,33 @@ function Account(options) { EventEmitter.call(this); - if (!options) - options = {}; - - options = utils.merge({}, options); + assert(options, 'Options are required.'); + assert(options.db, 'Database is required.'); + assert(options.wid, 'Wallet ID is required.'); + assert(options.accountKey, 'Account key is required.'); this.options = options; this.network = bcoin.network.get(options.network); this.db = options.db; + this.lookahead = options.lookahead != null ? options.lookahead : 5; - this.wid = options.wid || null; - this.name = options.name || null; + this.wid = options.wid; + this.name = options.name; this.witness = options.witness || false; - this.loaded = false; - this.loading = false; - - this.accountKey = options.accountKey || null; + this.accountKey = options.accountKey; this.accountIndex = options.accountIndex || 0; this.receiveDepth = options.receiveDepth || 1; this.changeDepth = options.changeDepth || 1; - this.receiveAddress = null; - this.changeAddress = null; - - this.lookahead = options.lookahead != null ? options.lookahead : 5; - this.initialized = options.initialized || false; - this.type = options.type || 'pubkeyhash'; this.keys = []; this.m = options.m || 1; this.n = options.n || 1; + this.initialized = options.initialized || false; + + this.loaded = false; + this.loading = false; + this.receiveAddress = null; + this.changeAddress = null; this.cache = new bcoin.lru(20, 1); @@ -1549,13 +1552,6 @@ Account.prototype.open = function open(callback) { this.loading = true; - try { - //this.db.register(this); - } catch (e) { - this.emit('error', err); - return callback(err); - } - this.init(function(err) { if (err) { self.emit('error', err); @@ -1585,13 +1581,6 @@ Account.prototype.destroy = function destroy(callback) { assert(!this.loading); - try { - //this.db.unregister(this); - } catch (e) { - this.emit('error', err); - return callback(err); - } - this.loaded = false; return utils.nextTick(callback); diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index b9783429..3ccf58a2 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -122,21 +122,21 @@ WalletDB.prototype._init = function _init() { this.tx.on('tx', function(tx, map) { self.emit('tx', tx, map); map.all.forEach(function(path) { - self.fire(path.id, 'tx', tx); + self.fire(path.id, 'tx', tx, path.name); }); }); this.tx.on('confirmed', function(tx, map) { self.emit('confirmed', tx, map); map.all.forEach(function(path) { - self.fire(path.id, 'confirmed', tx); + self.fire(path.id, 'confirmed', tx, path.name); }); }); this.tx.on('unconfirmed', function(tx, map) { self.emit('unconfirmed', tx, map); map.all.forEach(function(path) { - self.fire(path.id, 'unconfirmed', tx); + self.fire(path.id, 'unconfirmed', tx, path.name); }); }); @@ -145,7 +145,7 @@ WalletDB.prototype._init = function _init() { self.emit('updated', tx, map); map.all.forEach(function(path) { - self.fire(path.id, 'updated', tx); + self.fire(path.id, 'updated', tx, path.name); }); utils.forEachSerial(map.output, function(path, next) { @@ -154,13 +154,15 @@ WalletDB.prototype._init = function _init() { return next(); } + if (balances[path.id] != null) + return next(); + self.getBalance(path.id, function(err, balance) { if (err) return next(err); balances[path.id] = balance; - self.emit('balance', balance, path.id); self.fire(path.id, 'balance', balance); next();