wallet/bcoin: stop tracking network everywhere.
This commit is contained in:
parent
40bb08aed6
commit
f3b94ded65
17
lib/hd/hd.js
17
lib/hd/hd.js
@ -37,35 +37,32 @@ HD.fromBase58 = function fromBase58(xkey, network) {
|
||||
* @param {Object} options
|
||||
* @param {Buffer?} options.privateKey
|
||||
* @param {Buffer?} options.entropy
|
||||
* @param {String?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HD.generate = function generate(network) {
|
||||
return HDPrivateKey.generate(network);
|
||||
HD.generate = function generate() {
|
||||
return HDPrivateKey.generate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate an {@link HDPrivateKey} from a seed.
|
||||
* @param {Object|Mnemonic|Buffer} options - seed,
|
||||
* mnemonic, mnemonic options.
|
||||
* @param {String?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HD.fromSeed = function fromSeed(options, network) {
|
||||
return HDPrivateKey.fromSeed(options, network);
|
||||
HD.fromSeed = function fromSeed(options) {
|
||||
return HDPrivateKey.fromSeed(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an hd private key from a mnemonic.
|
||||
* @param {Mnemonic|Object} mnemonic
|
||||
* @param {String?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HD.fromMnemonic = function fromMnemonic(options, network) {
|
||||
return HDPrivateKey.fromMnemonic(options, network);
|
||||
HD.fromMnemonic = function fromMnemonic(options) {
|
||||
return HDPrivateKey.fromMnemonic(options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -115,7 +112,7 @@ HD.from = function from(options, network) {
|
||||
return HD.fromRaw(options, network);
|
||||
|
||||
if (options && typeof options === 'object')
|
||||
return HD.fromMnemonic(options, network);
|
||||
return HD.fromMnemonic(options);
|
||||
|
||||
throw new Error('Cannot create HD key from bad options.');
|
||||
};
|
||||
|
||||
@ -38,7 +38,6 @@ const SEED_SALT = Buffer.from('Bitcoin seed', 'ascii');
|
||||
* @param {Number?} options.childIndex
|
||||
* @param {Buffer?} options.chainCode
|
||||
* @param {Buffer?} options.privateKey
|
||||
* @property {Network} network
|
||||
* @property {Number} depth
|
||||
* @property {Number} parentFingerPrint
|
||||
* @property {Number} childIndex
|
||||
@ -50,7 +49,6 @@ function HDPrivateKey(options) {
|
||||
if (!(this instanceof HDPrivateKey))
|
||||
return new HDPrivateKey(options);
|
||||
|
||||
this.network = Network.primary;
|
||||
this.depth = 0;
|
||||
this.parentFingerPrint = 0;
|
||||
this.childIndex = 0;
|
||||
@ -60,8 +58,6 @@ function HDPrivateKey(options) {
|
||||
this.publicKey = encoding.ZERO_KEY;
|
||||
this.fingerPrint = -1;
|
||||
|
||||
this._xprivkey = null;
|
||||
|
||||
this._hdPublicKey = null;
|
||||
|
||||
if (options)
|
||||
@ -82,9 +78,6 @@ HDPrivateKey.prototype.fromOptions = function fromOptions(options) {
|
||||
assert(Buffer.isBuffer(options.chainCode));
|
||||
assert(Buffer.isBuffer(options.privateKey));
|
||||
|
||||
if (options.network)
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
this.depth = options.depth;
|
||||
this.parentFingerPrint = options.parentFingerPrint;
|
||||
this.childIndex = options.childIndex;
|
||||
@ -115,7 +108,6 @@ HDPrivateKey.prototype.toPublic = function toPublic() {
|
||||
|
||||
if (!key) {
|
||||
key = new HDPublicKey();
|
||||
key.network = this.network;
|
||||
key.depth = this.depth;
|
||||
key.parentFingerPrint = this.parentFingerPrint;
|
||||
key.childIndex = this.childIndex;
|
||||
@ -132,10 +124,8 @@ HDPrivateKey.prototype.toPublic = function toPublic() {
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.xprivkey = function xprivkey() {
|
||||
if (!this._xprivkey)
|
||||
this._xprivkey = this.toBase58();
|
||||
return this._xprivkey;
|
||||
HDPrivateKey.prototype.xprivkey = function xprivkey(network) {
|
||||
return this.toBase58(network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -143,8 +133,8 @@ HDPrivateKey.prototype.xprivkey = function xprivkey() {
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.xpubkey = function xpubkey() {
|
||||
return this.toPublic().xpubkey();
|
||||
HDPrivateKey.prototype.xpubkey = function xpubkey(network) {
|
||||
return this.toPublic().xpubkey(network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -168,8 +158,6 @@ HDPrivateKey.prototype.destroy = function destroy(pub) {
|
||||
this._hdPublicKey.destroy();
|
||||
this._hdPublicKey = null;
|
||||
}
|
||||
|
||||
this._xprivkey = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -229,7 +217,6 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
}
|
||||
|
||||
const child = new HDPrivateKey();
|
||||
child.network = this.network;
|
||||
child.depth = this.depth + 1;
|
||||
child.parentFingerPrint = this.fingerPrint;
|
||||
child.childIndex = index;
|
||||
@ -250,26 +237,26 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.getID = function getID(index) {
|
||||
return this.network.keyPrefix.xprivkey58
|
||||
+ this.publicKey.toString('hex')
|
||||
+ index;
|
||||
return 'v' + this.publicKey.toString('hex') + index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive a BIP44 account key.
|
||||
* @param {Number} purpose
|
||||
* @param {Number} type
|
||||
* @param {Number} account
|
||||
* @returns {HDPrivateKey}
|
||||
* @throws Error if key is not a master key.
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.deriveAccount = function deriveAccount(purpose, account) {
|
||||
HDPrivateKey.prototype.deriveAccount = function deriveAccount(purpose, type, account) {
|
||||
assert(util.isU32(purpose), 'Purpose must be a number.');
|
||||
assert(util.isU32(type), 'Account index must be a number.');
|
||||
assert(util.isU32(account), 'Account index must be a number.');
|
||||
assert(this.isMaster(), 'Cannot derive account index.');
|
||||
return this
|
||||
.derive(purpose, true)
|
||||
.derive(this.network.keyPrefix.coinType, true)
|
||||
.derive(type, true)
|
||||
.derive(account, true);
|
||||
};
|
||||
|
||||
@ -382,8 +369,7 @@ HDPrivateKey.prototype.derivePath = function derivePath(path) {
|
||||
HDPrivateKey.prototype.equals = function equals(obj) {
|
||||
assert(HDPrivateKey.isHDPrivateKey(obj));
|
||||
|
||||
return this.network === obj.network
|
||||
&& this.depth === obj.depth
|
||||
return this.depth === obj.depth
|
||||
&& this.parentFingerPrint === obj.parentFingerPrint
|
||||
&& this.childIndex === obj.childIndex
|
||||
&& this.chainCode.equals(obj.chainCode)
|
||||
@ -431,10 +417,9 @@ HDPrivateKey.prototype.compare = function compare(key) {
|
||||
* Inject properties from seed.
|
||||
* @private
|
||||
* @param {Buffer} seed
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) {
|
||||
HDPrivateKey.prototype.fromSeed = function fromSeed(seed) {
|
||||
assert(Buffer.isBuffer(seed));
|
||||
|
||||
if (seed.length * 8 < common.MIN_ENTROPY
|
||||
@ -450,7 +435,6 @@ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) {
|
||||
if (!secp256k1.privateKeyVerify(left))
|
||||
throw new Error('Master private key is invalid.');
|
||||
|
||||
this.network = Network.get(network);
|
||||
this.depth = 0;
|
||||
this.parentFingerPrint = 0;
|
||||
this.childIndex = 0;
|
||||
@ -464,59 +448,54 @@ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) {
|
||||
/**
|
||||
* Instantiate an hd private key from a 512 bit seed.
|
||||
* @param {Buffer} seed
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromSeed = function fromSeed(seed, network) {
|
||||
return new HDPrivateKey().fromSeed(seed, network);
|
||||
HDPrivateKey.fromSeed = function fromSeed(seed) {
|
||||
return new HDPrivateKey().fromSeed(seed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from a mnemonic.
|
||||
* @private
|
||||
* @param {Mnemonic} mnemonic
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
||||
HDPrivateKey.prototype.fromMnemonic = function fromMnemonic(mnemonic) {
|
||||
assert(mnemonic instanceof Mnemonic);
|
||||
return this.fromSeed(mnemonic.toSeed(), network);
|
||||
return this.fromSeed(mnemonic.toSeed());
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an hd private key from a mnemonic.
|
||||
* @param {Mnemonic} mnemonic
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
||||
return new HDPrivateKey().fromMnemonic(mnemonic, network);
|
||||
HDPrivateKey.fromMnemonic = function fromMnemonic(mnemonic) {
|
||||
return new HDPrivateKey().fromMnemonic(mnemonic);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from a mnemonic.
|
||||
* @private
|
||||
* @param {String} mnemonic
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromPhrase = function fromPhrase(phrase, network) {
|
||||
HDPrivateKey.prototype.fromPhrase = function fromPhrase(phrase) {
|
||||
const mnemonic = Mnemonic.fromPhrase(phrase);
|
||||
this.fromMnemonic(mnemonic, network);
|
||||
this.fromMnemonic(mnemonic);
|
||||
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);
|
||||
HDPrivateKey.fromPhrase = function fromPhrase(phrase) {
|
||||
return new HDPrivateKey().fromPhrase(phrase);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -524,13 +503,11 @@ HDPrivateKey.fromPhrase = function fromPhrase(phrase, network) {
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} entropy
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromKey = function fromKey(key, entropy, network) {
|
||||
HDPrivateKey.prototype.fromKey = function fromKey(key, entropy) {
|
||||
assert(Buffer.isBuffer(key) && key.length === 32);
|
||||
assert(Buffer.isBuffer(entropy) && entropy.length === 32);
|
||||
this.network = Network.get(network);
|
||||
this.depth = 0;
|
||||
this.parentFingerPrint = 0;
|
||||
this.childIndex = 0;
|
||||
@ -544,24 +521,22 @@ HDPrivateKey.prototype.fromKey = function fromKey(key, entropy, network) {
|
||||
* Create an hd private key from a key and entropy bytes.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} entropy
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromKey = function fromKey(key, entropy, network) {
|
||||
return new HDPrivateKey().fromKey(key, entropy, network);
|
||||
HDPrivateKey.fromKey = function fromKey(key, entropy) {
|
||||
return new HDPrivateKey().fromKey(key, entropy);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate an hd private key.
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.generate = function generate(network) {
|
||||
HDPrivateKey.generate = function generate() {
|
||||
const key = secp256k1.generatePrivateKey();
|
||||
const entropy = random.randomBytes(32);
|
||||
return HDPrivateKey.fromKey(key, entropy, network);
|
||||
return HDPrivateKey.fromKey(key, entropy);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -573,7 +548,6 @@ HDPrivateKey.generate = function generate(network) {
|
||||
|
||||
HDPrivateKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
assert(typeof xkey === 'string');
|
||||
this._xprivkey = xkey;
|
||||
return this.fromRaw(base58.decode(xkey), network);
|
||||
};
|
||||
|
||||
@ -587,7 +561,8 @@ HDPrivateKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
HDPrivateKey.prototype.fromReader = function fromReader(br, network) {
|
||||
const version = br.readU32BE();
|
||||
|
||||
this.network = Network.fromPrivate(version, network);
|
||||
Network.fromPrivate(version, network);
|
||||
|
||||
this.depth = br.readU8();
|
||||
this.parentFingerPrint = br.readU32BE();
|
||||
this.childIndex = br.readU32BE();
|
||||
@ -638,9 +613,6 @@ HDPrivateKey.prototype.getSize = function getSize() {
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toWriter = function toWriter(bw, network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
bw.writeU32BE(network.keyPrefix.xprivkey);
|
||||
@ -703,9 +675,9 @@ HDPrivateKey.fromRaw = function fromRaw(data, network) {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toJSON = function toJSON() {
|
||||
HDPrivateKey.prototype.toJSON = function toJSON(network) {
|
||||
return {
|
||||
xprivkey: this.xprivkey()
|
||||
xprivkey: this.xprivkey(network)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ const common = require('./common');
|
||||
* @param {Number?} options.childIndex
|
||||
* @param {Buffer?} options.chainCode
|
||||
* @param {Buffer?} options.publicKey
|
||||
* @property {Network} network
|
||||
* @property {Number} depth
|
||||
* @property {Number} parentFingerPrint
|
||||
* @property {Number} childIndex
|
||||
@ -41,7 +40,6 @@ function HDPublicKey(options) {
|
||||
if (!(this instanceof HDPublicKey))
|
||||
return new HDPublicKey(options);
|
||||
|
||||
this.network = Network.primary;
|
||||
this.depth = 0;
|
||||
this.parentFingerPrint = 0;
|
||||
this.childIndex = 0;
|
||||
@ -50,8 +48,6 @@ function HDPublicKey(options) {
|
||||
|
||||
this.fingerPrint = -1;
|
||||
|
||||
this._xpubkey = null;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
}
|
||||
@ -70,9 +66,6 @@ HDPublicKey.prototype.fromOptions = function fromOptions(options) {
|
||||
assert(Buffer.isBuffer(options.chainCode));
|
||||
assert(Buffer.isBuffer(options.publicKey));
|
||||
|
||||
if (options.network)
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
this.depth = options.depth;
|
||||
this.parentFingerPrint = options.parentFingerPrint;
|
||||
this.childIndex = options.childIndex;
|
||||
@ -106,7 +99,7 @@ HDPublicKey.prototype.toPublic = function toPublic() {
|
||||
* @returns {null}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.xprivkey = function xprivkey() {
|
||||
HDPublicKey.prototype.xprivkey = function xprivkey(network) {
|
||||
return null;
|
||||
};
|
||||
|
||||
@ -115,10 +108,8 @@ HDPublicKey.prototype.xprivkey = function xprivkey() {
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.xpubkey = function xpubkey() {
|
||||
if (!this._xpubkey)
|
||||
this._xpubkey = this.toBase58();
|
||||
return this._xpubkey;
|
||||
HDPublicKey.prototype.xpubkey = function xpubkey(network) {
|
||||
return this.toBase58(network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -134,8 +125,6 @@ HDPublicKey.prototype.destroy = function destroy() {
|
||||
cleanse(this.publicKey);
|
||||
|
||||
this.fingerPrint = -1;
|
||||
|
||||
this._xpubkey = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -189,7 +178,6 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
}
|
||||
|
||||
const child = new HDPublicKey();
|
||||
child.network = this.network;
|
||||
child.depth = this.depth + 1;
|
||||
child.parentFingerPrint = this.fingerPrint;
|
||||
child.childIndex = index;
|
||||
@ -209,22 +197,22 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.getID = function getID(index) {
|
||||
return this.network.keyPrefix.xpubkey58
|
||||
+ this.publicKey.toString('hex')
|
||||
+ index;
|
||||
return 'b' + this.publicKey.toString('hex') + index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive a BIP44 account key (does not derive, only ensures account key).
|
||||
* @method
|
||||
* @param {Number} purpose
|
||||
* @param {Number} type
|
||||
* @param {Number} account
|
||||
* @returns {HDPublicKey}
|
||||
* @throws Error if key is not already an account key.
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.deriveAccount = function deriveAccount(purpose, account) {
|
||||
HDPublicKey.prototype.deriveAccount = function deriveAccount(purpose, type, account) {
|
||||
assert(util.isU32(purpose));
|
||||
assert(util.isU32(type));
|
||||
assert(util.isU32(account));
|
||||
assert(this.isAccount(account), 'Cannot derive account index.');
|
||||
return this;
|
||||
@ -295,8 +283,7 @@ HDPublicKey.prototype.derivePath = function derivePath(path) {
|
||||
HDPublicKey.prototype.equals = function equals(obj) {
|
||||
assert(HDPublicKey.isHDPublicKey(obj));
|
||||
|
||||
return this.network === obj.network
|
||||
&& this.depth === obj.depth
|
||||
return this.depth === obj.depth
|
||||
&& this.parentFingerPrint === obj.parentFingerPrint
|
||||
&& this.childIndex === obj.childIndex
|
||||
&& this.chainCode.equals(obj.chainCode)
|
||||
@ -345,9 +332,9 @@ HDPublicKey.prototype.compare = function compare(key) {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.toJSON = function toJSON() {
|
||||
HDPublicKey.prototype.toJSON = function toJSON(network) {
|
||||
return {
|
||||
xpubkey: this.xpubkey()
|
||||
xpubkey: this.xpubkey(network)
|
||||
};
|
||||
};
|
||||
|
||||
@ -432,7 +419,6 @@ HDPublicKey.isRaw = function isRaw(data, network) {
|
||||
|
||||
HDPublicKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
assert(typeof xkey === 'string');
|
||||
this._xpubkey = xkey;
|
||||
return this.fromRaw(base58.decode(xkey), network);
|
||||
};
|
||||
|
||||
@ -446,7 +432,8 @@ HDPublicKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
HDPublicKey.prototype.fromReader = function fromReader(br, network) {
|
||||
const version = br.readU32BE();
|
||||
|
||||
this.network = Network.fromPublic(version, network);
|
||||
Network.fromPublic(version, network);
|
||||
|
||||
this.depth = br.readU8();
|
||||
this.parentFingerPrint = br.readU32BE();
|
||||
this.childIndex = br.readU32BE();
|
||||
@ -486,9 +473,6 @@ HDPublicKey.prototype.toBase58 = function toBase58(network) {
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.toWriter = function toWriter(bw, network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
bw.writeU32BE(network.keyPrefix.xpubkey);
|
||||
|
||||
@ -25,17 +25,15 @@ const bech32 = require('../utils/bech32');
|
||||
* @property {Buffer} hash
|
||||
* @property {AddressPrefix} type
|
||||
* @property {Number} version
|
||||
* @property {Network} network
|
||||
*/
|
||||
|
||||
function Address(options) {
|
||||
if (!(this instanceof Address))
|
||||
return new Address(options);
|
||||
|
||||
this.hash = encoding.ZERO_HASH160;
|
||||
this.type = Address.types.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
this.network = Network.primary;
|
||||
this.hash = encoding.ZERO_HASH160;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
@ -69,12 +67,7 @@ Address.prototype.fromOptions = function fromOptions(options) {
|
||||
if (typeof options === 'string')
|
||||
return this.fromString(options);
|
||||
|
||||
return this.fromHash(
|
||||
options.hash,
|
||||
options.type,
|
||||
options.version,
|
||||
options.network
|
||||
);
|
||||
return this.fromHash(options.hash, options.type, options.version);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -128,8 +121,7 @@ Address.prototype.isNull = function isNull() {
|
||||
Address.prototype.equals = function equals(addr) {
|
||||
assert(addr instanceof Address);
|
||||
|
||||
return this.network === addr.network
|
||||
&& this.type === addr.type
|
||||
return this.type === addr.type
|
||||
&& this.version === addr.version
|
||||
&& this.hash.equals(addr.hash);
|
||||
};
|
||||
@ -150,9 +142,6 @@ Address.prototype.getType = function getType() {
|
||||
*/
|
||||
|
||||
Address.prototype.getPrefix = function getPrefix(network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
const prefixes = network.addressPrefix;
|
||||
@ -241,9 +230,6 @@ Address.prototype.toBech32 = function toBech32(network) {
|
||||
assert(version !== -1,
|
||||
'Cannot convert non-program address to bech32.');
|
||||
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
const hrp = network.addressPrefix.bech32;
|
||||
@ -322,10 +308,6 @@ Address.prototype.inspect = function inspect() {
|
||||
|
||||
Address.prototype.fromRaw = function fromRaw(data, network) {
|
||||
const br = new BufferReader(data, true);
|
||||
|
||||
if (data.length > 40)
|
||||
throw new Error('Address is too long.');
|
||||
|
||||
const prefix = br.readU8();
|
||||
|
||||
network = Network.fromAddress(prefix, network);
|
||||
@ -333,18 +315,24 @@ Address.prototype.fromRaw = function fromRaw(data, network) {
|
||||
const type = Address.getType(prefix, network);
|
||||
|
||||
let version = -1;
|
||||
if (data.length > 25) {
|
||||
if (type === Address.types.WITNESS) {
|
||||
if (data.length > 38)
|
||||
throw new Error('Address is too long.');
|
||||
|
||||
version = br.readU8();
|
||||
|
||||
if (br.readU8() !== 0)
|
||||
throw new Error('Address version padding is non-zero.');
|
||||
} else {
|
||||
if (data.length !== 25)
|
||||
throw new Error('Address is too long.');
|
||||
}
|
||||
|
||||
const hash = br.readBytes(br.left() - 4);
|
||||
|
||||
br.verifyChecksum();
|
||||
|
||||
return this.fromHash(hash, type, version, network);
|
||||
return this.fromHash(hash, type, version);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -402,9 +390,9 @@ Address.prototype.fromBech32 = function fromBech32(data, network) {
|
||||
|
||||
const addr = bech32.decode(data);
|
||||
|
||||
network = Network.fromBech32(addr.hrp, network);
|
||||
Network.fromBech32(addr.hrp, network);
|
||||
|
||||
return this.fromHash(addr.hash, type, addr.version, network);
|
||||
return this.fromHash(addr.hash, type, addr.version);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -574,11 +562,10 @@ Address.fromScript = function fromScript(script) {
|
||||
* @param {Buffer|Hash} hash
|
||||
* @param {AddressPrefix} type
|
||||
* @param {Number} [version=-1]
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @throws on bad hash size
|
||||
*/
|
||||
|
||||
Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
Address.prototype.fromHash = function fromHash(hash, type, version) {
|
||||
if (typeof hash === 'string')
|
||||
hash = Buffer.from(hash, 'hex');
|
||||
|
||||
@ -593,8 +580,6 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
if (version == null)
|
||||
version = -1;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
assert(Buffer.isBuffer(hash));
|
||||
assert(util.isU8(type));
|
||||
assert(util.isI8(version));
|
||||
@ -618,7 +603,6 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
this.hash = hash;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
this.network = network;
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -628,113 +612,104 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
* @param {Hash} hash
|
||||
* @param {AddressPrefix} type
|
||||
* @param {Number} [version=-1]
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Address}
|
||||
* @throws on bad hash size
|
||||
*/
|
||||
|
||||
Address.fromHash = function fromHash(hash, type, version, network) {
|
||||
return new Address().fromHash(hash, type, version, network);
|
||||
Address.fromHash = function fromHash(hash, type, version) {
|
||||
return new Address().fromHash(hash, type, version);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from pubkeyhash.
|
||||
* @private
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.prototype.fromPubkeyhash = function fromPubkeyhash(hash, network) {
|
||||
Address.prototype.fromPubkeyhash = function fromPubkeyhash(hash) {
|
||||
const type = Address.types.PUBKEYHASH;
|
||||
assert(hash.length === 20, 'P2PKH must be 20 bytes.');
|
||||
return this.fromHash(hash, type, -1, network);
|
||||
return this.fromHash(hash, type, -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate address from pubkeyhash.
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.fromPubkeyhash = function fromPubkeyhash(hash, network) {
|
||||
return new Address().fromPubkeyhash(hash, network);
|
||||
Address.fromPubkeyhash = function fromPubkeyhash(hash) {
|
||||
return new Address().fromPubkeyhash(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from scripthash.
|
||||
* @private
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.prototype.fromScripthash = function fromScripthash(hash, network) {
|
||||
Address.prototype.fromScripthash = function fromScripthash(hash) {
|
||||
const type = Address.types.SCRIPTHASH;
|
||||
assert(hash && hash.length === 20, 'P2SH must be 20 bytes.');
|
||||
return this.fromHash(hash, type, -1, network);
|
||||
return this.fromHash(hash, type, -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate address from scripthash.
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.fromScripthash = function fromScripthash(hash, network) {
|
||||
return new Address().fromScripthash(hash, network);
|
||||
Address.fromScripthash = function fromScripthash(hash) {
|
||||
return new Address().fromScripthash(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from witness pubkeyhash.
|
||||
* @private
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.prototype.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash, network) {
|
||||
Address.prototype.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash) {
|
||||
const type = Address.types.WITNESS;
|
||||
assert(hash && hash.length === 20, 'P2WPKH must be 20 bytes.');
|
||||
return this.fromHash(hash, type, 0, network);
|
||||
return this.fromHash(hash, type, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate address from witness pubkeyhash.
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash, network) {
|
||||
return new Address().fromWitnessPubkeyhash(hash, network);
|
||||
Address.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash) {
|
||||
return new Address().fromWitnessPubkeyhash(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from witness scripthash.
|
||||
* @private
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.prototype.fromWitnessScripthash = function fromWitnessScripthash(hash, network) {
|
||||
Address.prototype.fromWitnessScripthash = function fromWitnessScripthash(hash) {
|
||||
const type = Address.types.WITNESS;
|
||||
assert(hash && hash.length === 32, 'P2WPKH must be 32 bytes.');
|
||||
return this.fromHash(hash, type, 0, network);
|
||||
return this.fromHash(hash, type, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate address from witness scripthash.
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.fromWitnessScripthash = function fromWitnessScripthash(hash, network) {
|
||||
return new Address().fromWitnessScripthash(hash, network);
|
||||
Address.fromWitnessScripthash = function fromWitnessScripthash(hash) {
|
||||
return new Address().fromWitnessScripthash(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -742,11 +717,10 @@ Address.fromWitnessScripthash = function fromWitnessScripthash(hash, network) {
|
||||
* @private
|
||||
* @param {Number} version
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.prototype.fromProgram = function fromProgram(version, hash, network) {
|
||||
Address.prototype.fromProgram = function fromProgram(version, hash) {
|
||||
const type = Address.types.WITNESS;
|
||||
|
||||
assert(version >= 0, 'Bad version for witness program.');
|
||||
@ -754,19 +728,18 @@ Address.prototype.fromProgram = function fromProgram(version, hash, network) {
|
||||
if (typeof hash === 'string')
|
||||
hash = Buffer.from(hash, 'hex');
|
||||
|
||||
return this.fromHash(hash, type, version, network);
|
||||
return this.fromHash(hash, type, version);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate address from witness program.
|
||||
* @param {Number} version
|
||||
* @param {Buffer} hash
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Address.fromProgram = function fromProgram(version, hash, network) {
|
||||
return new Address().fromProgram(version, hash, network);
|
||||
Address.fromProgram = function fromProgram(version, hash) {
|
||||
return new Address().fromProgram(version, hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -863,11 +836,6 @@ Address.getHash = function getHash(data, enc, network) {
|
||||
hash = data;
|
||||
} else if (data instanceof Address) {
|
||||
hash = data.hash;
|
||||
if (network) {
|
||||
network = Network.get(network);
|
||||
if (data.network !== network)
|
||||
throw new Error('Network mismatch for address.');
|
||||
}
|
||||
} else {
|
||||
throw new Error('Object is not an address.');
|
||||
}
|
||||
|
||||
@ -24,14 +24,12 @@ const secp256k1 = require('../crypto/secp256k1');
|
||||
* @alias module:primitives.KeyRing
|
||||
* @constructor
|
||||
* @param {Object} options
|
||||
* @param {Network} network
|
||||
*/
|
||||
|
||||
function KeyRing(options, network) {
|
||||
function KeyRing(options) {
|
||||
if (!(this instanceof KeyRing))
|
||||
return new KeyRing(options, network);
|
||||
return new KeyRing(options);
|
||||
|
||||
this.network = Network.primary;
|
||||
this.witness = false;
|
||||
this.nested = false;
|
||||
this.publicKey = encoding.ZERO_KEY;
|
||||
@ -48,7 +46,7 @@ function KeyRing(options, network) {
|
||||
this._scriptAddress = null;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options, network);
|
||||
this.fromOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,10 +55,7 @@ function KeyRing(options, network) {
|
||||
* @param {Object} options
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromOptions = function fromOptions(options, network) {
|
||||
if (!network)
|
||||
network = options.network;
|
||||
|
||||
KeyRing.prototype.fromOptions = function fromOptions(options) {
|
||||
let key = toKey(options);
|
||||
|
||||
if (options.witness != null) {
|
||||
@ -74,7 +69,7 @@ KeyRing.prototype.fromOptions = function fromOptions(options, network) {
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(key))
|
||||
return this.fromKey(key, network);
|
||||
return this.fromKey(key);
|
||||
|
||||
key = toKey(options.key);
|
||||
|
||||
@ -88,9 +83,9 @@ KeyRing.prototype.fromOptions = function fromOptions(options, network) {
|
||||
const compress = options.compressed;
|
||||
|
||||
if (script)
|
||||
return this.fromScript(key, script, compress, network);
|
||||
return this.fromScript(key, script, compress);
|
||||
|
||||
return this.fromKey(key, compress, network);
|
||||
return this.fromKey(key, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -123,19 +118,12 @@ KeyRing.prototype.refresh = function refresh() {
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromPrivate = function fromPrivate(key, compress, network) {
|
||||
KeyRing.prototype.fromPrivate = function fromPrivate(key, compress) {
|
||||
assert(Buffer.isBuffer(key), 'Private key must be a buffer.');
|
||||
assert(secp256k1.privateKeyVerify(key), 'Not a valid private key.');
|
||||
|
||||
if (typeof compress !== 'boolean') {
|
||||
network = compress;
|
||||
compress = null;
|
||||
}
|
||||
|
||||
this.network = Network.get(network);
|
||||
this.privateKey = key;
|
||||
this.publicKey = secp256k1.publicKeyCreate(key, compress !== false);
|
||||
|
||||
@ -146,25 +134,22 @@ KeyRing.prototype.fromPrivate = function fromPrivate(key, compress, network) {
|
||||
* Instantiate keyring from a private key.
|
||||
* @param {Buffer} key
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromPrivate = function fromPrivate(key, compress, network) {
|
||||
return new KeyRing().fromPrivate(key, compress, network);
|
||||
KeyRing.fromPrivate = function fromPrivate(key, compress) {
|
||||
return new KeyRing().fromPrivate(key, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject data from public key.
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromPublic = function fromPublic(key, network) {
|
||||
KeyRing.prototype.fromPublic = function fromPublic(key) {
|
||||
assert(Buffer.isBuffer(key), 'Public key must be a buffer.');
|
||||
assert(secp256k1.publicKeyVerify(key), 'Not a valid public key.');
|
||||
this.network = Network.get(network);
|
||||
this.publicKey = key;
|
||||
return this;
|
||||
};
|
||||
@ -173,41 +158,32 @@ KeyRing.prototype.fromPublic = function fromPublic(key, network) {
|
||||
* Generate a keyring.
|
||||
* @private
|
||||
* @param {Boolean?} compress
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.generate = function generate(compress, network) {
|
||||
if (typeof compress !== 'boolean') {
|
||||
network = compress;
|
||||
compress = null;
|
||||
}
|
||||
|
||||
KeyRing.prototype.generate = function generate(compress) {
|
||||
const key = secp256k1.generatePrivateKey();
|
||||
|
||||
return this.fromKey(key, compress, network);
|
||||
return this.fromKey(key, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a keyring.
|
||||
* @param {Boolean?} compress
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.generate = function generate(compress, network) {
|
||||
return new KeyRing().generate(compress, network);
|
||||
KeyRing.generate = function generate(compress) {
|
||||
return new KeyRing().generate(compress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate keyring from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromPublic = function fromPublic(key, network) {
|
||||
return new KeyRing().fromPublic(key, network);
|
||||
KeyRing.fromPublic = function fromPublic(key) {
|
||||
return new KeyRing().fromPublic(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -215,33 +191,26 @@ KeyRing.fromPublic = function fromPublic(key, network) {
|
||||
* @private
|
||||
* @param {Buffer} privateKey
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromKey = function fromKey(key, compress, network) {
|
||||
KeyRing.prototype.fromKey = function fromKey(key, compress) {
|
||||
assert(Buffer.isBuffer(key), 'Key must be a buffer.');
|
||||
|
||||
if (typeof compress !== 'boolean') {
|
||||
network = compress;
|
||||
compress = null;
|
||||
}
|
||||
|
||||
if (key.length === 32)
|
||||
return this.fromPrivate(key, compress !== false, network);
|
||||
return this.fromPrivate(key, compress !== false);
|
||||
|
||||
return this.fromPublic(key, network);
|
||||
return this.fromPublic(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate keyring from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromKey = function fromKey(key, compress, network) {
|
||||
return new KeyRing().fromKey(key, compress, network);
|
||||
KeyRing.fromKey = function fromKey(key, compress) {
|
||||
return new KeyRing().fromKey(key, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -250,18 +219,12 @@ KeyRing.fromKey = function fromKey(key, compress, network) {
|
||||
* @param {Buffer} key
|
||||
* @param {Script} script
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromScript = function fromScript(key, script, compress, network) {
|
||||
KeyRing.prototype.fromScript = function fromScript(key, script, compress) {
|
||||
assert(script instanceof Script, 'Non-script passed into KeyRing.');
|
||||
|
||||
if (typeof compress !== 'boolean') {
|
||||
network = compress;
|
||||
compress = null;
|
||||
}
|
||||
|
||||
this.fromKey(key, compress, network);
|
||||
this.fromKey(key, compress);
|
||||
this.script = script;
|
||||
|
||||
return this;
|
||||
@ -272,12 +235,11 @@ KeyRing.prototype.fromScript = function fromScript(key, script, compress, networ
|
||||
* @param {Buffer} key
|
||||
* @param {Script} script
|
||||
* @param {Boolean?} compress
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromScript = function fromScript(key, script, compress, network) {
|
||||
return new KeyRing().fromScript(key, script, compress, network);
|
||||
KeyRing.fromScript = function fromScript(key, script, compress) {
|
||||
return new KeyRing().fromScript(key, script, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -311,9 +273,6 @@ KeyRing.prototype.toSecret = function toSecret(network) {
|
||||
|
||||
assert(this.privateKey, 'Cannot serialize without private key.');
|
||||
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
bw.writeU8(network.keyPrefix.privkey);
|
||||
@ -339,7 +298,7 @@ KeyRing.prototype.fromSecret = function fromSecret(data, network) {
|
||||
|
||||
const version = br.readU8();
|
||||
|
||||
network = Network.fromWIF(version, network);
|
||||
Network.fromWIF(version, network);
|
||||
|
||||
const key = br.readBytes(32);
|
||||
|
||||
@ -352,7 +311,7 @@ KeyRing.prototype.fromSecret = function fromSecret(data, network) {
|
||||
|
||||
br.verifyChecksum();
|
||||
|
||||
return this.fromPrivate(key, compress, network);
|
||||
return this.fromPrivate(key, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -372,12 +331,12 @@ KeyRing.fromSecret = function fromSecret(data, network) {
|
||||
* @returns {Buffer} Private key.
|
||||
*/
|
||||
|
||||
KeyRing.prototype.getPrivateKey = function getPrivateKey(enc) {
|
||||
KeyRing.prototype.getPrivateKey = function getPrivateKey(enc, network) {
|
||||
if (!this.privateKey)
|
||||
return null;
|
||||
|
||||
if (enc === 'base58')
|
||||
return this.toSecret();
|
||||
return this.toSecret(network);
|
||||
|
||||
if (enc === 'hex')
|
||||
return this.privateKey.toString('hex');
|
||||
@ -459,21 +418,21 @@ KeyRing.prototype.getNestedHash = function getNestedHash(enc) {
|
||||
* @returns {Address|Base58Address}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.getNestedAddress = function getNestedAddress(enc) {
|
||||
KeyRing.prototype.getNestedAddress = function getNestedAddress(enc, network) {
|
||||
if (!this.witness)
|
||||
return null;
|
||||
|
||||
if (!this._nestedAddress) {
|
||||
const hash = this.getNestedHash();
|
||||
const addr = Address.fromScripthash(hash, this.network);
|
||||
const addr = Address.fromScripthash(hash);
|
||||
this._nestedAddress = addr;
|
||||
}
|
||||
|
||||
if (enc === 'base58')
|
||||
return this._nestedAddress.toBase58();
|
||||
return this._nestedAddress.toBase58(network);
|
||||
|
||||
if (enc === 'string')
|
||||
return this._nestedAddress.toString();
|
||||
return this._nestedAddress.toString(network);
|
||||
|
||||
return this._nestedAddress;
|
||||
};
|
||||
@ -532,7 +491,7 @@ KeyRing.prototype.getScriptHash256 = function getScriptHash256(enc) {
|
||||
* @returns {Address|Base58Address}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
|
||||
KeyRing.prototype.getScriptAddress = function getScriptAddress(enc, network) {
|
||||
if (!this.script)
|
||||
return null;
|
||||
|
||||
@ -540,19 +499,19 @@ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
|
||||
let addr;
|
||||
if (this.witness) {
|
||||
const hash = this.getScriptHash256();
|
||||
addr = Address.fromWitnessScripthash(hash, this.network);
|
||||
addr = Address.fromWitnessScripthash(hash);
|
||||
} else {
|
||||
const hash = this.getScriptHash160();
|
||||
addr = Address.fromScripthash(hash, this.network);
|
||||
addr = Address.fromScripthash(hash);
|
||||
}
|
||||
this._scriptAddress = addr;
|
||||
}
|
||||
|
||||
if (enc === 'base58')
|
||||
return this._scriptAddress.toBase58();
|
||||
return this._scriptAddress.toBase58(network);
|
||||
|
||||
if (enc === 'string')
|
||||
return this._scriptAddress.toString();
|
||||
return this._scriptAddress.toString(network);
|
||||
|
||||
return this._scriptAddress;
|
||||
};
|
||||
@ -578,24 +537,24 @@ KeyRing.prototype.getKeyHash = function getKeyHash(enc) {
|
||||
* @returns {Address|Base58Address}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) {
|
||||
KeyRing.prototype.getKeyAddress = function getKeyAddress(enc, network) {
|
||||
if (!this._keyAddress) {
|
||||
const hash = this.getKeyHash();
|
||||
|
||||
let addr;
|
||||
if (this.witness)
|
||||
addr = Address.fromWitnessPubkeyhash(hash, this.network);
|
||||
addr = Address.fromWitnessPubkeyhash(hash);
|
||||
else
|
||||
addr = Address.fromPubkeyhash(hash, this.network);
|
||||
addr = Address.fromPubkeyhash(hash);
|
||||
|
||||
this._keyAddress = addr;
|
||||
}
|
||||
|
||||
if (enc === 'base58')
|
||||
return this._keyAddress.toBase58();
|
||||
return this._keyAddress.toBase58(network);
|
||||
|
||||
if (enc === 'string')
|
||||
return this._keyAddress.toString();
|
||||
return this._keyAddress.toString(network);
|
||||
|
||||
return this._keyAddress;
|
||||
};
|
||||
@ -622,14 +581,14 @@ KeyRing.prototype.getHash = function getHash(enc) {
|
||||
* @returns {Address|Base58Address}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.getAddress = function getAddress(enc) {
|
||||
KeyRing.prototype.getAddress = function getAddress(enc, network) {
|
||||
if (this.nested)
|
||||
return this.getNestedAddress(enc);
|
||||
return this.getNestedAddress(enc, network);
|
||||
|
||||
if (this.script)
|
||||
return this.getScriptAddress(enc);
|
||||
return this.getScriptAddress(enc, network);
|
||||
|
||||
return this.getKeyAddress(enc);
|
||||
return this.getKeyAddress(enc, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -771,16 +730,15 @@ KeyRing.prototype.inspect = function inspect() {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.toJSON = function toJSON() {
|
||||
KeyRing.prototype.toJSON = function toJSON(network) {
|
||||
return {
|
||||
network: this.network.type,
|
||||
witness: this.witness,
|
||||
nested: this.nested,
|
||||
publicKey: this.publicKey.toString('hex'),
|
||||
script: this.script ? this.script.toRaw().toString('hex') : null,
|
||||
program: this.witness ? this.getProgram().toRaw().toString('hex') : null,
|
||||
type: Address.typesByVal[this.getType()].toLowerCase(),
|
||||
address: this.getAddress('string')
|
||||
address: this.getAddress('string', network)
|
||||
};
|
||||
};
|
||||
|
||||
@ -792,13 +750,11 @@ KeyRing.prototype.toJSON = function toJSON() {
|
||||
|
||||
KeyRing.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(json);
|
||||
assert(typeof json.network === 'string');
|
||||
assert(typeof json.witness === 'boolean');
|
||||
assert(typeof json.nested === 'boolean');
|
||||
assert(typeof json.publicKey === 'string');
|
||||
assert(!json.script || typeof json.script === 'string');
|
||||
|
||||
this.nework = Network.get(json.network);
|
||||
this.witness = json.witness;
|
||||
this.nested = json.nested;
|
||||
this.publicKey = Buffer.from(json.publicKey, 'hex');
|
||||
@ -882,12 +838,9 @@ KeyRing.prototype.toRaw = function toRaw() {
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
* @param {Network?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromReader = function fromReader(br, network) {
|
||||
this.network = Network.get(network);
|
||||
|
||||
KeyRing.prototype.fromReader = function fromReader(br) {
|
||||
const field = br.readU8();
|
||||
|
||||
this.witness = (field & 1) !== 0;
|
||||
@ -916,11 +869,10 @@ KeyRing.prototype.fromReader = function fromReader(br, network) {
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {Network?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data, network) {
|
||||
return this.fromReader(new BufferReader(data), network);
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -250,9 +250,6 @@ Account.prototype.pushKey = function pushKey(key) {
|
||||
if (typeof key === 'string')
|
||||
key = HD.PublicKey.fromBase58(key, this.network);
|
||||
|
||||
assert(key.network === this.network,
|
||||
'Network mismatch for account key.');
|
||||
|
||||
if (!HD.isPublic(key))
|
||||
throw new Error('Must add HD keys to wallet.');
|
||||
|
||||
@ -290,9 +287,6 @@ Account.prototype.spliceKey = function spliceKey(key) {
|
||||
if (typeof key === 'string')
|
||||
key = HD.PublicKey.fromBase58(key, this.network);
|
||||
|
||||
assert(key.network === this.network,
|
||||
'Network mismatch for account key.');
|
||||
|
||||
if (!HD.isPublic(key))
|
||||
throw new Error('Must add HD keys to wallet.');
|
||||
|
||||
@ -404,21 +398,21 @@ Account.prototype.createKey = async function createKey(b, branch) {
|
||||
key = this.deriveReceive(this.receiveDepth);
|
||||
lookahead = this.deriveReceive(this.receiveDepth + this.lookahead);
|
||||
await this.saveKey(b, lookahead);
|
||||
this.receiveDepth++;
|
||||
this.receiveDepth += 1;
|
||||
this.receive = key;
|
||||
break;
|
||||
case 1:
|
||||
key = this.deriveChange(this.changeDepth);
|
||||
lookahead = this.deriveReceive(this.changeDepth + this.lookahead);
|
||||
await this.saveKey(b, lookahead);
|
||||
this.changeDepth++;
|
||||
this.changeDepth += 1;
|
||||
this.change = key;
|
||||
break;
|
||||
case 2:
|
||||
key = this.deriveNested(this.nestedDepth);
|
||||
lookahead = this.deriveNested(this.nestedDepth + this.lookahead);
|
||||
await this.saveKey(b, lookahead);
|
||||
this.nestedDepth++;
|
||||
this.nestedDepth += 1;
|
||||
this.nested = key;
|
||||
break;
|
||||
default:
|
||||
@ -511,7 +505,8 @@ Account.prototype.deriveKey = function deriveKey(branch, index, master) {
|
||||
|
||||
let key;
|
||||
if (master && master.key && !this.watchOnly) {
|
||||
key = master.key.deriveAccount(44, this.accountIndex);
|
||||
const type = this.network.keyPrefix.coinType;
|
||||
key = master.key.deriveAccount(44, type, this.accountIndex);
|
||||
key = key.derive(branch).derive(index);
|
||||
} else {
|
||||
key = this.accountKey.derive(branch).derive(index);
|
||||
@ -577,22 +572,16 @@ Account.prototype.initDepth = async function initDepth(b) {
|
||||
// Receive Address
|
||||
this.receiveDepth = 1;
|
||||
|
||||
await this.saveKey(b, this.deriveReceive(0));
|
||||
|
||||
// Lookahead
|
||||
for (let i = 0; i < this.lookahead; i++) {
|
||||
const key = this.deriveReceive(i + 1);
|
||||
for (let i = 0; i <= this.lookahead; i++) {
|
||||
const key = this.deriveReceive(i);
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
|
||||
// Change Address
|
||||
this.changeDepth = 1;
|
||||
|
||||
await this.saveKey(b, this.deriveChange(0));
|
||||
|
||||
// Lookahead
|
||||
for (let i = 0; i < this.lookahead; i++) {
|
||||
const key = this.deriveChange(i + 1);
|
||||
for (let i = 0; i <= this.lookahead; i++) {
|
||||
const key = this.deriveChange(i);
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
|
||||
@ -600,11 +589,8 @@ Account.prototype.initDepth = async function initDepth(b) {
|
||||
if (this.witness) {
|
||||
this.nestedDepth = 1;
|
||||
|
||||
await this.saveKey(b, this.deriveNested(0));
|
||||
|
||||
// Lookahead
|
||||
for (let i = 0; i < this.lookahead; i++) {
|
||||
const key = this.deriveNested(i + 1);
|
||||
for (let i = 0; i <= this.lookahead; i++) {
|
||||
const key = this.deriveNested(i);
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
}
|
||||
@ -634,7 +620,6 @@ Account.prototype.syncDepth = async function syncDepth(b, receive, change, neste
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
|
||||
this.receive = this.deriveReceive(receive - 1);
|
||||
this.receiveDepth = receive;
|
||||
|
||||
derived = true;
|
||||
@ -651,7 +636,6 @@ Account.prototype.syncDepth = async function syncDepth(b, receive, change, neste
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
|
||||
this.change = this.deriveChange(change - 1);
|
||||
this.changeDepth = change;
|
||||
|
||||
derived = true;
|
||||
@ -667,7 +651,6 @@ Account.prototype.syncDepth = async function syncDepth(b, receive, change, neste
|
||||
await this.saveKey(b, key);
|
||||
}
|
||||
|
||||
this.nested = this.deriveNested(nested - 1);
|
||||
this.nestedDepth = nested;
|
||||
|
||||
derived = true;
|
||||
@ -694,7 +677,6 @@ Account.prototype.setLookahead = async function setLookahead(b, lookahead) {
|
||||
const diff = this.lookahead - lookahead;
|
||||
|
||||
this.receiveDepth += diff;
|
||||
|
||||
this.changeDepth += diff;
|
||||
|
||||
if (this.witness)
|
||||
@ -828,10 +810,14 @@ Account.prototype.nestedAddress = function nestedAddress() {
|
||||
*/
|
||||
|
||||
Account.prototype.inspect = function inspect() {
|
||||
const receive = this.receiveAddress();
|
||||
const change = this.changeAddress();
|
||||
const nested = this.nestedAddress();
|
||||
|
||||
return {
|
||||
wid: this.wid,
|
||||
name: this.name,
|
||||
network: this.network,
|
||||
network: this.network.type,
|
||||
initialized: this.initialized,
|
||||
witness: this.witness,
|
||||
watchOnly: this.watchOnly,
|
||||
@ -843,11 +829,11 @@ Account.prototype.inspect = function inspect() {
|
||||
changeDepth: this.changeDepth,
|
||||
nestedDepth: this.nestedDepth,
|
||||
lookahead: this.lookahead,
|
||||
receiveAddress: this.receiveAddress(),
|
||||
changeAddress: this.changeAddress(),
|
||||
nestedAddress: this.nestedAddress(),
|
||||
accountKey: this.accountKey.toBase58(),
|
||||
keys: this.keys.map(key => key.toBase58())
|
||||
receiveAddress: receive ? receive.toString(this.network) : null,
|
||||
changeAddress: change ? change.toString(this.network) : null,
|
||||
nestedAddress: nested ? nested.toString(this.network) : null,
|
||||
accountKey: this.accountKey.toBase58(this.network),
|
||||
keys: this.keys.map(key => key.toBase58(this.network))
|
||||
};
|
||||
};
|
||||
|
||||
@ -877,11 +863,11 @@ Account.prototype.toJSON = function toJSON(minimal, balance) {
|
||||
changeDepth: this.changeDepth,
|
||||
nestedDepth: this.nestedDepth,
|
||||
lookahead: this.lookahead,
|
||||
receiveAddress: receive ? receive.toString() : null,
|
||||
changeAddress: change ? change.toString() : null,
|
||||
nestedAddress: nested ? nested.toString() : null,
|
||||
accountKey: this.accountKey.toBase58(),
|
||||
keys: this.keys.map(key => key.toBase58()),
|
||||
receiveAddress: receive ? receive.toString(this.network) : null,
|
||||
changeAddress: change ? change.toString(this.network) : null,
|
||||
nestedAddress: nested ? nested.toString(this.network) : null,
|
||||
accountKey: this.accountKey.toBase58(this.network),
|
||||
keys: this.keys.map(key => key.toBase58(this.network)),
|
||||
balance: balance ? balance.toJSON(true) : null
|
||||
};
|
||||
};
|
||||
@ -919,11 +905,11 @@ Account.prototype.toRaw = function toRaw() {
|
||||
bw.writeU32(this.changeDepth);
|
||||
bw.writeU32(this.nestedDepth);
|
||||
bw.writeU8(this.lookahead);
|
||||
bw.writeBytes(this.accountKey.toRaw());
|
||||
bw.writeBytes(this.accountKey.toRaw(this.network));
|
||||
bw.writeU8(this.keys.length);
|
||||
|
||||
for (const key of this.keys)
|
||||
bw.writeBytes(key.toRaw());
|
||||
bw.writeBytes(key.toRaw(this.network));
|
||||
|
||||
return bw.render();
|
||||
};
|
||||
@ -949,14 +935,14 @@ Account.prototype.fromRaw = function fromRaw(data) {
|
||||
this.changeDepth = br.readU32();
|
||||
this.nestedDepth = br.readU32();
|
||||
this.lookahead = br.readU8();
|
||||
this.accountKey = HD.PublicKey.fromRaw(br.readBytes(82));
|
||||
this.accountKey = HD.PublicKey.fromRaw(br.readBytes(82), this.network);
|
||||
|
||||
assert(Account.typesByVal[this.type]);
|
||||
|
||||
const count = br.readU8();
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const key = HD.PublicKey.fromRaw(br.readBytes(82));
|
||||
const key = HD.PublicKey.fromRaw(br.readBytes(82), this.network);
|
||||
this.pushKey(key);
|
||||
}
|
||||
|
||||
|
||||
@ -572,7 +572,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
return;
|
||||
}
|
||||
|
||||
res.send(200, key.toJSON());
|
||||
res.send(200, key.toJSON(this.network));
|
||||
});
|
||||
|
||||
// Get private key
|
||||
@ -590,7 +590,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
return;
|
||||
}
|
||||
|
||||
res.send(200, { privateKey: key.toSecret() });
|
||||
res.send(200, { privateKey: key.toSecret(this.network) });
|
||||
});
|
||||
|
||||
// Create address
|
||||
@ -599,7 +599,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
const acct = valid.str('account');
|
||||
const address = await req.wallet.createReceive(acct);
|
||||
|
||||
res.send(200, address.toJSON());
|
||||
res.send(200, address.toJSON(this.network));
|
||||
});
|
||||
|
||||
// Create change address
|
||||
@ -608,7 +608,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
const acct = valid.str('account');
|
||||
const address = await req.wallet.createChange(acct);
|
||||
|
||||
res.send(200, address.toJSON());
|
||||
res.send(200, address.toJSON(this.network));
|
||||
});
|
||||
|
||||
// Create nested address
|
||||
@ -617,7 +617,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
const acct = valid.str('account');
|
||||
const address = await req.wallet.createNested(acct);
|
||||
|
||||
res.send(200, address.toJSON());
|
||||
res.send(200, address.toJSON(this.network));
|
||||
});
|
||||
|
||||
// Wallet Balance
|
||||
@ -851,7 +851,7 @@ HTTPServer.prototype.initSockets = function initSockets() {
|
||||
const json = [];
|
||||
|
||||
for (const addr of receive)
|
||||
json.push(addr.toJSON());
|
||||
json.push(addr.toJSON(this.network));
|
||||
|
||||
this.to(`w:${w.id}`, 'wallet address', json);
|
||||
});
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const Network = require('../protocol/network');
|
||||
const util = require('../utils/util');
|
||||
const Lock = require('../utils/lock');
|
||||
const random = require('../crypto/random');
|
||||
@ -92,6 +93,9 @@ MasterKey.algByVal = {
|
||||
MasterKey.prototype.fromOptions = function fromOptions(options) {
|
||||
assert(options);
|
||||
|
||||
if (options.network != null)
|
||||
this.network = Network.get(options.network);
|
||||
|
||||
if (options.encrypted != null) {
|
||||
assert(typeof options.encrypted === 'boolean');
|
||||
this.encrypted = options.encrypted;
|
||||
@ -203,7 +207,7 @@ MasterKey.prototype._unlock = async function _unlock(passphrase, timeout) {
|
||||
const key = await this.derive(passphrase);
|
||||
const data = aes.decipher(this.ciphertext, key, this.iv);
|
||||
|
||||
this.fromKeyRaw(data);
|
||||
this.readKey(data);
|
||||
|
||||
this.start(timeout);
|
||||
|
||||
@ -388,7 +392,7 @@ MasterKey.prototype._decrypt = async function _decrypt(passphrase, clean) {
|
||||
const key = await this.derive(passphrase);
|
||||
const data = aes.decipher(this.ciphertext, key, this.iv);
|
||||
|
||||
this.fromKeyRaw(data);
|
||||
this.readKey(data);
|
||||
this.encrypted = false;
|
||||
this.iv = null;
|
||||
this.ciphertext = null;
|
||||
@ -430,7 +434,7 @@ MasterKey.prototype._encrypt = async function _encrypt(passphrase, clean) {
|
||||
if (!passphrase)
|
||||
throw new Error('No passphrase provided.');
|
||||
|
||||
const raw = this.toKeyRaw();
|
||||
const raw = this.writeKey();
|
||||
const iv = random.randomBytes(16);
|
||||
|
||||
this.stop();
|
||||
@ -457,7 +461,7 @@ MasterKey.prototype._encrypt = async function _encrypt(passphrase, clean) {
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
MasterKey.prototype.getKeySize = function getKeySize() {
|
||||
MasterKey.prototype.keySize = function keySize() {
|
||||
let size = 0;
|
||||
|
||||
size += this.key.getSize();
|
||||
@ -474,10 +478,10 @@ MasterKey.prototype.getKeySize = function getKeySize() {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MasterKey.prototype.toKeyRaw = function toKeyRaw() {
|
||||
const bw = new StaticWriter(this.getKeySize());
|
||||
MasterKey.prototype.writeKey = function writeKey() {
|
||||
const bw = new StaticWriter(this.keySize());
|
||||
|
||||
this.key.toWriter(bw);
|
||||
this.key.toWriter(bw, this.network);
|
||||
|
||||
if (this.mnemonic) {
|
||||
bw.writeU8(1);
|
||||
@ -494,10 +498,10 @@ MasterKey.prototype.toKeyRaw = function toKeyRaw() {
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
MasterKey.prototype.fromKeyRaw = function fromKeyRaw(data) {
|
||||
MasterKey.prototype.readKey = function readKey(data) {
|
||||
const br = new BufferReader(data);
|
||||
|
||||
this.key = HD.PrivateKey.fromReader(br);
|
||||
this.key = HD.PrivateKey.fromReader(br, this.network);
|
||||
|
||||
if (br.readU8() === 1)
|
||||
this.mnemonic = Mnemonic.fromReader(br);
|
||||
@ -522,7 +526,7 @@ MasterKey.prototype.getSize = function getSize() {
|
||||
}
|
||||
|
||||
size += 1;
|
||||
size += encoding.sizeVarlen(this.getKeySize());
|
||||
size += encoding.sizeVarlen(this.keySize());
|
||||
|
||||
return size;
|
||||
};
|
||||
@ -552,10 +556,10 @@ MasterKey.prototype.toRaw = function toRaw() {
|
||||
bw.writeU8(0);
|
||||
|
||||
// NOTE: useless varint
|
||||
const size = this.getKeySize();
|
||||
const size = this.keySize();
|
||||
bw.writeVarint(size);
|
||||
|
||||
bw.writeBytes(this.key.toRaw());
|
||||
bw.writeBytes(this.key.toRaw(this.network));
|
||||
|
||||
if (this.mnemonic) {
|
||||
bw.writeU8(1);
|
||||
@ -573,9 +577,10 @@ MasterKey.prototype.toRaw = function toRaw() {
|
||||
* @param {Buffer} raw
|
||||
*/
|
||||
|
||||
MasterKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
MasterKey.prototype.fromRaw = function fromRaw(raw, network) {
|
||||
const br = new BufferReader(raw);
|
||||
|
||||
this.network = Network.get(network);
|
||||
this.encrypted = br.readU8() === 1;
|
||||
|
||||
if (this.encrypted) {
|
||||
@ -596,7 +601,7 @@ MasterKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
// NOTE: useless varint
|
||||
br.readVarint();
|
||||
|
||||
this.key = HD.PrivateKey.fromRaw(br.readBytes(82));
|
||||
this.key = HD.PrivateKey.fromRaw(br.readBytes(82), this.network);
|
||||
|
||||
if (br.readU8() === 1)
|
||||
this.mnemonic = Mnemonic.fromReader(br);
|
||||
@ -609,8 +614,8 @@ MasterKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
* @returns {MasterKey}
|
||||
*/
|
||||
|
||||
MasterKey.fromRaw = function fromRaw(raw) {
|
||||
return new MasterKey().fromRaw(raw);
|
||||
MasterKey.fromRaw = function fromRaw(raw, network) {
|
||||
return new MasterKey().fromRaw(raw, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -620,12 +625,13 @@ MasterKey.fromRaw = function fromRaw(raw) {
|
||||
* @param {Mnemonic?} mnemonic
|
||||
*/
|
||||
|
||||
MasterKey.prototype.fromKey = function fromKey(key, mnemonic) {
|
||||
MasterKey.prototype.fromKey = function fromKey(key, mnemonic, network) {
|
||||
this.encrypted = false;
|
||||
this.iv = null;
|
||||
this.ciphertext = null;
|
||||
this.key = key;
|
||||
this.mnemonic = mnemonic || null;
|
||||
this.network = Network.get(network);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -636,8 +642,8 @@ MasterKey.prototype.fromKey = function fromKey(key, mnemonic) {
|
||||
* @returns {MasterKey}
|
||||
*/
|
||||
|
||||
MasterKey.fromKey = function fromKey(key, mnemonic) {
|
||||
return new MasterKey().fromKey(key, mnemonic);
|
||||
MasterKey.fromKey = function fromKey(key, mnemonic, network) {
|
||||
return new MasterKey().fromKey(key, mnemonic, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -663,7 +669,7 @@ MasterKey.prototype.toJSON = function toJSON(unsafe) {
|
||||
|
||||
return {
|
||||
encrypted: false,
|
||||
key: unsafe ? this.key.toJSON() : undefined,
|
||||
key: unsafe ? this.key.toJSON(this.network) : undefined,
|
||||
mnemonic: unsafe && this.mnemonic ? this.mnemonic.toJSON() : undefined
|
||||
};
|
||||
};
|
||||
@ -677,7 +683,7 @@ MasterKey.prototype.inspect = function inspect() {
|
||||
const json = this.toJSON(true);
|
||||
|
||||
if (this.key)
|
||||
json.key = this.key.toJSON();
|
||||
json.key = this.key.toJSON(this.network);
|
||||
|
||||
if (this.mnemonic)
|
||||
json.mnemonic = this.mnemonic.toJSON();
|
||||
|
||||
@ -277,8 +277,8 @@ Path.prototype.toPath = function toPath() {
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Path.prototype.toAddress = function toAddress(network) {
|
||||
return Address.fromHash(this.hash, this.type, this.version, network);
|
||||
Path.prototype.toAddress = function toAddress() {
|
||||
return Address.fromHash(this.hash, this.type, this.version);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -238,7 +238,7 @@ RPC.prototype.dumpPrivKey = async function dumpPrivKey(args, help) {
|
||||
if (!ring)
|
||||
throw new RPCError(errs.MISC_ERROR, 'Key not found.');
|
||||
|
||||
return ring.toSecret();
|
||||
return ring.toSecret(this.network);
|
||||
};
|
||||
|
||||
RPC.prototype.dumpWallet = async function dumpWallet(args, help) {
|
||||
@ -279,7 +279,7 @@ RPC.prototype.dumpWallet = async function dumpWallet(args, help) {
|
||||
if (ring.branch === 1)
|
||||
fmt = '%s %s change=1 addr=%s';
|
||||
|
||||
const str = util.fmt(fmt, ring.toSecret(), time, addr);
|
||||
const str = util.fmt(fmt, ring.toSecret(this.network), time, addr);
|
||||
|
||||
out.push(str);
|
||||
}
|
||||
|
||||
@ -2137,6 +2137,11 @@ Balance.prototype.applyTo = function applyTo(balance) {
|
||||
balance.coin += this.coin;
|
||||
balance.unconfirmed += this.unconfirmed;
|
||||
balance.confirmed += this.confirmed;
|
||||
|
||||
assert(balance.tx >= 0);
|
||||
assert(balance.coin >= 0);
|
||||
assert(balance.unconfirmed >= 0);
|
||||
assert(balance.confirmed >= 0);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2204,7 +2209,6 @@ Balance.prototype.toJSON = function toJSON(minimal) {
|
||||
*/
|
||||
|
||||
Balance.prototype.inspect = function inspect() {
|
||||
return this;
|
||||
return '<Balance'
|
||||
+ ` tx=${this.tx}`
|
||||
+ ` coin=${this.coin}`
|
||||
|
||||
@ -109,13 +109,10 @@ Wallet.prototype.fromOptions = function fromOptions(options) {
|
||||
'Must create wallet with hd private key.');
|
||||
} else {
|
||||
mnemonic = new Mnemonic(options.mnemonic);
|
||||
key = HD.fromMnemonic(mnemonic, this.network);
|
||||
key = HD.fromMnemonic(mnemonic);
|
||||
}
|
||||
|
||||
assert(key.network === this.network,
|
||||
'Network mismatch for master key.');
|
||||
|
||||
this.master.fromKey(key, mnemonic);
|
||||
this.master.fromKey(key, mnemonic, this.network);
|
||||
|
||||
if (options.wid != null) {
|
||||
assert(util.isU32(options.wid));
|
||||
@ -616,12 +613,10 @@ Wallet.prototype._createAccount = async function _createAccount(options, passphr
|
||||
|
||||
if (!HD.isPublic(key))
|
||||
throw new Error('Must add HD public keys to watch only wallet.');
|
||||
|
||||
assert(key.network === this.network,
|
||||
'Network mismatch for watch only key.');
|
||||
} else {
|
||||
assert(this.master.key);
|
||||
key = this.master.key.deriveAccount(44, this.accountDepth);
|
||||
const type = this.network.keyPrefix.coinType;
|
||||
key = this.master.key.deriveAccount(44, type, this.accountDepth);
|
||||
key = key.toPublic();
|
||||
}
|
||||
|
||||
@ -1006,9 +1001,6 @@ Wallet.prototype.importKey = async function importKey(acct, ring, passphrase) {
|
||||
*/
|
||||
|
||||
Wallet.prototype._importKey = async function _importKey(acct, ring, passphrase) {
|
||||
assert(ring.network === this.network,
|
||||
'Network mismatch for key.');
|
||||
|
||||
if (!this.watchOnly) {
|
||||
if (!ring.privateKey)
|
||||
throw new Error('Cannot import pubkey into non watch-only wallet.');
|
||||
@ -1074,9 +1066,6 @@ Wallet.prototype.importAddress = async function importAddress(acct, address) {
|
||||
*/
|
||||
|
||||
Wallet.prototype._importAddress = async function _importAddress(acct, address) {
|
||||
assert(address.network === this.network,
|
||||
'Network mismatch for address.');
|
||||
|
||||
if (!this.watchOnly)
|
||||
throw new Error('Cannot import address into non watch-only wallet.');
|
||||
|
||||
@ -1885,7 +1874,7 @@ Wallet.prototype._add = async function _add(tx, block) {
|
||||
if (details) {
|
||||
const derived = await this.syncOutputDepth(tx);
|
||||
if (derived.length > 0) {
|
||||
this.wdb.emit('address', this.id, derived);
|
||||
this.wdb.emit('address', this, derived);
|
||||
this.emit('address', derived);
|
||||
}
|
||||
}
|
||||
@ -2350,6 +2339,8 @@ Wallet.prototype.fromRaw = function fromRaw(data) {
|
||||
const br = new BufferReader(data);
|
||||
const network = Network.fromMagic(br.readU32());
|
||||
|
||||
assert(network === this.network, 'Wallet network mismatch.');
|
||||
|
||||
this.wid = br.readU32();
|
||||
this.id = br.readVarString('ascii');
|
||||
this.initialized = br.readU8() === 1;
|
||||
@ -2357,9 +2348,7 @@ Wallet.prototype.fromRaw = function fromRaw(data) {
|
||||
this.accountDepth = br.readU32();
|
||||
this.token = br.readBytes(32);
|
||||
this.tokenDepth = br.readU32();
|
||||
this.master.fromRaw(br.readVarBytes());
|
||||
|
||||
assert(network === this.wdb.network, 'Wallet network mismatch.');
|
||||
this.master.fromRaw(br.readVarBytes(), this.network);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -18,11 +18,11 @@ const Path = require('./path');
|
||||
* @param {Object} options
|
||||
*/
|
||||
|
||||
function WalletKey(options, network) {
|
||||
function WalletKey(options) {
|
||||
if (!(this instanceof WalletKey))
|
||||
return new WalletKey(options, network);
|
||||
return new WalletKey(options);
|
||||
|
||||
KeyRing.call(this, options, network);
|
||||
KeyRing.call(this, options);
|
||||
|
||||
this.keyType = Path.types.HD;
|
||||
|
||||
@ -48,56 +48,52 @@ WalletKey.fromOptions = function fromOptions(options) {
|
||||
* Instantiate wallet key from a private key.
|
||||
* @param {Buffer} key
|
||||
* @param {Boolean?} compressed
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {WalletKey}
|
||||
*/
|
||||
|
||||
WalletKey.fromPrivate = function fromPrivate(key, compressed, network) {
|
||||
return new WalletKey().fromPrivate(key, compressed, network);
|
||||
WalletKey.fromPrivate = function fromPrivate(key, compressed) {
|
||||
return new WalletKey().fromPrivate(key, compressed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a wallet key.
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @param {Boolean?} compressed
|
||||
* @returns {WalletKey}
|
||||
*/
|
||||
|
||||
WalletKey.generate = function generate(compressed, network) {
|
||||
return new WalletKey().generate(compressed, network);
|
||||
WalletKey.generate = function generate(compressed) {
|
||||
return new WalletKey().generate(compressed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate wallet key from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {WalletKey}
|
||||
*/
|
||||
|
||||
WalletKey.fromPublic = function fromPublic(key, network) {
|
||||
return new WalletKey().fromPublic(key, network);
|
||||
WalletKey.fromPublic = function fromPublic(key) {
|
||||
return new WalletKey().fromPublic(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate wallet key from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {WalletKey}
|
||||
*/
|
||||
|
||||
WalletKey.fromKey = function fromKey(key, compressed, network) {
|
||||
return new WalletKey().fromKey(key, compressed, network);
|
||||
WalletKey.fromKey = function fromKey(key, compressed) {
|
||||
return new WalletKey().fromKey(key, compressed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate wallet key from script.
|
||||
* @param {Buffer} key
|
||||
* @param {Script} script
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {WalletKey}
|
||||
*/
|
||||
|
||||
WalletKey.fromScript = function fromScript(key, script, compressed, network) {
|
||||
return new WalletKey().fromScript(key, script, compressed, network);
|
||||
WalletKey.fromScript = function fromScript(key, script, compressed) {
|
||||
return new WalletKey().fromScript(key, script, compressed);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -116,9 +112,8 @@ WalletKey.fromSecret = function fromSecret(data, network) {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
WalletKey.prototype.toJSON = function toJSON() {
|
||||
WalletKey.prototype.toJSON = function toJSON(network) {
|
||||
return {
|
||||
network: this.network.type,
|
||||
name: this.name,
|
||||
account: this.account,
|
||||
branch: this.branch,
|
||||
@ -129,7 +124,7 @@ WalletKey.prototype.toJSON = function toJSON() {
|
||||
script: this.script ? this.script.toRaw().toString('hex') : null,
|
||||
program: this.witness ? this.getProgram().toRaw().toString('hex') : null,
|
||||
type: Address.typesByVal[this.getType()].toLowerCase(),
|
||||
address: this.getAddress('string')
|
||||
address: this.getAddress('string', network)
|
||||
};
|
||||
};
|
||||
|
||||
@ -173,9 +168,9 @@ WalletKey.prototype.fromHD = function fromHD(account, key, branch, index) {
|
||||
this.nested = branch === 2;
|
||||
|
||||
if (key.privateKey)
|
||||
return this.fromPrivate(key.privateKey, account.network);
|
||||
return this.fromPrivate(key.privateKey);
|
||||
|
||||
return this.fromPublic(key.publicKey, account.network);
|
||||
return this.fromPublic(key.publicKey);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -204,7 +199,7 @@ WalletKey.prototype.fromImport = function fromImport(account, data) {
|
||||
this.name = account.name;
|
||||
this.account = account.accountIndex;
|
||||
this.witness = account.witness;
|
||||
return this.fromRaw(data, account.network);
|
||||
return this.fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,7 +226,7 @@ WalletKey.prototype.fromRing = function fromRing(account, ring) {
|
||||
this.name = account.name;
|
||||
this.account = account.accountIndex;
|
||||
this.witness = account.witness;
|
||||
return this.fromOptions(ring, ring.network);
|
||||
return this.fromOptions(ring);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -329,7 +329,6 @@ function keyFromRaw(data, network) {
|
||||
const ring = {};
|
||||
const p = new BufferReader(data);
|
||||
|
||||
ring.network = bcoin.network.get(network);
|
||||
ring.witness = p.readU8() === 1;
|
||||
|
||||
const key = p.readVarBytes();
|
||||
|
||||
@ -13,7 +13,7 @@ describe('Address', function() {
|
||||
const p2pkh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromPubkeyhash(p2pkh);
|
||||
const expectedAddr = '1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match mainnet p2pkh address 2', () => {
|
||||
@ -21,15 +21,15 @@ describe('Address', function() {
|
||||
const p2pkh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromPubkeyhash(p2pkh);
|
||||
const expectedAddr = '12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match testnet p2pkh address', () => {
|
||||
const raw = '78b316a08647d5b77283e512d3603f1f1c8de68f';
|
||||
const p2pkh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromPubkeyhash(p2pkh, 'testnet');
|
||||
const addr = Address.fromPubkeyhash(p2pkh);
|
||||
const expectedAddr = 'mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('testnet'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should handle wrong p2pkh hash length', () => {
|
||||
@ -59,7 +59,7 @@ describe('Address', function() {
|
||||
const script = Script.fromRaw(p2sh);
|
||||
const addr = Address.fromScript(script);
|
||||
const expectedAddr = '3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match mainnet p2sh address obtained from script hash', () => {
|
||||
@ -67,7 +67,7 @@ describe('Address', function() {
|
||||
const p2sh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromScripthash(p2sh);
|
||||
const expectedAddr = '3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match mainnet p2sh address obtained from script 2', () => {
|
||||
@ -75,15 +75,15 @@ describe('Address', function() {
|
||||
const p2sh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromScripthash(p2sh);
|
||||
const expectedAddr = '3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match testnet p2sh address', () => {
|
||||
const raw = 'c579342c2c4c9220205e2cdc285617040c924a0a';
|
||||
const p2sh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromScripthash(p2sh, 'testnet');
|
||||
const addr = Address.fromScripthash(p2sh);
|
||||
const expectedAddr = '2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('testnet'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match mainnet segwit p2wpkh v0 address', () => {
|
||||
@ -91,7 +91,7 @@ describe('Address', function() {
|
||||
const p2wpkh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromWitnessPubkeyhash(p2wpkh);
|
||||
const expectedAddr = 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('main'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match mainnet segwit p2pwsh v0 address', () => {
|
||||
@ -101,16 +101,16 @@ describe('Address', function() {
|
||||
+ '6c985678cd4d27a1'
|
||||
+ 'b8c6329604903262', 'hex');
|
||||
const addr = Address.fromWitnessScripthash(p2wpkh);
|
||||
assert.strictEqual(addr.toString(),
|
||||
assert.strictEqual(addr.toString('main'),
|
||||
'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3');
|
||||
});
|
||||
|
||||
it('should match testnet segwit p2wpkh v0 address', () => {
|
||||
const raw = '751e76e8199196d454941c45d1b3a323f1433bd6';
|
||||
const p2wpkh = Buffer.from(raw, 'hex');
|
||||
const addr = Address.fromWitnessPubkeyhash(p2wpkh, 'testnet');
|
||||
const addr = Address.fromWitnessPubkeyhash(p2wpkh);
|
||||
const expectedAddr = 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx';
|
||||
assert.strictEqual(addr.toString(), expectedAddr);
|
||||
assert.strictEqual(addr.toString('testnet'), expectedAddr);
|
||||
});
|
||||
|
||||
it('should match testnet segwit p2pwsh v0 address', () => {
|
||||
@ -119,8 +119,8 @@ describe('Address', function() {
|
||||
+ '04bd19203356da13'
|
||||
+ '6c985678cd4d27a1'
|
||||
+ 'b8c6329604903262', 'hex');
|
||||
const addr = Address.fromWitnessScripthash(p2wpkh, 'testnet');
|
||||
assert.strictEqual(addr.toString(),
|
||||
const addr = Address.fromWitnessScripthash(p2wpkh);
|
||||
assert.strictEqual(addr.toString('testnet'),
|
||||
'tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7');
|
||||
});
|
||||
|
||||
@ -130,56 +130,56 @@ describe('Address', function() {
|
||||
+ '21b2a187905e5266'
|
||||
+ '362b99d5e91c6ce2'
|
||||
+ '4d165dab93e86433', 'hex');
|
||||
const addr = Address.fromWitnessScripthash(p2wpkh, 'testnet');
|
||||
assert.strictEqual(addr.toString(),
|
||||
const addr = Address.fromWitnessScripthash(p2wpkh);
|
||||
assert.strictEqual(addr.toString('testnet'),
|
||||
'tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy');
|
||||
});
|
||||
|
||||
it('should handle invalid segwit hrp', () => {
|
||||
const addr = 'tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle invalid segwit checksum', () => {
|
||||
const addr = 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle invalid segwit version', () => {
|
||||
const addr = 'BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle invalid segwit program length', () => {
|
||||
const addr = 'bc1rw5uspcuh';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle invalid segwit program length 2', () => {
|
||||
const addr = 'bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw5'
|
||||
+ '08d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle invalid segwit program length for witness v0', () => {
|
||||
const addr = 'tb1pw508d6qejxtdg4y5r3zarqfsj6c3';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle segwit mixed case', () => {
|
||||
const addr = 'tb1qrp33g0q5c5txsp9arysrx4k6z'
|
||||
+ 'dkfs4nce4xj0gdcccefvpysxf3q0sL5k7';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle segwit zero padding of more than 4 bits', () => {
|
||||
const addr = 'tb1pw508d6qejxtdg4y5r3zarqfsj6c3';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
|
||||
it('should handle segwit non-zero padding in 8-to-5 conversion', () => {
|
||||
const addr = 'tb1qrp33g0q5c5txsp9arysrx4k6'
|
||||
+ 'zdkfs4nce4xj0gdcccefvpysxf3pjxtptv';
|
||||
assert.throws(() => Address.fromString(addr));
|
||||
assert.throws(() => Address.fromString(addr, 'main'));
|
||||
});
|
||||
});
|
||||
|
||||
@ -182,16 +182,19 @@ describe('Bech32', function() {
|
||||
for (const [addr, script] of validAddresses) {
|
||||
it(`should have valid address for ${addr}`, () => {
|
||||
let ret = null;
|
||||
let network = null;
|
||||
|
||||
try {
|
||||
ret = Address.fromBech32(addr, 'main');
|
||||
network = 'main';
|
||||
ret = Address.fromBech32(addr, network);
|
||||
} catch (e) {
|
||||
ret = null;
|
||||
}
|
||||
|
||||
if (ret === null) {
|
||||
try {
|
||||
ret = Address.fromBech32(addr, 'testnet');
|
||||
network = 'testnet';
|
||||
ret = Address.fromBech32(addr, network);
|
||||
} catch (e) {
|
||||
ret = null;
|
||||
}
|
||||
@ -202,7 +205,7 @@ describe('Bech32', function() {
|
||||
const output = createProgram(ret.version, ret.hash);
|
||||
assert.bufferEqual(output, script);
|
||||
|
||||
const recreate = ret.toBech32();
|
||||
const recreate = ret.toBech32(network);
|
||||
assert.strictEqual(recreate, addr.toLowerCase());
|
||||
});
|
||||
}
|
||||
|
||||
@ -29,49 +29,49 @@ describe('HD', function() {
|
||||
it('should create master private key', () => {
|
||||
const seed = Buffer.from(vectors.seed, 'hex');
|
||||
const key = HD.PrivateKey.fromSeed(seed);
|
||||
assert.strictEqual(key.toBase58(), vectors.master_priv);
|
||||
assert.strictEqual(key.toPublic().toBase58(), vectors.master_pub);
|
||||
assert.strictEqual(key.toBase58('main'), vectors.master_priv);
|
||||
assert.strictEqual(key.toPublic().toBase58('main'), vectors.master_pub);
|
||||
master = key;
|
||||
});
|
||||
|
||||
it('should derive(0) child from master', () => {
|
||||
const child1 = master.derive(0);
|
||||
assert.strictEqual(child1.toBase58(), vectors.child1_priv);
|
||||
assert.strictEqual(child1.toPublic().toBase58(), vectors.child1_pub);
|
||||
assert.strictEqual(child1.toBase58('main'), vectors.child1_priv);
|
||||
assert.strictEqual(child1.toPublic().toBase58('main'), vectors.child1_pub);
|
||||
});
|
||||
|
||||
it('should derive(1) child from master public key', () => {
|
||||
const child2 = master.toPublic().derive(1);
|
||||
assert.strictEqual(child2.toBase58(), vectors.child2_pub);
|
||||
assert.strictEqual(child2.toBase58('main'), vectors.child2_pub);
|
||||
});
|
||||
|
||||
it('should derive(1) child from master', () => {
|
||||
const child3 = master.derive(1);
|
||||
assert.strictEqual(child3.toBase58(), vectors.child3_priv);
|
||||
assert.strictEqual(child3.toPublic().toBase58(), vectors.child3_pub);
|
||||
assert.strictEqual(child3.toBase58('main'), vectors.child3_priv);
|
||||
assert.strictEqual(child3.toPublic().toBase58('main'), vectors.child3_pub);
|
||||
});
|
||||
|
||||
it('should derive(2) child from master', () => {
|
||||
const child4 = master.derive(2);
|
||||
assert.strictEqual(child4.toBase58(), vectors.child4_priv);
|
||||
assert.strictEqual(child4.toPublic().toBase58(), vectors.child4_pub);
|
||||
assert.strictEqual(child4.toBase58('main'), vectors.child4_priv);
|
||||
assert.strictEqual(child4.toPublic().toBase58('main'), vectors.child4_pub);
|
||||
child = child4;
|
||||
});
|
||||
|
||||
it('should derive(0) child from child(2)', () => {
|
||||
const child5 = child.derive(0);
|
||||
assert.strictEqual(child5.toBase58(), vectors.child5_priv);
|
||||
assert.strictEqual(child5.toPublic().toBase58(), vectors.child5_pub);
|
||||
assert.strictEqual(child5.toBase58('main'), vectors.child5_priv);
|
||||
assert.strictEqual(child5.toPublic().toBase58('main'), vectors.child5_pub);
|
||||
});
|
||||
|
||||
it('should derive(1) child from child(2)', () => {
|
||||
const child6 = child.derive(1);
|
||||
assert.strictEqual(child6.toBase58(), vectors.child6_priv);
|
||||
assert.strictEqual(child6.toPublic().toBase58(), vectors.child6_pub);
|
||||
assert.strictEqual(child6.toBase58('main'), vectors.child6_priv);
|
||||
assert.strictEqual(child6.toPublic().toBase58('main'), vectors.child6_pub);
|
||||
});
|
||||
|
||||
it('should derive correctly when private key has leading zeros', () => {
|
||||
const key = HD.PrivateKey.fromBase58(vectors.zero_priv);
|
||||
const key = HD.PrivateKey.fromBase58(vectors.zero_priv, 'main');
|
||||
|
||||
assert.strictEqual(key.privateKey.toString('hex'),
|
||||
'00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd');
|
||||
@ -82,17 +82,19 @@ describe('HD', function() {
|
||||
});
|
||||
|
||||
it('should deserialize master private key', () => {
|
||||
HD.PrivateKey.fromBase58(master.toBase58());
|
||||
HD.PrivateKey.fromBase58(master.toBase58('main'), 'main');
|
||||
});
|
||||
|
||||
it('should deserialize master public key', () => {
|
||||
HD.PublicKey.fromBase58(master.toPublic().toBase58());
|
||||
HD.PublicKey.fromBase58(master.toPublic().toBase58('main'), 'main');
|
||||
});
|
||||
|
||||
it('should deserialize and reserialize json', () => {
|
||||
const key = HD.generate();
|
||||
const json = key.toJSON();
|
||||
base58Equal(HD.fromJSON(json).toBase58(), key.toBase58());
|
||||
base58Equal(
|
||||
HD.fromJSON(json, 'main').toBase58('main'),
|
||||
key.toBase58('main'));
|
||||
});
|
||||
|
||||
for (const vector of [vector1, vector2]) {
|
||||
@ -103,8 +105,8 @@ describe('HD', function() {
|
||||
const key = HD.PrivateKey.fromSeed(seed);
|
||||
const pub = key.toPublic();
|
||||
|
||||
base58Equal(key.toBase58(), vector.m.prv);
|
||||
base58Equal(pub.toBase58(), vector.m.pub);
|
||||
base58Equal(key.toBase58('main'), vector.m.prv);
|
||||
base58Equal(pub.toBase58('main'), vector.m.pub);
|
||||
|
||||
master = key;
|
||||
});
|
||||
@ -118,8 +120,8 @@ describe('HD', function() {
|
||||
it(`should derive ${path} from master`, () => {
|
||||
const key = master.derivePath(path);
|
||||
const pub = key.toPublic();
|
||||
base58Equal(key.toBase58(), kp.prv);
|
||||
base58Equal(pub.toBase58(), kp.pub);
|
||||
base58Equal(key.toBase58('main'), kp.prv);
|
||||
base58Equal(pub.toBase58('main'), kp.pub);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,10 +60,10 @@ describe('HTTP', function() {
|
||||
it('should get wallet info', async () => {
|
||||
const info = await wallet.getInfo();
|
||||
assert.strictEqual(info.id, 'test');
|
||||
assert.typeOf(info.account, 'object');
|
||||
const str = info.account.receiveAddress;
|
||||
const acct = await wallet.getAccount('default');
|
||||
const str = acct.receiveAddress;
|
||||
assert.typeOf(str, 'string');
|
||||
addr = Address.fromString(str);
|
||||
addr = Address.fromString(str, node.network);
|
||||
});
|
||||
|
||||
it('should fill with funds', async () => {
|
||||
@ -95,7 +95,7 @@ describe('HTTP', function() {
|
||||
await co.timeout(300);
|
||||
|
||||
assert(receive);
|
||||
assert.strictEqual(receive.id, 'test');
|
||||
assert.strictEqual(receive.name, 'default');
|
||||
assert.strictEqual(receive.type, 'pubkeyhash');
|
||||
assert.strictEqual(receive.branch, 0);
|
||||
assert(balance);
|
||||
@ -116,7 +116,7 @@ describe('HTTP', function() {
|
||||
rate: 10000,
|
||||
outputs: [{
|
||||
value: 10000,
|
||||
address: addr.toString()
|
||||
address: addr.toString(node.network)
|
||||
}]
|
||||
};
|
||||
|
||||
@ -232,11 +232,11 @@ describe('HTTP', function() {
|
||||
|
||||
it('should validate an address', async () => {
|
||||
const json = await wallet.client.rpc.execute('validateaddress', [
|
||||
addr.toString()
|
||||
addr.toString(node.network)
|
||||
]);
|
||||
assert.deepStrictEqual(json, {
|
||||
isvalid: true,
|
||||
address: addr.toString(),
|
||||
address: addr.toString(node.network),
|
||||
scriptPubKey: Script.fromAddress(addr).toRaw().toString('hex'),
|
||||
ismine: false,
|
||||
iswatchonly: false
|
||||
|
||||
@ -51,7 +51,7 @@ describe('Input', function() {
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const addr = input.getAddress().toBase58();
|
||||
const addr = input.getAddress().toBase58('main');
|
||||
const prevout = input.prevout.toRaw();
|
||||
|
||||
assert.strictEqual(type, 'pubkeyhash');
|
||||
@ -100,7 +100,7 @@ describe('Input', function() {
|
||||
|
||||
const type = input.getType();
|
||||
const subtype = input.getSubtype();
|
||||
const addr = input.getAddress().toBase58();
|
||||
const addr = input.getAddress().toBase58('main');
|
||||
const prevout = input.prevout.toRaw();
|
||||
const redeem = input.getRedeem().toRaw();
|
||||
|
||||
|
||||
@ -7,10 +7,10 @@ const assert = require('./util/assert');
|
||||
const KeyRing = require('../lib/primitives/keyring');
|
||||
|
||||
const uncompressed = KeyRing.fromSecret(
|
||||
'5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss');
|
||||
'5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', 'main');
|
||||
|
||||
const compressed = KeyRing.fromSecret(
|
||||
'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1');
|
||||
'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1', 'main');
|
||||
|
||||
describe('KeyRing', function() {
|
||||
it('should get uncompressed public key', () => {
|
||||
@ -23,13 +23,13 @@ describe('KeyRing', function() {
|
||||
it('should get uncompressed public key address', () => {
|
||||
assert.strictEqual(
|
||||
'1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN',
|
||||
uncompressed.getKeyAddress('base58'));
|
||||
uncompressed.getKeyAddress('base58', 'main'));
|
||||
});
|
||||
|
||||
it('should get uncompressed WIF', () => {
|
||||
assert.strictEqual(
|
||||
'5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss',
|
||||
uncompressed.toSecret());
|
||||
uncompressed.toSecret('main'));
|
||||
});
|
||||
|
||||
it('should get compressed public key', () => {
|
||||
@ -41,12 +41,12 @@ describe('KeyRing', function() {
|
||||
it('should get compressed public key address', () => {
|
||||
assert.strictEqual(
|
||||
'1F3sAm6ZtwLAUnj7d38pGFxtP3RVEvtsbV',
|
||||
compressed.getKeyAddress('base58'));
|
||||
compressed.getKeyAddress('base58', 'main'));
|
||||
});
|
||||
|
||||
it('should get compressed WIF', () => {
|
||||
assert.strictEqual(
|
||||
'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1',
|
||||
compressed.toSecret());
|
||||
compressed.toSecret('main'));
|
||||
});
|
||||
});
|
||||
|
||||
@ -36,7 +36,7 @@ describe('Mnemonic', function() {
|
||||
assert.bufferEqual(mnemonic.toSeed(), seed);
|
||||
|
||||
const key = HDPrivateKey.fromMnemonic(mnemonic);
|
||||
assert.strictEqual(key.toBase58(), xpriv);
|
||||
assert.strictEqual(key.toBase58('main'), xpriv);
|
||||
});
|
||||
|
||||
it(`should create a ${language} mnemonic from phrase (${i})`, () => {
|
||||
@ -51,7 +51,7 @@ describe('Mnemonic', function() {
|
||||
assert.bufferEqual(mnemonic.toSeed(), seed);
|
||||
|
||||
const key = HDPrivateKey.fromMnemonic(mnemonic);
|
||||
assert.strictEqual(key.toBase58(), xpriv);
|
||||
assert.strictEqual(key.toBase58('main'), xpriv);
|
||||
});
|
||||
|
||||
i += 1;
|
||||
|
||||
@ -551,17 +551,15 @@ describe('Node', function() {
|
||||
it('should validate an address', async () => {
|
||||
const addr = new Address();
|
||||
|
||||
addr.network = node.network;
|
||||
|
||||
const json = await node.rpc.call({
|
||||
method: 'validateaddress',
|
||||
params: [addr.toString()]
|
||||
params: [addr.toString(node.network)]
|
||||
}, {});
|
||||
|
||||
assert.deepStrictEqual(json.result, {
|
||||
isvalid: true,
|
||||
address: addr.toString(),
|
||||
scriptPubKey: Script.fromAddress(addr).toJSON(),
|
||||
address: addr.toString(node.network),
|
||||
scriptPubKey: Script.fromAddress(addr, node.network).toJSON(),
|
||||
ismine: false,
|
||||
iswatchonly: false
|
||||
});
|
||||
|
||||
@ -87,8 +87,10 @@ MemWallet.prototype.init = function init() {
|
||||
if (!this.master)
|
||||
this.master = HD.PrivateKey.generate();
|
||||
|
||||
if (!this.key)
|
||||
this.key = this.master.deriveAccount(44, this.account);
|
||||
if (!this.key) {
|
||||
const type = this.network.keyPrefix.coinType;
|
||||
this.key = this.master.deriveAccount(44, type, this.account);
|
||||
}
|
||||
|
||||
i = this.receiveDepth;
|
||||
while (i--)
|
||||
@ -132,7 +134,8 @@ MemWallet.prototype.derivePath = function derivePath(path) {
|
||||
};
|
||||
|
||||
MemWallet.prototype.deriveKey = function deriveKey(branch, index) {
|
||||
let key = this.master.deriveAccount(44, this.account);
|
||||
const type = this.network.keyPrefix.coinType;
|
||||
let key = this.master.deriveAccount(44, type, this.account);
|
||||
key = key.derive(branch).derive(index);
|
||||
const ring = new KeyRing({
|
||||
network: this.network,
|
||||
|
||||
@ -73,7 +73,7 @@ async function testP2PKH(witness, nesting) {
|
||||
const wallet = await wdb.create({ witness });
|
||||
|
||||
const waddr = await wallet.receiveAddress();
|
||||
const addr = Address.fromString(waddr.toString());
|
||||
const addr = Address.fromString(waddr.toString(wdb.network), wdb.network);
|
||||
|
||||
assert.strictEqual(addr.type, type);
|
||||
assert.strictEqual(addr.type, waddr.type);
|
||||
@ -235,19 +235,19 @@ describe('Wallet', function() {
|
||||
const addr1 = await wallet.receiveAddress();
|
||||
assert(addr1);
|
||||
|
||||
const str = addr1.toString();
|
||||
const addr2 = Address.fromString(str);
|
||||
const str = addr1.toString(wdb.network);
|
||||
const addr2 = Address.fromString(str, wdb.network);
|
||||
|
||||
assert(addr2.equals(addr1));
|
||||
});
|
||||
|
||||
it('should validate existing address', () => {
|
||||
assert(Address.fromString('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
|
||||
assert(Address.fromString('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc', 'main'));
|
||||
});
|
||||
|
||||
it('should fail to validate invalid address', () => {
|
||||
assert.throws(() => {
|
||||
Address.fromString('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc');
|
||||
Address.fromString('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc', 'main');
|
||||
});
|
||||
});
|
||||
|
||||
@ -277,7 +277,7 @@ describe('Wallet', function() {
|
||||
});
|
||||
|
||||
const xpriv = HD.PrivateKey.generate();
|
||||
const key = xpriv.deriveAccount(44, 0).toPublic();
|
||||
const key = xpriv.deriveAccount(44, 0, 0).toPublic();
|
||||
|
||||
await wallet.addSharedKey(0, key);
|
||||
|
||||
@ -1303,7 +1303,7 @@ describe('Wallet', function() {
|
||||
const details = await wallet.toDetails(txs);
|
||||
|
||||
assert(details.some((tx) => {
|
||||
return tx.toJSON().outputs[0].path.name === 'foo';
|
||||
return tx.toJSON(wdb.network).outputs[0].path.name === 'foo';
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user