network: add more helper functions.
This commit is contained in:
parent
2997333122
commit
11a660aeab
41
lib/hd/hd.js
41
lib/hd/hd.js
@ -82,25 +82,14 @@ HD.fromJSON = function fromJSON(json, network) {
|
||||
/**
|
||||
* Instantiate an HD key from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @param {Network?} network
|
||||
* @returns {HDPrivateKey|HDPublicKey}
|
||||
*/
|
||||
|
||||
HD.fromRaw = function fromRaw(data) {
|
||||
if (HDPrivateKey.isRaw(data))
|
||||
return HDPrivateKey.fromRaw(data);
|
||||
return HDPublicKey.fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate HD key from extended serialized data.
|
||||
* @param {Buffer} data
|
||||
* @returns {HDPrivateKey|HDPublicKey}
|
||||
*/
|
||||
|
||||
HD.fromExtended = function fromExtended(data) {
|
||||
if (HDPrivateKey.isRaw(data))
|
||||
return HDPrivateKey.fromExtended(data);
|
||||
return HDPublicKey.fromRaw(data);
|
||||
HD.fromRaw = function fromRaw(data, network) {
|
||||
if (HDPrivateKey.isRaw(data, network))
|
||||
return HDPrivateKey.fromRaw(data, network);
|
||||
return HDPublicKey.fromRaw(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -117,11 +106,11 @@ HD.from = function from(options, network) {
|
||||
if (HD.isHD(options))
|
||||
return options;
|
||||
|
||||
if (HD.isBase58(options))
|
||||
if (HD.isBase58(options, network))
|
||||
return HD.fromBase58(options, network);
|
||||
|
||||
if (HD.isRaw(options))
|
||||
return HD.fromRaw(options);
|
||||
if (HD.isRaw(options, network))
|
||||
return HD.fromRaw(options, network);
|
||||
|
||||
if (options && typeof options === 'object')
|
||||
return HD.fromMnemonic(options, network);
|
||||
@ -132,23 +121,25 @@ HD.from = function from(options, network) {
|
||||
/**
|
||||
* Test whether an object is in the form of a base58 hd key.
|
||||
* @param {String} data
|
||||
* @param {Network?} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HD.isBase58 = function isBase58(data) {
|
||||
return HDPrivateKey.isBase58(data)
|
||||
|| HDPublicKey.isBase58(data);
|
||||
HD.isBase58 = function isBase58(data, network) {
|
||||
return HDPrivateKey.isBase58(data, network)
|
||||
|| HDPublicKey.isBase58(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether an object is in the form of a serialized hd key.
|
||||
* @param {Buffer} data
|
||||
* @param {Network?} network
|
||||
* @returns {NetworkType}
|
||||
*/
|
||||
|
||||
HD.isRaw = function isRaw(data) {
|
||||
return HDPrivateKey.isRaw(data)
|
||||
|| HDPublicKey.isRaw(data);
|
||||
HD.isRaw = function isRaw(data, network) {
|
||||
return HDPrivateKey.isRaw(data, network)
|
||||
|| HDPublicKey.isRaw(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -10,7 +10,6 @@ var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var ec = require('../crypto/ec');
|
||||
var networks = require('../protocol/networks');
|
||||
var Network = require('../protocol/network');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var BufferReader = require('../utils/reader');
|
||||
@ -142,18 +141,6 @@ HDPrivateKey.prototype.xpubkey = function xpubkey() {
|
||||
return this.toPublic().xpubkey();
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify network.
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.verifyNetwork = function verifyNetwork(network) {
|
||||
network = Network.get(network);
|
||||
return this.network.keyPrefix.xprivkey === network.keyPrefix.xprivkey
|
||||
&& this.network.keyPrefix.coinType === network.keyPrefix.coinType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the key (zeroes chain code, privkey, and pubkey).
|
||||
* @param {Boolean} pub - Destroy hd public key as well.
|
||||
@ -189,19 +176,11 @@ HDPrivateKey.prototype.destroy = function destroy(pub) {
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
var bw, id, data, hash, left, right, key, child;
|
||||
|
||||
if (typeof hardened !== 'boolean') {
|
||||
cache = hardened;
|
||||
hardened = false;
|
||||
}
|
||||
|
||||
if (!cache)
|
||||
cache = common.cache;
|
||||
|
||||
if (typeof index === 'string')
|
||||
return this.derivePath(index, cache);
|
||||
return this.derivePath(index);
|
||||
|
||||
hardened = index >= common.HARDENED ? true : hardened;
|
||||
|
||||
@ -214,12 +193,11 @@ HDPrivateKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
if (this.depth >= 0xff)
|
||||
throw new Error('Depth too high.');
|
||||
|
||||
if (cache) {
|
||||
id = this.getID(index);
|
||||
child = cache.get(id);
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
id = this.getID(index);
|
||||
child = common.cache.get(id);
|
||||
|
||||
if (child)
|
||||
return child;
|
||||
|
||||
bw = new StaticWriter(37);
|
||||
|
||||
@ -241,7 +219,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
try {
|
||||
key = ec.privateKeyTweakAdd(this.privateKey, left);
|
||||
} catch (e) {
|
||||
return this.derive(index + 1, cache);
|
||||
return this.derive(index + 1);
|
||||
}
|
||||
|
||||
if (!this.fingerPrint)
|
||||
@ -256,8 +234,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
child.privateKey = key;
|
||||
child.publicKey = ec.publicKeyCreate(key, true);
|
||||
|
||||
if (cache)
|
||||
cache.set(id, child);
|
||||
common.cache.set(id, child);
|
||||
|
||||
return child;
|
||||
};
|
||||
@ -282,13 +259,13 @@ HDPrivateKey.prototype.getID = function getID(index) {
|
||||
* @throws Error if key is not a master key.
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex, cache) {
|
||||
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex) {
|
||||
assert(util.isNumber(accountIndex), 'Account index must be a number.');
|
||||
assert(this.isMaster(), 'Cannot derive account index.');
|
||||
return this
|
||||
.derive(44, true, cache)
|
||||
.derive(this.network.keyPrefix.coinType, true, cache)
|
||||
.derive(accountIndex, true, cache);
|
||||
.derive(44, true)
|
||||
.derive(this.network.keyPrefix.coinType, true)
|
||||
.derive(accountIndex, true);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -296,9 +273,9 @@ HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex,
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45(cache) {
|
||||
HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() {
|
||||
assert(this.isMaster(), 'Cannot derive purpose 45.');
|
||||
return this.derive(45, true, cache);
|
||||
return this.derive(45, true);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -332,33 +309,38 @@ HDPrivateKey.prototype.isPurpose45 = function isPurpose45() {
|
||||
/**
|
||||
* Test whether an object is in the form of a base58 xprivkey.
|
||||
* @param {String} data
|
||||
* @param {Network?} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.isBase58 = function isBase58(data) {
|
||||
var i, type, prefix;
|
||||
HDPrivateKey.isBase58 = function isBase58(data, network) {
|
||||
var prefix;
|
||||
|
||||
if (typeof data !== 'string')
|
||||
return false;
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xprivkey58;
|
||||
if (data.indexOf(prefix) === 0)
|
||||
return true;
|
||||
}
|
||||
if (data.length < 4)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
prefix = data.substring(0, 4);
|
||||
|
||||
try {
|
||||
Network.fromPrivate58(prefix, network);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a buffer has a valid network prefix.
|
||||
* @param {Buffer} data
|
||||
* @returns {NetworkType}
|
||||
* @param {Network?} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.isRaw = function isRaw(data) {
|
||||
var i, version, prefix, type;
|
||||
HDPrivateKey.isRaw = function isRaw(data, network) {
|
||||
var version;
|
||||
|
||||
if (!Buffer.isBuffer(data))
|
||||
return false;
|
||||
@ -368,14 +350,12 @@ HDPrivateKey.isRaw = function isRaw(data) {
|
||||
|
||||
version = data.readUInt32BE(0, true);
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xprivkey;
|
||||
if (version === prefix)
|
||||
return type;
|
||||
try {
|
||||
Network.fromPrivate(version, network);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -404,13 +384,13 @@ HDPrivateKey.isValidPath = function isValidPath(path) {
|
||||
* @throws Error if `path` is not a valid path.
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.derivePath = function derivePath(path, cache) {
|
||||
HDPrivateKey.prototype.derivePath = function derivePath(path) {
|
||||
var indexes = common.parsePath(path, common.MAX_INDEX);
|
||||
var key = this;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < indexes.length; i++)
|
||||
key = key.derive(indexes[i], cache);
|
||||
key = key.derive(indexes[i]);
|
||||
|
||||
return key;
|
||||
};
|
||||
@ -530,8 +510,7 @@ HDPrivateKey.fromSeed = function fromSeed(seed, network) {
|
||||
|
||||
HDPrivateKey.prototype.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
||||
assert(mnemonic instanceof Mnemonic);
|
||||
this.fromSeed(mnemonic.toSeed(), network);
|
||||
return this;
|
||||
return this.fromSeed(mnemonic.toSeed(), network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -622,42 +601,31 @@ HDPrivateKey.generate = function generate(network) {
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
this.fromRaw(base58.decode(xkey));
|
||||
assert(typeof xkey === 'string');
|
||||
this._xprivkey = xkey;
|
||||
if (network && !this.verifyNetwork(network))
|
||||
throw new Error('Network mismatch for HD private key.');
|
||||
return this;
|
||||
return this.fromRaw(base58.decode(xkey), network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromReader = function fromReader(br) {
|
||||
var i, version, type, prefix;
|
||||
HDPrivateKey.prototype.fromReader = function fromReader(br, network) {
|
||||
var version = br.readU32BE();
|
||||
|
||||
version = br.readU32BE();
|
||||
this.network = Network.fromPrivate(version, network);
|
||||
this.depth = br.readU8();
|
||||
this.parentFingerPrint = br.readBytes(4);
|
||||
this.childIndex = br.readU32BE();
|
||||
this.chainCode = br.readBytes(32);
|
||||
br.readU8();
|
||||
this.privateKey = br.readBytes(32);
|
||||
br.verifyChecksum();
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xprivkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Network not found.');
|
||||
|
||||
this.publicKey = ec.publicKeyCreate(this.privateKey, true);
|
||||
this.network = Network.get(type);
|
||||
|
||||
br.verifyChecksum();
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -666,10 +634,11 @@ HDPrivateKey.prototype.fromReader = function fromReader(br) {
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this.fromReader(new BufferReader(raw));
|
||||
HDPrivateKey.prototype.fromRaw = function fromRaw(raw, network) {
|
||||
return this.fromReader(new BufferReader(raw), network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -739,21 +708,23 @@ HDPrivateKey.fromBase58 = function fromBase58(xkey, network) {
|
||||
/**
|
||||
* Instantiate key from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromReader = function fromReader(br) {
|
||||
return new HDPrivateKey().fromReader(br);
|
||||
HDPrivateKey.fromReader = function fromReader(br, network) {
|
||||
return new HDPrivateKey().fromReader(br, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromRaw = function fromRaw(raw) {
|
||||
return new HDPrivateKey().fromRaw(raw);
|
||||
HDPrivateKey.fromRaw = function fromRaw(raw, network) {
|
||||
return new HDPrivateKey().fromRaw(raw, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -803,7 +774,7 @@ HDPrivateKey.isHDPrivateKey = function isHDPrivateKey(obj) {
|
||||
return obj
|
||||
&& typeof obj.derive === 'function'
|
||||
&& typeof obj.fromMnemonic === 'function'
|
||||
&& obj.chainCode !== undefined;
|
||||
&& Buffer.isBuffer(obj.chainCode);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
137
lib/hd/public.js
137
lib/hd/public.js
@ -10,7 +10,6 @@ var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var ec = require('../crypto/ec');
|
||||
var networks = require('../protocol/networks');
|
||||
var Network = require('../protocol/network');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var BufferReader = require('../utils/reader');
|
||||
@ -121,18 +120,6 @@ HDPublicKey.prototype.xpubkey = function() {
|
||||
return this._xpubkey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify network.
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.verifyNetwork = function verifyNetwork(network) {
|
||||
network = Network.get(network);
|
||||
return this.network.keyPrefix.xpubkey === network.keyPrefix.xpubkey
|
||||
&& this.network.keyPrefix.coinType === network.keyPrefix.coinType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the key (zeroes chain code and pubkey).
|
||||
*/
|
||||
@ -162,19 +149,11 @@ HDPublicKey.prototype.destroy = function destroy() {
|
||||
* @throws on `hardened`
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
var bw, id, data, hash, left, right, key, child;
|
||||
|
||||
if (typeof hardened !== 'boolean') {
|
||||
cache = hardened;
|
||||
hardened = false;
|
||||
}
|
||||
|
||||
if (!cache)
|
||||
cache = common.cache;
|
||||
|
||||
if (typeof index === 'string')
|
||||
return this.derivePath(index, cache);
|
||||
return this.derivePath(index);
|
||||
|
||||
if (index >= common.HARDENED || hardened)
|
||||
throw new Error('Index out of range.');
|
||||
@ -185,12 +164,11 @@ HDPublicKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
if (this.depth >= 0xff)
|
||||
throw new Error('Depth too high.');
|
||||
|
||||
if (cache) {
|
||||
id = this.getID(index);
|
||||
child = cache.get(id);
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
id = this.getID(index);
|
||||
child = common.cache.get(id);
|
||||
|
||||
if (child)
|
||||
return child;
|
||||
|
||||
bw = new StaticWriter(37);
|
||||
bw.writeBytes(this.publicKey);
|
||||
@ -204,7 +182,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
try {
|
||||
key = ec.publicKeyTweakAdd(this.publicKey, left, true);
|
||||
} catch (e) {
|
||||
return this.derive(index + 1, cache);
|
||||
return this.derive(index + 1);
|
||||
}
|
||||
|
||||
if (!this.fingerPrint)
|
||||
@ -218,8 +196,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened, cache) {
|
||||
child.chainCode = right;
|
||||
child.publicKey = key;
|
||||
|
||||
if (cache)
|
||||
cache.set(id, child);
|
||||
common.cache.set(id, child);
|
||||
|
||||
return child;
|
||||
};
|
||||
@ -320,13 +297,13 @@ HDPublicKey.isValidPath = function isValidPath(path) {
|
||||
* @throws Error if hardened.
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.derivePath = function derivePath(path, cache) {
|
||||
HDPublicKey.prototype.derivePath = function derivePath(path) {
|
||||
var indexes = common.parsePath(path, common.HARDENED);
|
||||
var key = this;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < indexes.length; i++)
|
||||
key = key.derive(indexes[i], cache);
|
||||
key = key.derive(indexes[i]);
|
||||
|
||||
return key;
|
||||
};
|
||||
@ -427,47 +404,53 @@ HDPublicKey.fromJSON = function fromJSON(json, network) {
|
||||
/**
|
||||
* Test whether an object is in the form of a base58 xpubkey.
|
||||
* @param {String} data
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPublicKey.isBase58 = function isBase58(data) {
|
||||
var i, type, prefix;
|
||||
HDPublicKey.isBase58 = function isBase58(data, network) {
|
||||
var prefix;
|
||||
|
||||
if (typeof data !== 'string')
|
||||
return false;
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xpubkey58;
|
||||
if (data.indexOf(prefix) === 0)
|
||||
return true;
|
||||
}
|
||||
if (data.length < 4)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
prefix = data.substring(0, 4);
|
||||
|
||||
try {
|
||||
Network.fromPublic58(prefix, network);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a buffer has a valid network prefix.
|
||||
* @param {Buffer} data
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {NetworkType}
|
||||
*/
|
||||
|
||||
HDPublicKey.isRaw = function isRaw(data) {
|
||||
var i, version, prefix, type;
|
||||
HDPublicKey.isRaw = function isRaw(data, network) {
|
||||
var version;
|
||||
|
||||
if (!Buffer.isBuffer(data))
|
||||
return false;
|
||||
|
||||
if (data.length < 4)
|
||||
return false;
|
||||
|
||||
version = data.readUInt32BE(0, true);
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xpubkey;
|
||||
if (version === prefix)
|
||||
return type;
|
||||
try {
|
||||
Network.fromPublic(version, network);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -478,41 +461,30 @@ HDPublicKey.isRaw = function isRaw(data) {
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.fromBase58 = function fromBase58(xkey, network) {
|
||||
this.fromRaw(base58.decode(xkey));
|
||||
assert(typeof xkey === 'string');
|
||||
this._xpubkey = xkey;
|
||||
if (network && !this.verifyNetwork(network))
|
||||
throw new Error('Network mismatch for HD public key.');
|
||||
return this;
|
||||
return this.fromRaw(base58.decode(xkey), network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.fromReader = function fromReader(br) {
|
||||
var i, version, type, prefix;
|
||||
HDPublicKey.prototype.fromReader = function fromReader(br, network) {
|
||||
var version = br.readU32BE();
|
||||
|
||||
version = br.readU32BE();
|
||||
this.network = Network.fromPublic(version, network);
|
||||
this.depth = br.readU8();
|
||||
this.parentFingerPrint = br.readBytes(4);
|
||||
this.childIndex = br.readU32BE();
|
||||
this.chainCode = br.readBytes(32);
|
||||
this.publicKey = br.readBytes(33);
|
||||
|
||||
br.verifyChecksum();
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.xpubkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Network not found.');
|
||||
|
||||
this.network = Network.get(type);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -520,15 +492,16 @@ HDPublicKey.prototype.fromReader = function fromReader(br) {
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this.fromReader(new BufferReader(raw));
|
||||
HDPublicKey.prototype.fromRaw = function fromRaw(raw, network) {
|
||||
return this.fromReader(new BufferReader(raw), network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize key data to base58 extended key.
|
||||
* @param {Network|String} network
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
@ -539,7 +512,7 @@ HDPublicKey.prototype.toBase58 = function toBase58(network) {
|
||||
/**
|
||||
* Write the key to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
* @param {Network|NetworkType} network
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.toWriter = function toWriter(bw, network) {
|
||||
@ -570,7 +543,7 @@ HDPublicKey.prototype.getSize = function getSize() {
|
||||
|
||||
/**
|
||||
* Serialize the key.
|
||||
* @param {Network|NetworkType} network
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
@ -592,21 +565,23 @@ HDPublicKey.fromBase58 = function fromBase58(xkey, network) {
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {BufferReader} br
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPublicKey}
|
||||
*/
|
||||
|
||||
HDPublicKey.fromReader = function fromReader(br) {
|
||||
return new HDPublicKey().fromReader(br);
|
||||
HDPublicKey.fromReader = function fromReader(br, network) {
|
||||
return new HDPublicKey().fromReader(br, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {Buffer} raw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {HDPublicKey}
|
||||
*/
|
||||
|
||||
HDPublicKey.fromRaw = function fromRaw(data) {
|
||||
return new HDPublicKey().fromRaw(data);
|
||||
HDPublicKey.fromRaw = function fromRaw(data, network) {
|
||||
return new HDPublicKey().fromRaw(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -618,8 +593,8 @@ HDPublicKey.fromRaw = function fromRaw(data) {
|
||||
HDPublicKey.isHDPublicKey = function isHDPublicKey(obj) {
|
||||
return obj
|
||||
&& typeof obj.derive === 'function'
|
||||
&& typeof obj.toExtended !== 'function'
|
||||
&& obj.chainCode !== undefined;
|
||||
&& obj.fromMnemonic === undefined
|
||||
&& Buffer.isBuffer(obj.chainCode);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var Network = require('../protocol/network');
|
||||
var networks = require('../protocol/networks');
|
||||
var encoding = require('../utils/encoding');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
@ -22,12 +21,7 @@ var bech32 = require('../utils/bech32');
|
||||
* Represents an address.
|
||||
* @alias module:primitives.Address
|
||||
* @constructor
|
||||
* @param {Object} options
|
||||
* @param {Buffer|Hash} options.hash - Address hash.
|
||||
* @param {AddressPrefix} options.type - Address type
|
||||
* `{witness,}{pubkeyhash,scripthash}`.
|
||||
* @param {Number} [options.version=-1] - Witness program version.
|
||||
* @param {(Network|NetworkType)?} options.network - Network name.
|
||||
* @param {Object?} options
|
||||
* @property {Buffer} hash
|
||||
* @property {AddressPrefix} type
|
||||
* @property {Number} version
|
||||
@ -105,30 +99,6 @@ Address.prototype.getHash = function getHash(enc) {
|
||||
return this.hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network address prefix for the address.
|
||||
* @param {Network?} network
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Address.prototype.getPrefix = function getPrefix(network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
network = Network.get(network);
|
||||
return Address.getPrefix(this.type, this.hash, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify an address network (compares prefixes).
|
||||
* @param {Network} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Address.prototype.verifyNetwork = function verifyNetwork(network) {
|
||||
assert(network);
|
||||
return this.getPrefix() === this.getPrefix(network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the address is null.
|
||||
* @returns {Boolean}
|
||||
@ -153,13 +123,46 @@ Address.prototype.isNull = function isNull() {
|
||||
|
||||
/**
|
||||
* Get the address type as a string.
|
||||
* @returns {AddressPrefix}
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
Address.prototype.getType = function getType() {
|
||||
return Address.typesByVal[this.type].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network address prefix for the address.
|
||||
* @param {Network?} network
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Address.prototype.getPrefix = function getPrefix(network) {
|
||||
var prefixes;
|
||||
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
prefixes = network.addressPrefix;
|
||||
|
||||
switch (this.type) {
|
||||
case Address.types.PUBKEYHASH:
|
||||
return prefixes.pubkeyhash;
|
||||
case Address.types.SCRIPTHASH:
|
||||
return prefixes.scripthash;
|
||||
case Address.types.WITNESS:
|
||||
if (this.hash.length === 20)
|
||||
return prefixes.witnesspubkeyhash;
|
||||
|
||||
if (this.hash.length === 32)
|
||||
return prefixes.witnessscripthash;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate size of serialized address.
|
||||
* @returns {Number}
|
||||
@ -225,7 +228,7 @@ Address.prototype.toBech32 = function toBech32(network) {
|
||||
var hrp;
|
||||
|
||||
assert(version !== -1,
|
||||
'Cannot convert non-segwit address to bech32.');
|
||||
'Cannot convert non-program address to bech32.');
|
||||
|
||||
if (!network)
|
||||
network = this.network;
|
||||
@ -245,28 +248,18 @@ Address.prototype.toBech32 = function toBech32(network) {
|
||||
*/
|
||||
|
||||
Address.prototype.fromString = function fromString(addr, network) {
|
||||
var i, type, hrp, expect;
|
||||
var hrp;
|
||||
|
||||
assert(typeof addr === 'string');
|
||||
assert(addr.length >= 2);
|
||||
|
||||
hrp = addr.substring(0, 2).toLowerCase();
|
||||
|
||||
if (network) {
|
||||
network = Network.get(network);
|
||||
expect = network.addressPrefix.bech32;
|
||||
if (hrp === expect)
|
||||
return this.fromBech32(addr, network);
|
||||
} else {
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
expect = networks[type].addressPrefix.bech32;
|
||||
if (hrp === expect)
|
||||
return this.fromBech32(addr, type);
|
||||
}
|
||||
try {
|
||||
hrp = addr.substring(0, 2).toLowerCase();
|
||||
network = Network.fromBech32(hrp, network);
|
||||
} catch (e) {
|
||||
return this.fromBase58(addr, network);
|
||||
}
|
||||
|
||||
return this.fromBase58(addr, network);
|
||||
return this.fromBech32(addr, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -312,23 +305,16 @@ Address.prototype.inspect = function inspect() {
|
||||
* @throws Parse error
|
||||
*/
|
||||
|
||||
Address.prototype.fromRaw = function fromRaw(data) {
|
||||
Address.prototype.fromRaw = function fromRaw(data, network) {
|
||||
var br = new BufferReader(data, true);
|
||||
var i, prefix, network, type, version, hash;
|
||||
var prefix, type, version, hash;
|
||||
|
||||
if (data.length > 40)
|
||||
throw new Error('Address is too long.');
|
||||
|
||||
prefix = br.readU8();
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
network = networks[networks.types[i]];
|
||||
type = Address.getType(prefix, network);
|
||||
if (type !== -1)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Unknown address prefix.');
|
||||
network = Network.fromAddress(prefix, network);
|
||||
type = Address.getType(prefix, network);
|
||||
|
||||
if (data.length > 25) {
|
||||
version = br.readU8();
|
||||
@ -351,87 +337,69 @@ Address.prototype.fromRaw = function fromRaw(data) {
|
||||
* @throws Parse error.
|
||||
*/
|
||||
|
||||
Address.fromRaw = function fromRaw(data) {
|
||||
return new Address().fromRaw(data);
|
||||
Address.fromRaw = function fromRaw(data, network) {
|
||||
return new Address().fromRaw(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from base58 address.
|
||||
* @private
|
||||
* @param {Base58Address} str
|
||||
* @param {Base58Address} data
|
||||
* @param {Network?} network
|
||||
* @throws Parse error
|
||||
*/
|
||||
|
||||
Address.prototype.fromBase58 = function fromBase58(str, network) {
|
||||
assert(typeof str === 'string');
|
||||
Address.prototype.fromBase58 = function fromBase58(data, network) {
|
||||
assert(typeof data === 'string');
|
||||
|
||||
if (str.length > 55)
|
||||
if (data.length > 55)
|
||||
throw new Error('Address is too long.');
|
||||
|
||||
this.fromRaw(base58.decode(str));
|
||||
|
||||
if (network && !this.verifyNetwork(network))
|
||||
throw new Error('Network mismatch for address.');
|
||||
|
||||
return this;
|
||||
return this.fromRaw(base58.decode(data), network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an address object from a base58 address.
|
||||
* @param {Base58Address} str
|
||||
* @param {Base58Address} data
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
* @throws Parse error.
|
||||
*/
|
||||
|
||||
Address.fromBase58 = function fromBase58(str, network) {
|
||||
return new Address().fromBase58(str, network);
|
||||
Address.fromBase58 = function fromBase58(data, network) {
|
||||
return new Address().fromBase58(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from bech32 address.
|
||||
* @private
|
||||
* @param {String} str
|
||||
* @param {String} data
|
||||
* @param {Network?} network
|
||||
* @throws Parse error
|
||||
*/
|
||||
|
||||
Address.prototype.fromBech32 = function fromBech32(str, network) {
|
||||
Address.prototype.fromBech32 = function fromBech32(data, network) {
|
||||
var type = Address.types.WITNESS;
|
||||
var i, addr;
|
||||
var addr;
|
||||
|
||||
assert(typeof str === 'string');
|
||||
assert(typeof data === 'string');
|
||||
|
||||
addr = bech32.decode(str);
|
||||
addr = bech32.decode(data);
|
||||
network = Network.fromBech32(addr.hrp, network);
|
||||
|
||||
if (network) {
|
||||
network = Network.get(network);
|
||||
if (addr.hrp !== network.addressPrefix.bech32)
|
||||
throw new Error('Network mismatch for bech32 address.');
|
||||
} else {
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
network = networks[networks.types[i]];
|
||||
if (addr.hrp === network.addressPrefix.bech32)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Unknown bech32 address prefix.');
|
||||
}
|
||||
|
||||
return this.fromHash(addr.hash, type, addr.version, network.type);
|
||||
return this.fromHash(addr.hash, type, addr.version, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an address object from a bech32 address.
|
||||
* @param {String} str
|
||||
* @param {String} data
|
||||
* @param {Network?} network
|
||||
* @returns {Address}
|
||||
* @throws Parse error.
|
||||
*/
|
||||
|
||||
Address.fromBech32 = function fromBech32(str, network) {
|
||||
return new Address().fromBech32(str, network);
|
||||
Address.fromBech32 = function fromBech32(data, network) {
|
||||
return new Address().fromBech32(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -877,37 +845,11 @@ Address.getHash = function getHash(data, enc) {
|
||||
: hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network address prefix for a specified address type.
|
||||
* @param {AddressPrefix} type
|
||||
* @param {Buffer} hash
|
||||
* @param {Network} network
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Address.getPrefix = function getPrefix(type, hash, network) {
|
||||
var prefixes = network.addressPrefix;
|
||||
switch (type) {
|
||||
case Address.types.PUBKEYHASH:
|
||||
return prefixes.pubkeyhash;
|
||||
case Address.types.SCRIPTHASH:
|
||||
return prefixes.scripthash;
|
||||
case Address.types.WITNESS:
|
||||
if (hash.length === 20)
|
||||
return prefixes.witnesspubkeyhash;
|
||||
if (hash.length === 32)
|
||||
return prefixes.witnessscripthash;
|
||||
assert(false, 'No witness prefix defined.');
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an address type for a specified network address prefix.
|
||||
* @param {Number} prefix
|
||||
* @param {Network} network
|
||||
* @returns {AddressPrefix}
|
||||
* @returns {AddressType}
|
||||
*/
|
||||
|
||||
Address.getType = function getType(prefix, network) {
|
||||
@ -922,7 +864,7 @@ Address.getType = function getType(prefix, network) {
|
||||
case prefixes.witnessscripthash:
|
||||
return Address.types.WITNESS;
|
||||
default:
|
||||
return -1;
|
||||
throw new Error('Unknown address prefix.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var encoding = require('../utils/encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var networks = require('../protocol/networks');
|
||||
var Network = require('../protocol/network');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -124,7 +123,7 @@ KeyRing.prototype.refresh = function refresh() {
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {Boolean?} compressed
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromPrivate = function fromPrivate(key, compressed, network) {
|
||||
@ -147,7 +146,7 @@ KeyRing.prototype.fromPrivate = function fromPrivate(key, compressed, network) {
|
||||
* Instantiate keyring from a private key.
|
||||
* @param {Buffer} key
|
||||
* @param {Boolean?} compressed
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
@ -159,7 +158,7 @@ KeyRing.fromPrivate = function fromPrivate(key, compressed, network) {
|
||||
* Inject data from public key.
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromPublic = function fromPublic(key, network) {
|
||||
@ -203,7 +202,7 @@ KeyRing.generate = function(compressed, network) {
|
||||
/**
|
||||
* Instantiate keyring from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
@ -215,7 +214,7 @@ KeyRing.fromPublic = function fromPublic(key, network) {
|
||||
* Inject data from public key.
|
||||
* @private
|
||||
* @param {Buffer} privateKey
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromKey = function fromKey(key, compressed, network) {
|
||||
@ -235,7 +234,7 @@ KeyRing.prototype.fromKey = function fromKey(key, compressed, network) {
|
||||
/**
|
||||
* Instantiate keyring from a public key.
|
||||
* @param {Buffer} publicKey
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
@ -248,7 +247,7 @@ KeyRing.fromKey = function fromKey(key, compressed, network) {
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {Script} script
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromScript = function fromScript(key, script, compressed, network) {
|
||||
@ -269,7 +268,7 @@ KeyRing.prototype.fromScript = function fromScript(key, script, compressed, netw
|
||||
* Instantiate keyring from script.
|
||||
* @param {Buffer} key
|
||||
* @param {Script} script
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @param {(NetworkType|Network)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
@ -302,13 +301,18 @@ KeyRing.prototype.getSecretSize = function getSecretSize() {
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.toSecret = function toSecret() {
|
||||
KeyRing.prototype.toSecret = function toSecret(network) {
|
||||
var size = this.getSecretSize();
|
||||
var bw = new StaticWriter(size);
|
||||
|
||||
assert(this.privateKey, 'Cannot serialize without private key.');
|
||||
|
||||
bw.writeU8(this.network.keyPrefix.privkey);
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = Network.get(network);
|
||||
|
||||
bw.writeU8(network.keyPrefix.privkey);
|
||||
bw.writeBytes(this.privateKey);
|
||||
|
||||
if (this.publicKey.length === 33)
|
||||
@ -323,23 +327,15 @@ KeyRing.prototype.toSecret = function toSecret() {
|
||||
* Inject properties from serialized CBitcoinSecret.
|
||||
* @private
|
||||
* @param {Base58String} secret
|
||||
* @param {Network?} network
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromSecret = function fromSecret(data, network) {
|
||||
var br = new BufferReader(base58.decode(data), true);
|
||||
var i, prefix, version, type, key, compressed;
|
||||
var version, key, compressed;
|
||||
|
||||
version = br.readU8();
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].keyPrefix.privkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Network not found.');
|
||||
network = Network.fromWIF(version, network);
|
||||
|
||||
key = br.readBytes(32);
|
||||
|
||||
@ -352,18 +348,13 @@ KeyRing.prototype.fromSecret = function fromSecret(data, network) {
|
||||
|
||||
br.verifyChecksum();
|
||||
|
||||
this.fromPrivate(key, compressed, type);
|
||||
|
||||
if (network && !this.verifyNetwork(network))
|
||||
throw new Error('Network mismatch for WIF.');
|
||||
|
||||
return this;
|
||||
return this.fromPrivate(key, compressed, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a keyring from a serialized CBitcoinSecret.
|
||||
* @param {Base58String} secret
|
||||
* @param {Network?} network
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
@ -371,17 +362,6 @@ KeyRing.fromSecret = function fromSecret(data, network) {
|
||||
return new KeyRing().fromSecret(data, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify network.
|
||||
* @param {(NetworkType|Network)} network
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.verifyNetwork = function verifyNetwork(network) {
|
||||
network = Network.get(network);
|
||||
return this.network.keyPrefix.privkey === network.keyPrefix.privkey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get private key.
|
||||
* @param {String?} enc - Can be `"hex"`, `"base58"`, or `null`.
|
||||
|
||||
@ -235,22 +235,121 @@ Network.ensure = function ensure(type) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its magic number.
|
||||
* Get a network by an associated comparator.
|
||||
* @private
|
||||
* @param {Object} value
|
||||
* @param {Function} compare
|
||||
* @param {Network|null} network
|
||||
* @param {String} name
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromMagic = function fromMagic(magic) {
|
||||
Network.by = function by(value, compare, network, name) {
|
||||
var i, type;
|
||||
|
||||
if (network) {
|
||||
network = Network.get(network);
|
||||
if (compare(network, value))
|
||||
return network;
|
||||
throw new Error('Network mismatch for ' + name + '.');
|
||||
}
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
if (magic === networks[type].magic)
|
||||
break;
|
||||
network = networks[type];
|
||||
if (compare(network, value))
|
||||
return Network.get(type);
|
||||
}
|
||||
|
||||
assert(i < networks.types.length, 'Network not found.');
|
||||
throw new Error('Network not found for ' + name + '.');
|
||||
};
|
||||
|
||||
return Network.get(type);
|
||||
/**
|
||||
* Get a network by its magic number.
|
||||
* @param {Number} value
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromMagic = function fromMagic(value, network) {
|
||||
return Network.by(value, cmpMagic, network, 'magic number');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its WIF prefix.
|
||||
* @param {Number} value
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromWIF = function fromWIF(prefix, network) {
|
||||
return Network.by(prefix, cmpWIF, network, 'WIF');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its xpubkey prefix.
|
||||
* @param {Number} value
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromPublic = function fromPublic(prefix, network) {
|
||||
return Network.by(prefix, cmpPub, network, 'xpubkey');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its xprivkey prefix.
|
||||
* @param {Number} value
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromPrivate = function fromPrivate(prefix, network) {
|
||||
return Network.by(prefix, cmpPriv, network, 'xprivkey');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its xpubkey base58 prefix.
|
||||
* @param {String} prefix
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromPublic58 = function fromPublic58(prefix, network) {
|
||||
return Network.by(prefix, cmpPub58, network, 'xpubkey');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its xprivkey base58 prefix.
|
||||
* @param {String} prefix
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromPrivate58 = function fromPrivate58(prefix, network) {
|
||||
return Network.by(prefix, cmpPriv58, network, 'xprivkey');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its base58 address prefix.
|
||||
* @param {Number} value
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromAddress = function fromAddress(prefix, network) {
|
||||
return Network.by(prefix, cmpAddress, network, 'base58 address');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network by its bech32 address prefix.
|
||||
* @param {String} hrp
|
||||
* @param {Network?} network
|
||||
* @returns {Network}
|
||||
*/
|
||||
|
||||
Network.fromBech32 = function fromBech32(hrp, network) {
|
||||
return Network.by(hrp, cmpBech32, network, 'bech32 address');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -302,6 +401,48 @@ function cmpNode(a, b) {
|
||||
return a.height - b.height;
|
||||
}
|
||||
|
||||
function cmpMagic(network, magic) {
|
||||
return network.magic === magic;
|
||||
}
|
||||
|
||||
function cmpWIF(network, prefix) {
|
||||
return network.keyPrefix.privkey === prefix;
|
||||
}
|
||||
|
||||
function cmpPub(network, prefix) {
|
||||
return network.keyPrefix.xpubkey === prefix;
|
||||
}
|
||||
|
||||
function cmpPriv(network, prefix) {
|
||||
return network.keyPrefix.xprivkey === prefix;
|
||||
}
|
||||
|
||||
function cmpPub58(network, prefix) {
|
||||
return network.keyPrefix.xpubkey58 === prefix;
|
||||
}
|
||||
|
||||
function cmpPriv58(network, prefix) {
|
||||
return network.keyPrefix.xprivkey58 === prefix;
|
||||
}
|
||||
|
||||
function cmpAddress(network, prefix) {
|
||||
var prefixes = network.addressPrefix;
|
||||
|
||||
switch (prefix) {
|
||||
case prefixes.pubkeyhash:
|
||||
case prefixes.scripthash:
|
||||
case prefixes.witnesspubkeyhash:
|
||||
case prefixes.witnessscripthash:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function cmpBech32(network, hrp) {
|
||||
return network.addressPrefix.bech32 === hrp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user