hd: do not store mnemonic on hd private key.
This commit is contained in:
parent
d7e2942117
commit
aa7e550f91
@ -5,8 +5,9 @@ var bench = require('./bench');
|
|||||||
var HD = require('../lib/hd');
|
var HD = require('../lib/hd');
|
||||||
var Mnemonic = require('../lib/hd/mnemonic');
|
var Mnemonic = require('../lib/hd/mnemonic');
|
||||||
|
|
||||||
var key = HD.fromMnemonic();
|
var mnemonic = new Mnemonic();
|
||||||
var phrase = key.mnemonic.getPhrase();
|
var key = HD.fromMnemonic(mnemonic);
|
||||||
|
var phrase = mnemonic.getPhrase();
|
||||||
var i, end;
|
var i, end;
|
||||||
|
|
||||||
assert.equal(Mnemonic.fromPhrase(phrase).getPhrase(), phrase);
|
assert.equal(Mnemonic.fromPhrase(phrase).getPhrase(), phrase);
|
||||||
|
|||||||
@ -27,14 +27,12 @@ var HDPublicKey = require('./public');
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @param {Object|Base58String} options
|
* @param {Object|Base58String} options
|
||||||
* @param {Base58String?} options.xkey - Serialized base58 key.
|
* @param {Base58String?} options.xkey - Serialized base58 key.
|
||||||
* @param {Mnemonic?} options.mnemonic
|
|
||||||
* @param {Number?} options.depth
|
* @param {Number?} options.depth
|
||||||
* @param {Buffer?} options.parentFingerPrint
|
* @param {Buffer?} options.parentFingerPrint
|
||||||
* @param {Number?} options.childIndex
|
* @param {Number?} options.childIndex
|
||||||
* @param {Buffer?} options.chainCode
|
* @param {Buffer?} options.chainCode
|
||||||
* @param {Buffer?} options.privateKey
|
* @param {Buffer?} options.privateKey
|
||||||
* @property {Network} network
|
* @property {Network} network
|
||||||
* @property {Mnemonic?} mnemonic
|
|
||||||
* @property {Number} depth
|
* @property {Number} depth
|
||||||
* @property {Buffer} parentFingerPrint
|
* @property {Buffer} parentFingerPrint
|
||||||
* @property {Number} childIndex
|
* @property {Number} childIndex
|
||||||
@ -56,8 +54,6 @@ function HDPrivateKey(options) {
|
|||||||
this.publicKey = encoding.ZERO_KEY;
|
this.publicKey = encoding.ZERO_KEY;
|
||||||
this.fingerPrint = null;
|
this.fingerPrint = null;
|
||||||
|
|
||||||
this.mnemonic = null;
|
|
||||||
|
|
||||||
this._xprivkey = null;
|
this._xprivkey = null;
|
||||||
|
|
||||||
this._hdPublicKey = null;
|
this._hdPublicKey = null;
|
||||||
@ -91,16 +87,6 @@ HDPrivateKey.prototype.fromOptions = function fromOptions(options) {
|
|||||||
this.privateKey = options.privateKey;
|
this.privateKey = options.privateKey;
|
||||||
this.publicKey = ec.publicKeyCreate(options.privateKey, true);
|
this.publicKey = ec.publicKeyCreate(options.privateKey, true);
|
||||||
|
|
||||||
if (options.mnemonic) {
|
|
||||||
assert(options.mnemonic instanceof Mnemonic);
|
|
||||||
this.mnemonic = options.mnemonic;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.xprivkey) {
|
|
||||||
assert(typeof options.xprivkey === 'string');
|
|
||||||
this._xprivkey = options.xprivkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -194,11 +180,6 @@ HDPrivateKey.prototype.destroy = function destroy(pub) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._xprivkey = null;
|
this._xprivkey = null;
|
||||||
|
|
||||||
if (this.mnemonic) {
|
|
||||||
this.mnemonic.destroy();
|
|
||||||
this.mnemonic = null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -543,21 +524,19 @@ HDPrivateKey.fromSeed = function fromSeed(seed, network) {
|
|||||||
/**
|
/**
|
||||||
* Inject properties from a mnemonic.
|
* Inject properties from a mnemonic.
|
||||||
* @private
|
* @private
|
||||||
* @param {Mnemonic|Object} mnemonic
|
* @param {Mnemonic} mnemonic
|
||||||
* @param {(Network|NetworkType)?} network
|
* @param {(Network|NetworkType)?} network
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HDPrivateKey.prototype.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
HDPrivateKey.prototype.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
||||||
if (!(mnemonic instanceof Mnemonic))
|
assert(mnemonic instanceof Mnemonic);
|
||||||
mnemonic = new Mnemonic(mnemonic);
|
|
||||||
this.fromSeed(mnemonic.toSeed(), network);
|
this.fromSeed(mnemonic.toSeed(), network);
|
||||||
this.mnemonic = mnemonic;
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate an hd private key from a mnemonic.
|
* Instantiate an hd private key from a mnemonic.
|
||||||
* @param {Mnemonic|Object} mnemonic
|
* @param {Mnemonic} mnemonic
|
||||||
* @param {(Network|NetworkType)?} network
|
* @param {(Network|NetworkType)?} network
|
||||||
* @returns {HDPrivateKey}
|
* @returns {HDPrivateKey}
|
||||||
*/
|
*/
|
||||||
@ -566,6 +545,30 @@ HDPrivateKey.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
|||||||
return new HDPrivateKey().fromMnemonic(mnemonic, network);
|
return new HDPrivateKey().fromMnemonic(mnemonic, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from a mnemonic.
|
||||||
|
* @private
|
||||||
|
* @param {String} mnemonic
|
||||||
|
* @param {(Network|NetworkType)?} network
|
||||||
|
*/
|
||||||
|
|
||||||
|
HDPrivateKey.prototype.fromPhrase = function fromPhrase(phrase, network) {
|
||||||
|
var mnemonic = Mnemonic.fromPhrase(phrase);
|
||||||
|
this.fromMnemonic(mnemonic, network);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate an hd private key from a phrase.
|
||||||
|
* @param {String} phrase
|
||||||
|
* @param {(Network|NetworkType)?} network
|
||||||
|
* @returns {HDPrivateKey}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HDPrivateKey.fromPhrase = function fromPhrase(phrase, network) {
|
||||||
|
return new HDPrivateKey().fromPhrase(phrase, network);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from privateKey and entropy.
|
* Inject properties from privateKey and entropy.
|
||||||
* @private
|
* @private
|
||||||
@ -722,97 +725,6 @@ HDPrivateKey.prototype.toRaw = function toRaw(network) {
|
|||||||
return this.toWriter(new StaticWriter(82), network).render();
|
return this.toWriter(new StaticWriter(82), network).render();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate extended serialization size.
|
|
||||||
* @returns {Number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.prototype.getExtendedSize = function getSize() {
|
|
||||||
var size = this.getSize();
|
|
||||||
|
|
||||||
size += 1;
|
|
||||||
|
|
||||||
if (this.mnemonic)
|
|
||||||
size += this.mnemonic.getSize();
|
|
||||||
|
|
||||||
return size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the key in "extended"
|
|
||||||
* format to a buffer writer.
|
|
||||||
* @param {BufferWriter} bw
|
|
||||||
* @param {(Network|NetworkType)?} network
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.prototype.toExtendedWriter = function toExtendedWriter(bw, network) {
|
|
||||||
this.toWriter(bw, network);
|
|
||||||
|
|
||||||
if (this.mnemonic) {
|
|
||||||
bw.writeU8(1);
|
|
||||||
this.mnemonic.toWriter(bw);
|
|
||||||
} else {
|
|
||||||
bw.writeU8(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bw;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize the key in "extended"
|
|
||||||
* format (includes the mnemonic).
|
|
||||||
* @param {(Network|NetworkType)?} network
|
|
||||||
* @returns {Buffer}
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.prototype.toExtended = function toExtended(network) {
|
|
||||||
var size = this.getExtendedSize();
|
|
||||||
return this.toExtendedWriter(new StaticWriter(size), network).render();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inject properties from buffer reader.
|
|
||||||
* @private
|
|
||||||
* @param {BufferReader} br
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.prototype.fromExtendedReader = function fromExtendedReader(br) {
|
|
||||||
this.fromReader(br);
|
|
||||||
if (br.readU8() === 1)
|
|
||||||
this.mnemonic = Mnemonic.fromReader(br);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inject properties from extended serialized data.
|
|
||||||
* @private
|
|
||||||
* @param {Buffer} data
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.prototype.fromExtended = function fromExtended(data) {
|
|
||||||
return this.fromExtendedReader(new BufferReader(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate key from "extended" buffer reader.
|
|
||||||
* @param {BufferReader} br
|
|
||||||
* @returns {HDPrivateKey}
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.fromExtendedReader = function fromExtendedReader(br) {
|
|
||||||
return new HDPrivateKey().fromExtendedReader(br);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate key from "extended" serialized data.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {HDPrivateKey}
|
|
||||||
*/
|
|
||||||
|
|
||||||
HDPrivateKey.fromExtended = function fromExtended(data) {
|
|
||||||
return new HDPrivateKey().fromExtended(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate an HD private key from a base58 string.
|
* Instantiate an HD private key from a base58 string.
|
||||||
* @param {Base58String} xkey
|
* @param {Base58String} xkey
|
||||||
@ -851,8 +763,7 @@ HDPrivateKey.fromRaw = function fromRaw(raw) {
|
|||||||
|
|
||||||
HDPrivateKey.prototype.toJSON = function toJSON() {
|
HDPrivateKey.prototype.toJSON = function toJSON() {
|
||||||
return {
|
return {
|
||||||
xprivkey: this.xprivkey(),
|
xprivkey: this.xprivkey()
|
||||||
mnemonic: this.mnemonic ? this.mnemonic.toJSON() : null
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -868,9 +779,6 @@ HDPrivateKey.prototype.fromJSON = function fromJSON(json, network) {
|
|||||||
|
|
||||||
this.fromBase58(json.xprivkey, network);
|
this.fromBase58(json.xprivkey, network);
|
||||||
|
|
||||||
if (json.mnemonic)
|
|
||||||
this.mnemonic = Mnemonic.fromJSON(json.mnemonic);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -894,7 +802,7 @@ HDPrivateKey.fromJSON = function fromJSON(json, network) {
|
|||||||
HDPrivateKey.isHDPrivateKey = function isHDPrivateKey(obj) {
|
HDPrivateKey.isHDPrivateKey = function isHDPrivateKey(obj) {
|
||||||
return obj
|
return obj
|
||||||
&& typeof obj.derive === 'function'
|
&& typeof obj.derive === 'function'
|
||||||
&& typeof obj.toExtended === 'function'
|
&& typeof obj.fromMnemonic === 'function'
|
||||||
&& obj.chainCode !== undefined;
|
&& obj.chainCode !== undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -79,11 +79,6 @@ HDPublicKey.prototype.fromOptions = function fromOptions(options) {
|
|||||||
this.chainCode = options.chainCode;
|
this.chainCode = options.chainCode;
|
||||||
this.publicKey = options.publicKey;
|
this.publicKey = options.publicKey;
|
||||||
|
|
||||||
if (options.xpubkey) {
|
|
||||||
assert(typeof options.xpubkey === 'string');
|
|
||||||
this._xpubkey = options.xpubkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ var BufferReader = require('../utils/reader');
|
|||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
var encoding = require('../utils/encoding');
|
var encoding = require('../utils/encoding');
|
||||||
var HD = require('../hd/hd');
|
var HD = require('../hd/hd');
|
||||||
|
var Mnemonic = HD.Mnemonic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Master BIP32 key which can exist
|
* Master BIP32 key which can exist
|
||||||
@ -32,6 +33,7 @@ function MasterKey(options) {
|
|||||||
this.iv = null;
|
this.iv = null;
|
||||||
this.ciphertext = null;
|
this.ciphertext = null;
|
||||||
this.key = null;
|
this.key = null;
|
||||||
|
this.mnemonic = null;
|
||||||
|
|
||||||
this.alg = MasterKey.alg.PBKDF2;
|
this.alg = MasterKey.alg.PBKDF2;
|
||||||
this.N = 50000;
|
this.N = 50000;
|
||||||
@ -103,10 +105,15 @@ MasterKey.prototype.fromOptions = function fromOptions(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.key) {
|
if (options.key) {
|
||||||
assert(HD.isHD(options.key));
|
assert(HD.isPrivate(options.key));
|
||||||
this.key = options.key;
|
this.key = options.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.mnemonic) {
|
||||||
|
assert(options.mnemonic instanceof Mnemonic);
|
||||||
|
this.mnemonic = options.mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.alg != null) {
|
if (options.alg != null) {
|
||||||
if (typeof options.alg === 'string') {
|
if (typeof options.alg === 'string') {
|
||||||
this.alg = MasterKey.alg[options.alg.toUpperCase()];
|
this.alg = MasterKey.alg[options.alg.toUpperCase()];
|
||||||
@ -195,7 +202,7 @@ MasterKey.prototype._unlock = co(function* _unlock(passphrase, timeout) {
|
|||||||
key = yield this.derive(passphrase);
|
key = yield this.derive(passphrase);
|
||||||
data = crypto.decipher(this.ciphertext, key, this.iv);
|
data = crypto.decipher(this.ciphertext, key, this.iv);
|
||||||
|
|
||||||
this.key = HD.fromExtended(data);
|
this.fromKeyRaw(data);
|
||||||
|
|
||||||
this.start(timeout);
|
this.start(timeout);
|
||||||
|
|
||||||
@ -382,7 +389,7 @@ MasterKey.prototype._decrypt = co(function* decrypt(passphrase, clean) {
|
|||||||
key = yield this.derive(passphrase);
|
key = yield this.derive(passphrase);
|
||||||
data = crypto.decipher(this.ciphertext, key, this.iv);
|
data = crypto.decipher(this.ciphertext, key, this.iv);
|
||||||
|
|
||||||
this.key = HD.fromExtended(data);
|
this.fromKeyRaw(data);
|
||||||
this.encrypted = false;
|
this.encrypted = false;
|
||||||
this.iv = null;
|
this.iv = null;
|
||||||
this.ciphertext = null;
|
this.ciphertext = null;
|
||||||
@ -426,7 +433,7 @@ MasterKey.prototype._encrypt = co(function* encrypt(passphrase, clean) {
|
|||||||
if (!passphrase)
|
if (!passphrase)
|
||||||
throw new Error('No passphrase provided.');
|
throw new Error('No passphrase provided.');
|
||||||
|
|
||||||
data = this.key.toExtended();
|
data = this.toKeyRaw();
|
||||||
iv = crypto.randomBytes(16);
|
iv = crypto.randomBytes(16);
|
||||||
|
|
||||||
this.stop();
|
this.stop();
|
||||||
@ -435,6 +442,7 @@ MasterKey.prototype._encrypt = co(function* encrypt(passphrase, clean) {
|
|||||||
data = crypto.encipher(data, key, iv);
|
data = crypto.encipher(data, key, iv);
|
||||||
|
|
||||||
this.key = null;
|
this.key = null;
|
||||||
|
this.mnemonic = null;
|
||||||
this.encrypted = true;
|
this.encrypted = true;
|
||||||
this.iv = iv;
|
this.iv = iv;
|
||||||
this.ciphertext = data;
|
this.ciphertext = data;
|
||||||
@ -447,6 +455,59 @@ MasterKey.prototype._encrypt = co(function* encrypt(passphrase, clean) {
|
|||||||
return key;
|
return key;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate key serialization size.
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MasterKey.prototype.getKeySize = function getKeySize() {
|
||||||
|
var size = 0;
|
||||||
|
|
||||||
|
size += this.key.getSize();
|
||||||
|
size += 1;
|
||||||
|
|
||||||
|
if (this.mnemonic)
|
||||||
|
size += this.mnemonic.getSize();
|
||||||
|
|
||||||
|
return size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize key and menmonic to a single buffer.
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MasterKey.prototype.toKeyRaw = function toKeyRaw() {
|
||||||
|
var bw = new StaticWriter(this.getKeySize());
|
||||||
|
|
||||||
|
this.key.toWriter(bw);
|
||||||
|
|
||||||
|
if (this.mnemonic) {
|
||||||
|
bw.writeU8(1);
|
||||||
|
this.mnemonic.toWriter(bw);
|
||||||
|
} else {
|
||||||
|
bw.writeU8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bw.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from serialized key.
|
||||||
|
* @param {Buffer} data
|
||||||
|
*/
|
||||||
|
|
||||||
|
MasterKey.prototype.fromKeyRaw = function fromKeyRaw(data) {
|
||||||
|
var br = new BufferReader(data);
|
||||||
|
|
||||||
|
this.key = HD.fromReader(br);
|
||||||
|
|
||||||
|
if (br.readU8() === 1)
|
||||||
|
this.mnemonic = Mnemonic.fromReader(br);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate serialization size.
|
* Calculate serialization size.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
@ -464,7 +525,7 @@ MasterKey.prototype.getSize = function getSize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size += 1;
|
size += 1;
|
||||||
size += encoding.sizeVarlen(this.key.getExtendedSize());
|
size += encoding.sizeVarlen(this.getKeySize());
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
};
|
};
|
||||||
@ -493,7 +554,19 @@ MasterKey.prototype.toRaw = function toRaw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bw.writeU8(0);
|
bw.writeU8(0);
|
||||||
bw.writeVarBytes(this.key.toExtended());
|
|
||||||
|
// NOTE: useless varint
|
||||||
|
size = this.getKeySize();
|
||||||
|
bw.writeVarint(size);
|
||||||
|
|
||||||
|
bw.writeBytes(this.key.toRaw());
|
||||||
|
|
||||||
|
if (this.mnemonic) {
|
||||||
|
bw.writeU8(1);
|
||||||
|
this.mnemonic.toWriter(bw);
|
||||||
|
} else {
|
||||||
|
bw.writeU8(0);
|
||||||
|
}
|
||||||
|
|
||||||
return bw.render();
|
return bw.render();
|
||||||
};
|
};
|
||||||
@ -524,7 +597,13 @@ MasterKey.prototype.fromRaw = function fromRaw(raw) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.key = HD.fromExtended(br.readVarBytes());
|
// NOTE: useless varint
|
||||||
|
br.skipVarint();
|
||||||
|
|
||||||
|
this.key = HD.fromRaw(br.readBytes(82));
|
||||||
|
|
||||||
|
if (br.readU8() === 1)
|
||||||
|
this.mnemonic = Mnemonic.fromReader(br);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -542,24 +621,27 @@ MasterKey.fromRaw = function fromRaw(raw) {
|
|||||||
* Inject properties from an HDPrivateKey.
|
* Inject properties from an HDPrivateKey.
|
||||||
* @private
|
* @private
|
||||||
* @param {HDPrivateKey} key
|
* @param {HDPrivateKey} key
|
||||||
|
* @param {Mnemonic?} mnemonic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MasterKey.prototype.fromKey = function fromKey(key) {
|
MasterKey.prototype.fromKey = function fromKey(key, mnemonic) {
|
||||||
this.encrypted = false;
|
this.encrypted = false;
|
||||||
this.iv = null;
|
this.iv = null;
|
||||||
this.ciphertext = null;
|
this.ciphertext = null;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
this.mnemonic = mnemonic || null;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate master key from an HDPrivateKey.
|
* Instantiate master key from an HDPrivateKey.
|
||||||
* @param {HDPrivateKey} key
|
* @param {HDPrivateKey} key
|
||||||
|
* @param {Mnemonic?} mnemonic
|
||||||
* @returns {MasterKey}
|
* @returns {MasterKey}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MasterKey.fromKey = function fromKey(key) {
|
MasterKey.fromKey = function fromKey(key, mnemonic) {
|
||||||
return new MasterKey().fromKey(key);
|
return new MasterKey().fromKey(key, mnemonic);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -585,7 +667,8 @@ MasterKey.prototype.toJSON = function toJSON(unsafe) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
encrypted: false,
|
encrypted: false,
|
||||||
key: unsafe ? this.key.toJSON() : undefined
|
key: unsafe ? this.key.toJSON() : undefined,
|
||||||
|
mnemonic: unsafe && this.mnemonic ? this.mnemonic.toJSON() : undefined
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -596,8 +679,13 @@ MasterKey.prototype.toJSON = function toJSON(unsafe) {
|
|||||||
|
|
||||||
MasterKey.prototype.inspect = function inspect() {
|
MasterKey.prototype.inspect = function inspect() {
|
||||||
var json = this.toJSON(true);
|
var json = this.toJSON(true);
|
||||||
|
|
||||||
if (this.key)
|
if (this.key)
|
||||||
json.key = this.key.toJSON();
|
json.key = this.key.toJSON();
|
||||||
|
|
||||||
|
if (this.mnemonic)
|
||||||
|
json.mnemonic = this.mnemonic.toJSON();
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ var MasterKey = require('./masterkey');
|
|||||||
var LRU = require('../utils/lru');
|
var LRU = require('../utils/lru');
|
||||||
var policy = require('../protocol/policy');
|
var policy = require('../protocol/policy');
|
||||||
var consensus = require('../protocol/consensus');
|
var consensus = require('../protocol/consensus');
|
||||||
|
var Mnemonic = HD.Mnemonic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BIP44 Wallet
|
* BIP44 Wallet
|
||||||
@ -102,26 +103,24 @@ util.inherits(Wallet, EventEmitter);
|
|||||||
|
|
||||||
Wallet.prototype.fromOptions = function fromOptions(options) {
|
Wallet.prototype.fromOptions = function fromOptions(options) {
|
||||||
var key = options.master;
|
var key = options.master;
|
||||||
var id, token;
|
var id, token, mnemonic;
|
||||||
|
|
||||||
if (MasterKey.isMasterKey(key)) {
|
if (key) {
|
||||||
this.master.fromOptions(key);
|
if (typeof key === 'string')
|
||||||
} else {
|
|
||||||
if (!key)
|
|
||||||
key = HD.fromMnemonic(null, this.network);
|
|
||||||
|
|
||||||
if (HD.isBase58(key))
|
|
||||||
key = HD.fromBase58(key, this.network);
|
key = HD.fromBase58(key, this.network);
|
||||||
|
|
||||||
assert(HD.isPrivate(key),
|
assert(HD.isPrivate(key),
|
||||||
'Must create wallet with hd private key.');
|
'Must create wallet with hd private key.');
|
||||||
|
} else {
|
||||||
assert(key.verifyNetwork(this.network),
|
mnemonic = new Mnemonic(options.mnemonic);
|
||||||
'Network mismatch for master key.');
|
key = HD.fromMnemonic(mnemonic, this.network);
|
||||||
|
|
||||||
this.master.fromKey(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(key.verifyNetwork(this.network),
|
||||||
|
'Network mismatch for master key.');
|
||||||
|
|
||||||
|
this.master.fromKey(key, mnemonic);
|
||||||
|
|
||||||
if (options.wid != null) {
|
if (options.wid != null) {
|
||||||
assert(util.isNumber(options.wid));
|
assert(util.isNumber(options.wid));
|
||||||
this.wid = options.wid;
|
this.wid = options.wid;
|
||||||
|
|||||||
@ -87,7 +87,7 @@ describe('HD', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should deserialize and reserialize', function() {
|
it('should deserialize and reserialize', function() {
|
||||||
var key = HD.fromMnemonic();
|
var key = HD.generate();
|
||||||
assert.equal(HD.fromJSON(key.toJSON()).toBase58(), key.toBase58());
|
assert.equal(HD.fromJSON(key.toJSON()).toBase58(), key.toBase58());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,7 @@ MemWallet.prototype.init = function init() {
|
|||||||
var i;
|
var i;
|
||||||
|
|
||||||
if (!this.master)
|
if (!this.master)
|
||||||
this.master = HD.PrivateKey.fromMnemonic(null, this.network);
|
this.master = HD.PrivateKey.generate();
|
||||||
|
|
||||||
if (!this.key)
|
if (!this.key)
|
||||||
this.key = this.master.deriveAccount44(this.account);
|
this.key = this.master.deriveAccount44(this.account);
|
||||||
|
|||||||
@ -154,7 +154,7 @@ describe('Wallet', function() {
|
|||||||
n: 2
|
n: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
k = HD.fromMnemonic().deriveAccount44(0).toPublic();
|
k = HD.generate().deriveAccount44(0).toPublic();
|
||||||
|
|
||||||
yield w.addSharedKey(k);
|
yield w.addSharedKey(k);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user