diff --git a/lib/bcoin/address.js b/lib/bcoin/address.js index aa3d0581..5f43e8e3 100644 --- a/lib/bcoin/address.js +++ b/lib/bcoin/address.js @@ -35,7 +35,7 @@ function Address(options) { this.label = options.label || ''; this.derived = !!options.derived; - this.key = bcoin.keypair(options); + this.key = options.pair || options.key || bcoin.keypair(options); this.path = options.path; this.change = !!options.change; this.index = options.index; diff --git a/lib/bcoin/hd.js b/lib/bcoin/hd.js index fe21186d..f32385d1 100644 --- a/lib/bcoin/hd.js +++ b/lib/bcoin/hd.js @@ -46,8 +46,6 @@ * THE SOFTWARE. */ -var hd = exports; - /** * Modules */ @@ -55,6 +53,7 @@ var hd = exports; var bcoin = require('../bcoin'); var hash = require('hash.js'); var bn = require('bn.js'); +var inherits = require('inherits'); var elliptic = require('elliptic'); var utils = bcoin.utils; var assert = utils.assert; @@ -104,6 +103,14 @@ HDSeed._mnemonic = function _mnemonic(entropy) { return mnemonic.join(' '); }; +/** + * Abstract + */ + +function HD(options) { + return new HDPrivateKey(options); +} + /** * HD Private Key */ @@ -114,15 +121,30 @@ function HDPrivateKey(options) { if (!(this instanceof HDPrivateKey)) return new HDPrivateKey(options); + assert(!(options instanceof HDPrivateKey)); + assert(!(options instanceof HDPublicKey)); + + if (options instanceof bcoin.hd.seed) + options = { seed: options }; + + if (options) { + if (options.xprivkey) + options.xkey = options.xprivkey; + if (options.xpubkey) + options.xkey = options.xpubkey; + } + + if (options) { + if (HDPublicKey.isExtended(options) || HDPublicKey.isExtended(options.xkey)) + return new HDPublicKey(options); + } + if (!options) options = { seed: bcoin.hd.seed() }; if (HDPrivateKey.isExtended(options)) options = { xkey: options }; - if (HDPublicKey.isExtended(options)) - return new HDPublicKey(options); - if (options.passphrase !== undefined || options.bits || options.entropy @@ -161,6 +183,8 @@ function HDPrivateKey(options) { this.isPublic = false; } +inherits(HDPrivateKey, HD); + HDPrivateKey.prototype.scan44 = function scan44(options, txByAddress, callback) { var self = this; var accounts = []; @@ -837,9 +861,20 @@ function HDPublicKey(options) { if (!options) throw new Error('No options for HDPublicKey'); + assert(!(options instanceof HDPrivateKey)); + assert(!(options instanceof HDPublicKey)); + + assert(!options.xprivkey); + + if (options.xpubkey) + options.xkey = options.xpubkey; + if (HDPublicKey.isExtended(options)) options = { xkey: options }; + if (HDPrivateKey.isExtended(options) || HDPrivateKey.isExtended(options.xkey)) + throw new Error('Cannot pass xprivkey into HDPublicKey'); + data = options.xkey ? this._unbuild(options.xkey) : options; @@ -859,6 +894,8 @@ function HDPublicKey(options) { this.isPublic = true; } +inherits(HDPublicKey, HD); + HDPublicKey.prototype.scan44 = HDPrivateKey.prototype.scan44; HDPublicKey.prototype.deriveAccount44 = HDPrivateKey.prototype.deriveAccount44; HDPublicKey.prototype.deriveBIP44 = HDPrivateKey.prototype.deriveBIP44; @@ -1174,10 +1211,14 @@ cache.get = function(key, index) { * Expose */ -hd.seed = HDSeed; -hd.priv = HDPrivateKey; -hd.pub = HDPublicKey; -hd.privateKey = HDPrivateKey; -hd.publicKey = HDPublicKey; -hd.pbkdf2 = pbkdf2; -hd.fromJSON = HDPrivateKey.fromJSON; +exports = HD; + +exports.seed = HDSeed; +exports.priv = HDPrivateKey; +exports.pub = HDPublicKey; +exports.privateKey = HDPrivateKey; +exports.publicKey = HDPublicKey; +exports.pbkdf2 = pbkdf2; +exports.fromJSON = HDPrivateKey.fromJSON; + +module.exports = HD; diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 07c356fa..aa94120a 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -31,39 +31,17 @@ function Wallet(options) { options = utils.merge({}, options); - if (!options.master) { - options.master = options.hd - ? bcoin.hd.privateKey(options.hd) - : bcoin.hd.privateKey(); - delete options.hd; + if (typeof options.master === 'string') + options.master = { xkey: options.master }; + + if (options.master + && typeof options.master === 'object' + && !(options.master instanceof bcoin.hd)) { + options.master = bcoin.hd(options.master); } - if (options.key) { - options.pair = options.key; - delete options.key; - } - - if (options.priv) { - options.privateKey = options.priv; - delete options.priv; - } - - if (options.pub) { - options.publicKey = options.pub; - delete options.pub; - } - - if ((options.pair instanceof bcoin.hd.privateKey) - || (options.pair instanceof bcoin.hd.publicKey)) { - options.master = options.pair; - delete options.pair; - } else if (options.privateKey instanceof bcoin.hd.privateKey) { - options.master = options.privateKey; - delete options.privateKey; - } else if (options.publicKey instanceof bcoin.hd.publicKey) { - options.master = options.publicKey; - delete options.publicKey; - } + if (!options.master) + options.master = bcoin.hd.privateKey(); this.options = options; this.addresses = []; @@ -81,7 +59,7 @@ function Wallet(options) { this.cosignerIndex = -1; this.type = options.type || 'pubkeyhash'; - this.derivation = options.derivation || null; + this.derivation = options.derivation || 'bip44'; this.compressed = options.compressed !== false; this.keys = []; this.m = options.m || 1; @@ -93,13 +71,6 @@ function Wallet(options) { assert(this.type === 'pubkeyhash' || this.type === 'multisig'); this.prefixType = this.type === 'multisig' ? 'scripthash' : 'pubkeyhash'; - if (!this.derivation) { - if (this.type === 'multisig') - this.derivation = 'bip45'; - else - this.derivation = 'bip44'; - } - if (network.prefixes[this.prefixType] == null) throw new Error('Unknown prefix: ' + this.prefixType); @@ -778,7 +749,6 @@ Wallet.prototype.__defineGetter__('address', function() { }); Wallet.prototype.toJSON = function toJSON(encrypt) { - assert(this._initialized); return { v: 3, name: 'wallet',