diff --git a/lib/bcoin/hd.js b/lib/bcoin/hd.js index 4225356d..eb92fdd6 100644 --- a/lib/bcoin/hd.js +++ b/lib/bcoin/hd.js @@ -563,6 +563,44 @@ HDPub.prototype.deriveString = function(path) { }); }; +/** + * Make HD keys behave like elliptic KeyPairs + */ + +[HDPriv, HDPub].forEach(function(HD) { + HD.prototype.validate = function validate() { + return this.pair.validate.apply(this.pair, arguments); + }; + + HD.prototype.getPublic = function getPublic() { + return this.pair.getPublic.apply(this.pair, arguments); + }; + + HD.prototype.getPrivate = function getPrivate() { + return this.pair.getPublic.apply(this.pair, arguments); + }; + + HD.prototype.sign = function sign(msg) { + return this.pair.sign.apply(this.pair, arguments); + }; + + HD.prototype.verify = function verify(msg, signature) { + return this.pair.verify.apply(this.pair, arguments); + }; + + HD.prototype.inspect = function inspect() { + return this.pair.inspect.apply(this.pair, arguments); + }; + + HD.prototype.__defineGetter__('pub', function() { + return this.pair.pub; + }); + + HD.prototype.__defineGetter__('priv', function() { + return this.pair.priv; + }); +}); + /** * Helpers */ diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index b6c4743f..7274944b 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -135,7 +135,7 @@ TX.prototype.signature = function(input, key, type) { var hash = this.subscriptHash(tx.inputs.indexOf(input), s, type); // Sign the transaction with our one input - var signature = bcoin.ecdsa.sign(hash, key).toDER(); + var signature = bcoin.ecdsa.sign(hash, key.priv).toDER(); // Add the sighash as a single byte to the signature signature = signature.concat(type); @@ -204,7 +204,7 @@ TX.prototype.signInput = function(input, key, type) { var hash = this.subscriptHash(this.inputs.indexOf(input), s, type); // Sign the transaction with our one input - var signature = bcoin.ecdsa.sign(hash, key).toDER(); + var signature = bcoin.ecdsa.sign(hash, key.priv).toDER(); // Add the sighash as a single byte to the signature signature = signature.concat(type); diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 8c4b9748..2c6606c6 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -23,25 +23,31 @@ function Wallet(options, passphrase) { if (!options) options = {}; + this.options = options; this.compressed = typeof options.compressed !== 'undefined' ? options.compressed : true; this.storage = options.storage; this.key = null; this.loaded = false; this.lastTs = 0; - this.sharedKeys = options.sharedKeys; if (options.priv instanceof bcoin.hd.priv) { this.hd = options.priv; - this.key = this.hd.pair; + this.key = this.hd; } else if (options.pub instanceof bcoin.hd.pub) { this.hd = options.pub; - this.key = this.hd.pair; + this.key = this.hd; } else if (options.hd) { this.hd = bcoin.hd.priv(options); - this.key = this.hd.pair; + this.key = this.hd; } else if (options.key) { - this.key = options.key; + if ((options.key instanceof bcoin.hd.priv) + || (options.key instanceof bcoin.hd.pub)) { + this.hd = options.key; + this.key = options.key; + } else { + this.key = options.key; + } } else if (options.passphrase) { this.key = bcoin.ecdsa.genKeyPair({ pers: options.scope, @@ -107,7 +113,7 @@ Wallet.prototype._init = function init() { }); }; -Wallet.prototype.multisig = function(options) { +Wallet.prototype.multisig = function multisig(options) { var pub = this.key.getPublic(this.compressed, 'array'); options.type = options.type || options.addressType; @@ -142,6 +148,17 @@ Wallet.prototype.multisig = function(options) { } }; +Wallet.prototype.derive = function derive() { + var options = this.options; + + if (!this.hd) + throw new Error('wallet is not HD'); + + options.priv = this.hd.derive.apply(this.hd, arguments); + + return bcoin.wallet(options); +}; + Wallet.prototype.getPrivateKey = function getPrivateKey(enc) { var priv = this.key.getPrivate(); if (priv) @@ -184,6 +201,17 @@ Wallet.prototype.getPublicKey = function getPublicKey(enc) { return pub; }; +Wallet.prototype._getPublicKey = function _getPublicKey(enc) { + var pub = this.key.getPublic(this.compressed, 'array'); + + if (enc === 'base58') + return utils.toBase58(pub); + else if (enc === 'hex') + return utils.toHex(pub); + else + return pub; +}; + Wallet.prototype.getPublicKeys = function() { var keys = this.sharedKeys.slice().map(utils.toKeyArray); diff --git a/test/wallet-test.js b/test/wallet-test.js index bfbbf100..1b88b002 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -254,11 +254,20 @@ describe('Wallet', function() { }); it('should verify 2-of-3 p2sh tx', function(cb) { + var hd = bcoin.hd.priv(); + var hd1 = hd.derive(0); + var hd2 = hd.derive(1); + var hd3 = hd.derive(2); + // Generate 3 key pairs var key1 = bcoin.ecdsa.genKeyPair(); var key2 = bcoin.ecdsa.genKeyPair(); var key3 = bcoin.ecdsa.genKeyPair(); + // var key1 = hd1; + // var key2 = hd2; + // var key3 = hd3; + // Grab the 3 pubkeys var pub1 = key1.getPublic(true, 'array'); var pub2 = key2.getPublic(true, 'array');