Change errors
This commit is contained in:
parent
94f3f02210
commit
803027353a
@ -15,6 +15,7 @@ var Point = require('./crypto/point');
|
|||||||
var PrivateKey = require('./privatekey');
|
var PrivateKey = require('./privatekey');
|
||||||
var Random = require('./crypto/random');
|
var Random = require('./crypto/random');
|
||||||
|
|
||||||
|
var inherits = require('inherits');
|
||||||
var bufferUtil = require('./util/buffer');
|
var bufferUtil = require('./util/buffer');
|
||||||
var jsUtil = require('./util/js');
|
var jsUtil = require('./util/js');
|
||||||
|
|
||||||
@ -46,13 +47,13 @@ function HDPrivateKey(arg) {
|
|||||||
} else if (jsUtil.isValidJson(arg)) {
|
} else if (jsUtil.isValidJson(arg)) {
|
||||||
this._buildFromJson(arg);
|
this._buildFromJson(arg);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPrivateKey.getSerializedError(arg));
|
throw HDPrivateKey.getSerializedError(arg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_.isObject(arg)) {
|
if (_.isObject(arg)) {
|
||||||
this._buildFromObject(arg);
|
this._buildFromObject(arg);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPrivateKey.Errors.UnrecognizedArgument);
|
throw new HDPrivateKey.Error.UnrecognizedArgument(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -87,7 +88,7 @@ HDPrivateKey.prototype.derive = function(arg, hardened) {
|
|||||||
} else if (_.isString(arg)) {
|
} else if (_.isString(arg)) {
|
||||||
return this._deriveFromString(arg);
|
return this._deriveFromString(arg);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPrivateKey.Errors.InvalidDerivationArgument);
|
throw new HDPrivateKey.Error.InvalidDerivationArgument(arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ HDPrivateKey.prototype._deriveFromString = function(path) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
if (!_.contains(HDPrivateKey.RootElementAlias, steps[0])) {
|
if (!_.contains(HDPrivateKey.RootElementAlias, steps[0])) {
|
||||||
throw new Error(HDPrivateKey.Errors.InvalidPath);
|
throw new HDPrivateKey.Error.InvalidPath(path);
|
||||||
}
|
}
|
||||||
steps = steps.slice(1);
|
steps = steps.slice(1);
|
||||||
|
|
||||||
@ -171,23 +172,23 @@ HDPrivateKey.isValidSerialized = function(data, network) {
|
|||||||
* @param {string|Buffer} data - the serialized private key
|
* @param {string|Buffer} data - the serialized private key
|
||||||
* @param {string|Network=} network - optional, if present, checks that the
|
* @param {string|Network=} network - optional, if present, checks that the
|
||||||
* network provided matches the network serialized.
|
* network provided matches the network serialized.
|
||||||
* @return {HDPrivateKey.Errors|null}
|
* @return {HDPrivateKey.Error.InvalidArgument|null}
|
||||||
*/
|
*/
|
||||||
HDPrivateKey.getSerializedError = function(data, network) {
|
HDPrivateKey.getSerializedError = function(data, network) {
|
||||||
/* jshint maxcomplexity: 10 */
|
/* jshint maxcomplexity: 10 */
|
||||||
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
||||||
return HDPrivateKey.Errors.InvalidArgument;
|
return new HDPrivateKey.Error.InvalidArgument('Expected string or buffer');
|
||||||
}
|
}
|
||||||
if (!Base58.validCharacters(data)) {
|
if (!Base58.validCharacters(data)) {
|
||||||
return HDPrivateKey.Errors.InvalidB58Char;
|
return new HDPrivateKey.Error.InvalidB58Char('(unknown)', data);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
data = Base58Check.decode(data);
|
data = Base58Check.decode(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return HDPrivateKey.Errors.InvalidB58Checksum;
|
return new HDPrivateKey.Error.InvalidB58Checksum(data);
|
||||||
}
|
}
|
||||||
if (data.length !== 78) {
|
if (data.length !== HDPrivateKey.DataLength) {
|
||||||
return HDPrivateKey.Errors.InvalidLength;
|
return new HDPrivateKey.Error.InvalidLength(data);
|
||||||
}
|
}
|
||||||
if (!_.isUndefined(network)) {
|
if (!_.isUndefined(network)) {
|
||||||
var error = HDPrivateKey._validateNetwork(data, network);
|
var error = HDPrivateKey._validateNetwork(data, network);
|
||||||
@ -198,14 +199,14 @@ HDPrivateKey.getSerializedError = function(data, network) {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
HDPrivateKey._validateNetwork = function(data, network) {
|
HDPrivateKey._validateNetwork = function(data, networkArg) {
|
||||||
network = Network.get(network);
|
var network = Network.get(networkArg);
|
||||||
if (!network) {
|
if (!network) {
|
||||||
return HDPrivateKey.Errors.InvalidNetworkArgument;
|
return new HDPrivateKey.Error.InvalidNetworkArgument(networkArg);
|
||||||
}
|
}
|
||||||
var version = data.slice(0, 4);
|
var version = data.slice(0, 4);
|
||||||
if (bufferUtil.integerFromBuffer(version) !== network.xprivkey) {
|
if (bufferUtil.integerFromBuffer(version) !== network.xprivkey) {
|
||||||
return HDPrivateKey.Errors.InvalidNetwork;
|
return new HDPrivateKey.Error.InvalidNetwork(version);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@ -263,13 +264,13 @@ HDPrivateKey.fromSeed = function(hexa, network) {
|
|||||||
hexa = bufferUtil.hexToBuffer(hexa);
|
hexa = bufferUtil.hexToBuffer(hexa);
|
||||||
}
|
}
|
||||||
if (!Buffer.isBuffer(hexa)) {
|
if (!Buffer.isBuffer(hexa)) {
|
||||||
throw new Error(HDPrivateKey.Errors.InvalidEntropyArg);
|
throw new HDPrivateKey.Error.InvalidEntropyArgument(hexa);
|
||||||
}
|
}
|
||||||
if (hexa.length < MINIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
if (hexa.length < MINIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
||||||
throw new Error(HDPrivateKey.Errors.NotEnoughEntropy);
|
throw new HDPrivateKey.Error.NotEnoughEntropy(hexa);
|
||||||
}
|
}
|
||||||
if (hexa.length > MAXIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
if (hexa.length > MAXIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
||||||
throw new Error(HDPrivateKey.Errors.TooMuchEntropy);
|
throw new HDPrivateKey.Error.TooMuchEntropy(hexa);
|
||||||
}
|
}
|
||||||
var hash = Hash.sha512hmac(hexa, new buffer.Buffer('Bitcoin seed'));
|
var hash = Hash.sha512hmac(hexa, new buffer.Buffer('Bitcoin seed'));
|
||||||
|
|
||||||
@ -310,11 +311,12 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) {
|
|||||||
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
||||||
bufferUtil.emptyBuffer(1), arg.privateKey
|
bufferUtil.emptyBuffer(1), arg.privateKey
|
||||||
];
|
];
|
||||||
|
var concat = buffer.Buffer.concat(sequence);
|
||||||
if (!arg.checksum || !arg.checksum.length) {
|
if (!arg.checksum || !arg.checksum.length) {
|
||||||
arg.checksum = Base58Check.checksum(buffer.Buffer.concat(sequence));
|
arg.checksum = Base58Check.checksum(concat);
|
||||||
} else {
|
} else {
|
||||||
if (arg.checksum.toString() !== Base58Check.checksum(buffer.Buffer.concat(sequence)).toString()) {
|
if (arg.checksum.toString() !== Base58Check.checksum(concat).toString()) {
|
||||||
throw new Error(HDPrivateKey.Errors.InvalidB58Checksum);
|
throw new HDPrivateKey.Error.InvalidB58Checksum(concat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +427,7 @@ HDPrivateKey.ChainCodeSize = 32;
|
|||||||
HDPrivateKey.PrivateKeySize = 32;
|
HDPrivateKey.PrivateKeySize = 32;
|
||||||
HDPrivateKey.CheckSumSize = 4;
|
HDPrivateKey.CheckSumSize = 4;
|
||||||
|
|
||||||
|
HDPrivateKey.DataLength = 78;
|
||||||
HDPrivateKey.SerializedByteSize = 82;
|
HDPrivateKey.SerializedByteSize = 82;
|
||||||
|
|
||||||
HDPrivateKey.VersionStart = 0;
|
HDPrivateKey.VersionStart = 0;
|
||||||
@ -444,22 +447,80 @@ HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.
|
|||||||
|
|
||||||
assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize);
|
assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize);
|
||||||
|
|
||||||
HDPrivateKey.Errors = {};
|
HDPrivateKey.Error = function() {
|
||||||
HDPrivateKey.Errors.InvalidArgument = 'Invalid argument, expected string or Buffer';
|
Error.apply(this, arguments);
|
||||||
HDPrivateKey.Errors.InvalidB58Char = 'Invalid Base 58 character';
|
};
|
||||||
HDPrivateKey.Errors.InvalidB58Checksum = 'Invalid Base 58 checksum';
|
inherits(HDPrivateKey.Error, Error);
|
||||||
HDPrivateKey.Errors.InvalidChildIndex = 'Invalid Child Index - must be a number';
|
|
||||||
HDPrivateKey.Errors.InvalidConstant = 'Unrecognized xprivkey version';
|
HDPrivateKey.Error.InvalidArgument = function(message) {
|
||||||
HDPrivateKey.Errors.InvalidDepth = 'Invalid depth parameter - must be a number';
|
HDPrivateKey.Error.apply(this, arguments);
|
||||||
HDPrivateKey.Errors.InvalidDerivationArgument = 'Invalid argument, expected number and boolean or string';
|
this.message = 'Invalid argument: ' + message;
|
||||||
HDPrivateKey.Errors.InvalidEntropyArg = 'Invalid argument: entropy must be an hexa string or binary buffer';
|
};
|
||||||
HDPrivateKey.Errors.InvalidLength = 'Invalid length for xprivkey format';
|
inherits(HDPrivateKey.Error.InvalidArgument, TypeError);
|
||||||
HDPrivateKey.Errors.InvalidNetwork = 'Unexpected version for network';
|
|
||||||
HDPrivateKey.Errors.InvalidNetworkArgument = 'Network argument must be \'livenet\' or \'testnet\'';
|
HDPrivateKey.Error.InvalidB58Char = function(character, string) {
|
||||||
HDPrivateKey.Errors.InvalidParentFingerPrint = 'Invalid Parent Fingerprint - must be a number';
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
HDPrivateKey.Errors.InvalidPath = 'Invalid path for derivation: must start with "m"';
|
this.message = 'Invalid Base 58 character: ' + character + ' in "' + string + '"';
|
||||||
HDPrivateKey.Errors.NotEnoughEntropy = 'Need more than 128 bytes of entropy';
|
};
|
||||||
HDPrivateKey.Errors.TooMuchEntropy = 'More than 512 bytes of entropy is non standard';
|
inherits(HDPrivateKey.Error.InvalidB58Char, HDPrivateKey.Error.InvalidArgument);
|
||||||
HDPrivateKey.Errors.UnrecognizedArgument = 'Creating a HDPrivateKey requires a string, a buffer, a json, or an object';
|
|
||||||
|
HDPrivateKey.Error.InvalidB58Checksum = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid Base 58 checksum in "' + message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidB58Checksum, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidDerivationArgument = function(args) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid derivation argument "' + args + '", expected number and boolean or string';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidDerivationArgument, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidEntropyArgument = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid argument: entropy must be an hexa string or binary buffer, got ' + typeof message;
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidEntropyArgument, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidLength = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid length for xprivkey format in "' + message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidLength, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidNetwork = function(network) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Unexpected version for network: got ' + network;
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidNetwork, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidNetworkArgument = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Network argument must be \'livenet\' or \'testnet\', got "' + message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidNetworkArgument, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.InvalidPath = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid path for derivation "' + message + '", must start with "m"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.InvalidPath, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.NotEnoughEntropy = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidEntropyArgument.apply(this, arguments);
|
||||||
|
this.message = 'Need more than 128 bytes of entropy, got ' + message.length + ' in "' + message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.NotEnoughEntropy, HDPrivateKey.Error.InvalidEntropyArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.TooMuchEntropy = function(message) {
|
||||||
|
HDPrivateKey.Error.InvalidEntropyArgument.apply(this, arguments);
|
||||||
|
this.message = 'More than 512 bytes of entropy is non standard, got ' + message.length + ' in "' + message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.TooMuchEntropy, HDPrivateKey.Error.InvalidEntropyArgument);
|
||||||
|
|
||||||
|
HDPrivateKey.Error.UnrecognizedArgument = function(message) {
|
||||||
|
this.message = 'Creating a HDPrivateKey requires a string, a buffer, a json, or an object, got "' + message + '" of type "' + typeof message + '"';
|
||||||
|
};
|
||||||
|
inherits(HDPrivateKey.Error.UnrecognizedArgument, HDPrivateKey.Error.InvalidArgument);
|
||||||
|
|
||||||
module.exports = HDPrivateKey;
|
module.exports = HDPrivateKey;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ var Point = require('./crypto/point');
|
|||||||
var PublicKey = require('./publickey');
|
var PublicKey = require('./publickey');
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var inherits = require('inherits');
|
||||||
|
|
||||||
var jsUtil = require('./util/js');
|
var jsUtil = require('./util/js');
|
||||||
var bufferUtil = require('./util/buffer');
|
var bufferUtil = require('./util/buffer');
|
||||||
@ -35,16 +36,16 @@ function HDPublicKey(arg) {
|
|||||||
}
|
}
|
||||||
if (arg) {
|
if (arg) {
|
||||||
if (_.isString(arg) || bufferUtil.isBuffer(arg)) {
|
if (_.isString(arg) || bufferUtil.isBuffer(arg)) {
|
||||||
if (HDPublicKey.isValidSerialized(arg)) {
|
var error = HDPublicKey.getSerializedError(arg);
|
||||||
|
if (!error) {
|
||||||
return this._buildFromSerialized(arg);
|
return this._buildFromSerialized(arg);
|
||||||
} else if (jsUtil.isValidJson(arg)) {
|
} else if (jsUtil.isValidJson(arg)) {
|
||||||
return this._buildFromJson(arg);
|
return this._buildFromJson(arg);
|
||||||
} else {
|
} else {
|
||||||
var error = HDPublicKey.getSerializedError(arg);
|
if (error instanceof HDPublicKey.Error.ArgumentIsPrivateExtended) {
|
||||||
if (error === HDPublicKey.Errors.ArgumentIsPrivateExtended) {
|
|
||||||
return new HDPrivateKey(arg).hdPublicKey;
|
return new HDPrivateKey(arg).hdPublicKey;
|
||||||
}
|
}
|
||||||
throw new Error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_.isObject(arg)) {
|
if (_.isObject(arg)) {
|
||||||
@ -54,11 +55,11 @@ function HDPublicKey(arg) {
|
|||||||
return this._buildFromObject(arg);
|
return this._buildFromObject(arg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPublicKey.Errors.UnrecognizedArgument);
|
throw new HDPublicKey.Error.UnrecognizedArgument(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPublicKey.Errors.MustSupplyArgument);
|
throw new HDPublicKey.Error.MustSupplyArgument();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,13 +90,13 @@ HDPublicKey.prototype.derive = function (arg, hardened) {
|
|||||||
} else if (_.isString(arg)) {
|
} else if (_.isString(arg)) {
|
||||||
return this._deriveFromString(arg);
|
return this._deriveFromString(arg);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPublicKey.Errors.InvalidDerivationArgument);
|
throw new HDPublicKey.Error.InvalidDerivationArgument(arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
HDPublicKey.prototype._deriveWithNumber = function (index, hardened) {
|
HDPublicKey.prototype._deriveWithNumber = function (index, hardened) {
|
||||||
if (hardened || index >= HDPublicKey.Hardened) {
|
if (hardened || index >= HDPublicKey.Hardened) {
|
||||||
throw new Error(HDPublicKey.Errors.InvalidIndexCantDeriveHardened);
|
throw new HDPublicKey.Error.InvalidIndexCantDeriveHardened();
|
||||||
}
|
}
|
||||||
var cached = HDKeyCache.get(this.xpubkey, index, hardened);
|
var cached = HDKeyCache.get(this.xpubkey, index, hardened);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@ -131,7 +132,7 @@ HDPublicKey.prototype._deriveFromString = function (path) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
if (!_.contains(HDPublicKey.RootElementAlias, steps[0])) {
|
if (!_.contains(HDPublicKey.RootElementAlias, steps[0])) {
|
||||||
throw new Error(HDPublicKey.Errors.InvalidPath);
|
throw new HDPublicKey.Error.InvalidPath(path);
|
||||||
}
|
}
|
||||||
steps = steps.slice(1);
|
steps = steps.slice(1);
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ HDPublicKey.prototype._deriveFromString = function (path) {
|
|||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
HDPublicKey.isValidSerialized = function (data, network) {
|
HDPublicKey.isValidSerialized = function (data, network) {
|
||||||
return !HDPublicKey.getSerializedError(data, network);
|
return _.isNull(HDPublicKey.getSerializedError(data, network));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,24 +165,24 @@ HDPublicKey.isValidSerialized = function (data, network) {
|
|||||||
* @param {string|Buffer} data - the serialized private key
|
* @param {string|Buffer} data - the serialized private key
|
||||||
* @param {string|Network=} network - optional, if present, checks that the
|
* @param {string|Network=} network - optional, if present, checks that the
|
||||||
* network provided matches the network serialized.
|
* network provided matches the network serialized.
|
||||||
* @return {HDPublicKey.Errors|null}
|
* @return {HDPublicKey.Error|null}
|
||||||
*/
|
*/
|
||||||
HDPublicKey.getSerializedError = function (data, network) {
|
HDPublicKey.getSerializedError = function (data, network) {
|
||||||
/* jshint maxcomplexity: 10 */
|
/* jshint maxcomplexity: 10 */
|
||||||
/* jshint maxstatements: 20 */
|
/* jshint maxstatements: 20 */
|
||||||
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
||||||
return HDPublicKey.Errors.InvalidArgument;
|
return new HDPublicKey.Error.InvalidArgument('expected buffer or string');
|
||||||
}
|
}
|
||||||
if (!Base58.validCharacters(data)) {
|
if (!Base58.validCharacters(data)) {
|
||||||
return HDPublicKey.Errors.InvalidB58Char;
|
return new HDPublicKey.Error.InvalidB58Char('(unknown)', data);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
data = Base58Check.decode(data);
|
data = Base58Check.decode(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return HDPublicKey.Errors.InvalidB58Checksum;
|
return new HDPublicKey.Error.InvalidB58Checksum(data);
|
||||||
}
|
}
|
||||||
if (data.length !== 78) {
|
if (data.length !== HDPublicKey.DataSize) {
|
||||||
return HDPublicKey.Errors.InvalidLength;
|
return new HDPublicKey.Error.InvalidLength(data);
|
||||||
}
|
}
|
||||||
if (!_.isUndefined(network)) {
|
if (!_.isUndefined(network)) {
|
||||||
var error = HDPublicKey._validateNetwork(data, network);
|
var error = HDPublicKey._validateNetwork(data, network);
|
||||||
@ -191,19 +192,19 @@ HDPublicKey.getSerializedError = function (data, network) {
|
|||||||
}
|
}
|
||||||
network = Network.get(network) || Network.defaultNetwork;
|
network = Network.get(network) || Network.defaultNetwork;
|
||||||
if (bufferUtil.integerFromBuffer(data.slice(0, 4)) === network.xprivkey) {
|
if (bufferUtil.integerFromBuffer(data.slice(0, 4)) === network.xprivkey) {
|
||||||
return HDPublicKey.Errors.ArgumentIsPrivateExtended;
|
return new HDPublicKey.Error.ArgumentIsPrivateExtended();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
HDPublicKey._validateNetwork = function (data, network) {
|
HDPublicKey._validateNetwork = function (data, networkArg) {
|
||||||
network = Network.get(network);
|
var network = Network.get(networkArg);
|
||||||
if (!network) {
|
if (!network) {
|
||||||
return HDPublicKey.Errors.InvalidNetworkArgument;
|
return new HDPublicKey.Error.InvalidNetworkArgument(networkArg);
|
||||||
}
|
}
|
||||||
var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd);
|
var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd);
|
||||||
if (bufferUtil.integerFromBuffer(version) !== network.xpubkey) {
|
if (bufferUtil.integerFromBuffer(version) !== network.xpubkey) {
|
||||||
return HDPublicKey.Errors.InvalidNetwork;
|
return new HDPublicKey.Error.InvalidNetwork(version);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@ -288,7 +289,7 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) {
|
|||||||
arg.checksum = checksum;
|
arg.checksum = checksum;
|
||||||
} else {
|
} else {
|
||||||
if (arg.checksum.toString('hex') !== checksum.toString('hex')) {
|
if (arg.checksum.toString('hex') !== checksum.toString('hex')) {
|
||||||
throw new Error(HDPublicKey.Errors.InvalidB58Checksum);
|
throw new HDPublicKey.Error.InvalidB58Checksum(concat, checksum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,6 +386,7 @@ HDPublicKey.ChainCodeSize = 32;
|
|||||||
HDPublicKey.PublicKeySize = 33;
|
HDPublicKey.PublicKeySize = 33;
|
||||||
HDPublicKey.CheckSumSize = 4;
|
HDPublicKey.CheckSumSize = 4;
|
||||||
|
|
||||||
|
HDPublicKey.DataSize = 78;
|
||||||
HDPublicKey.SerializedByteSize = 82;
|
HDPublicKey.SerializedByteSize = 82;
|
||||||
|
|
||||||
HDPublicKey.VersionStart = 0;
|
HDPublicKey.VersionStart = 0;
|
||||||
@ -402,25 +404,78 @@ HDPublicKey.PublicKeyEnd = HDPublicKey.PublicKeyStart + HDPublicKey.Pu
|
|||||||
HDPublicKey.ChecksumStart = HDPublicKey.PublicKeyEnd;
|
HDPublicKey.ChecksumStart = HDPublicKey.PublicKeyEnd;
|
||||||
HDPublicKey.ChecksumEnd = HDPublicKey.ChecksumStart + HDPublicKey.CheckSumSize;
|
HDPublicKey.ChecksumEnd = HDPublicKey.ChecksumStart + HDPublicKey.CheckSumSize;
|
||||||
|
|
||||||
|
assert(HDPublicKey.PublicKeyEnd === HDPublicKey.DataSize);
|
||||||
assert(HDPublicKey.ChecksumEnd === HDPublicKey.SerializedByteSize);
|
assert(HDPublicKey.ChecksumEnd === HDPublicKey.SerializedByteSize);
|
||||||
|
|
||||||
HDPublicKey.Errors = {};
|
HDPublicKey.Error = function() {
|
||||||
HDPublicKey.Errors.ArgumentIsPrivateExtended = 'Argument starts with xpriv..., it\'s a private key';
|
Error.apply(this, arguments);
|
||||||
HDPublicKey.Errors.InvalidArgument = 'Invalid argument, expected string or Buffer';
|
};
|
||||||
HDPublicKey.Errors.InvalidB58Char = 'Invalid Base 58 character';
|
inherits(HDPublicKey.Error, Error);
|
||||||
HDPublicKey.Errors.InvalidB58Checksum = 'Invalid Base 58 checksum';
|
|
||||||
HDPublicKey.Errors.InvalidChildIndex = 'Invalid Child Index - must be a number';
|
HDPublicKey.Error.InvalidArgument = function() {
|
||||||
HDPublicKey.Errors.InvalidConstant = 'Unrecognized xpubkey version';
|
HDPublicKey.Error.apply(this, arguments);
|
||||||
HDPublicKey.Errors.InvalidDepth = 'Invalid depth parameter - must be a number';
|
this.message = 'Invalid argument';
|
||||||
HDPublicKey.Errors.InvalidDerivationArgument = 'Invalid argument, expected number and boolean or string';
|
};
|
||||||
HDPublicKey.Errors.InvalidEntropyArg = 'Invalid argument: entropy must be an hexa string or binary buffer';
|
inherits(HDPublicKey.Error.InvalidArgument, HDPublicKey.Error);
|
||||||
HDPublicKey.Errors.InvalidLength = 'Invalid length for xpubkey format';
|
|
||||||
HDPublicKey.Errors.InvalidNetwork = 'Unexpected version for network';
|
HDPublicKey.Error.ArgumentIsPrivateExtended = function() {
|
||||||
HDPublicKey.Errors.InvalidNetworkArgument = 'Network argument must be \'livenet\' or \'testnet\'';
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
HDPublicKey.Errors.InvalidParentFingerPrint = 'Invalid Parent Fingerprint - must be a number';
|
this.message = 'Argument starts with xpriv..., it\'s a private key';
|
||||||
HDPublicKey.Errors.InvalidPath = 'Invalid path for derivation: must start with "m"';
|
};
|
||||||
HDPublicKey.Errors.MustSupplyArgument = 'Must supply an argument for the constructor';
|
inherits(HDPublicKey.Error.ArgumentIsPrivateExtended, HDPublicKey.Error.InvalidArgument);
|
||||||
HDPublicKey.Errors.UnrecognizedArgument = 'Creating a HDPublicKey requires a string, a buffer, a json, or an object';
|
|
||||||
|
HDPublicKey.Error.InvalidB58Char = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid Base 58 character';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidB58Char, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidB58Checksum = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid Base 58 checksum';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidB58Checksum, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidDerivationArgument = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid argument, expected number and boolean or string';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidDerivationArgument, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidLength = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid length for xpubkey format';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidLength, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidNetwork = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Unexpected version for network';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidNetwork, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidNetworkArgument = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Network argument must be \'livenet\' or \'testnet\'';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidNetworkArgument, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.InvalidPath = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Invalid path for derivation: must start with "m"';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.InvalidPath, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.MustSupplyArgument = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Must supply an argument for the constructor';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.MustSupplyArgument, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
|
HDPublicKey.Error.UnrecognizedArgument = function() {
|
||||||
|
HDPublicKey.Error.InvalidArgument.apply(this, arguments);
|
||||||
|
this.message = 'Creating a HDPublicKey requires a string, a buffer, a json, or an object';
|
||||||
|
};
|
||||||
|
inherits(HDPublicKey.Error.UnrecognizedArgument, HDPublicKey.Error.InvalidArgument);
|
||||||
|
|
||||||
module.exports = HDPublicKey;
|
module.exports = HDPublicKey;
|
||||||
|
|
||||||
|
|||||||
@ -75,6 +75,7 @@
|
|||||||
"bs58": "=2.0.0",
|
"bs58": "=2.0.0",
|
||||||
"elliptic": "=0.15.14",
|
"elliptic": "=0.15.14",
|
||||||
"hash.js": "=0.3.2",
|
"hash.js": "=0.3.2",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
"lodash": "=2.4.1",
|
"lodash": "=2.4.1",
|
||||||
"sha512": "=0.0.1"
|
"sha512": "=0.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -15,24 +15,41 @@ var json = '{"network":"livenet","depth":0,"fingerPrint":876747070,"parentFinger
|
|||||||
|
|
||||||
describe('HDPrivate key interface', function() {
|
describe('HDPrivate key interface', function() {
|
||||||
/* jshint maxstatements: 50 */
|
/* jshint maxstatements: 50 */
|
||||||
var expectFail = function(argument, error) {
|
var expectFail = function(func, error) {
|
||||||
expect(function() {
|
var got = null;
|
||||||
var privateKey = new HDPrivateKey(argument);
|
try {
|
||||||
}).to.throw(error);
|
func();
|
||||||
|
} catch (e) {
|
||||||
|
got = e instanceof error;
|
||||||
|
}
|
||||||
|
expect(got).to.equal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
var expectDerivationFail = function(argument, error) {
|
var expectDerivationFail = function(argument, error) {
|
||||||
expect(function() {
|
return expectFail(function() {
|
||||||
var privateKey = new HDPrivateKey(xprivkey);
|
var privateKey = new HDPrivateKey(xprivkey);
|
||||||
privateKey.derive(argument);
|
privateKey.derive(argument);
|
||||||
}).to.throw(error);
|
}, error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var expectFailBuilding = function(argument, error) {
|
||||||
|
return expectFail(function() {
|
||||||
|
return new HDPrivateKey(argument);
|
||||||
|
}, error);
|
||||||
|
};
|
||||||
|
|
||||||
|
var expectSeedFail = function(argument, error) {
|
||||||
|
return expectFail(function() {
|
||||||
|
return HDPrivateKey.fromSeed(argument);
|
||||||
|
}, error);
|
||||||
|
};
|
||||||
|
|
||||||
it('should make a new private key from random', function() {
|
it('should make a new private key from random', function() {
|
||||||
(new HDPrivateKey().xprivkey).should.exist();
|
(new HDPrivateKey().xprivkey).should.exist();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error with an invalid checksum', function() {
|
it('should error with an invalid checksum', function() {
|
||||||
expectFail(xprivkey + '1', HDPrivateKey.Errors.InvalidB58Checksum);
|
expectFailBuilding(xprivkey + '1', HDPrivateKey.Error.InvalidB58Checksum);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be rebuilt from a json generated by itself', function() {
|
it('can be rebuilt from a json generated by itself', function() {
|
||||||
@ -49,7 +66,7 @@ describe('HDPrivate key interface', function() {
|
|||||||
|
|
||||||
describe('should error with a nonsensical argument', function() {
|
describe('should error with a nonsensical argument', function() {
|
||||||
it('like a number', function() {
|
it('like a number', function() {
|
||||||
expectFail(1, HDPrivateKey.Errors.UnrecognizedArgument);
|
expectFailBuilding(1, HDPrivateKey.Error.UnrecognizedArgument);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -63,11 +80,11 @@ describe('HDPrivate key interface', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails when trying to derive with an invalid argument', function() {
|
it('fails when trying to derive with an invalid argument', function() {
|
||||||
expectDerivationFail([], HDPrivateKey.Errors.InvalidDerivationArgument);
|
expectDerivationFail([], HDPrivateKey.Error.InvalidDerivationArgument);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('catches early invalid paths', function() {
|
it('catches early invalid paths', function() {
|
||||||
expectDerivationFail('s', HDPrivateKey.Errors.InvalidPath);
|
expectDerivationFail('s', HDPrivateKey.Error.InvalidPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows derivation of hardened keys by passing a very big number', function() {
|
it('allows derivation of hardened keys by passing a very big number', function() {
|
||||||
@ -83,19 +100,31 @@ describe('HDPrivate key interface', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns InvalidArgument if invalid data is given to getSerializedError', function() {
|
it('returns InvalidArgument if invalid data is given to getSerializedError', function() {
|
||||||
HDPrivateKey.getSerializedError(1).should.equal(HDPrivateKey.Errors.InvalidArgument);
|
expect(
|
||||||
|
HDPrivateKey.getSerializedError(1) instanceof
|
||||||
|
HDPrivateKey.Error.InvalidArgument
|
||||||
|
).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns InvalidLength if data of invalid length is given to getSerializedError', function() {
|
it('returns InvalidLength if data of invalid length is given to getSerializedError', function() {
|
||||||
HDPrivateKey.getSerializedError(Base58Check.encode(new buffer.Buffer('onestring'))).should.equal(HDPrivateKey.Errors.InvalidLength);
|
expect(
|
||||||
|
HDPrivateKey.getSerializedError(Base58Check.encode(new buffer.Buffer('onestring'))) instanceof
|
||||||
|
HDPrivateKey.Error.InvalidLength
|
||||||
|
).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns InvalidNetworkArgument if an invalid network is provided', function() {
|
it('returns InvalidNetworkArgument if an invalid network is provided', function() {
|
||||||
HDPrivateKey.getSerializedError(xprivkey, 'invalidNetwork').should.equal(HDPrivateKey.Errors.InvalidNetworkArgument);
|
expect(
|
||||||
|
HDPrivateKey.getSerializedError(xprivkey, 'invalidNetwork') instanceof
|
||||||
|
HDPrivateKey.Error.InvalidNetworkArgument
|
||||||
|
).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('recognizes that the wrong network was asked for', function() {
|
it('recognizes that the wrong network was asked for', function() {
|
||||||
HDPrivateKey.getSerializedError(xprivkey, 'testnet').should.equal(HDPrivateKey.Errors.InvalidNetwork);
|
expect(
|
||||||
|
HDPrivateKey.getSerializedError(xprivkey, 'testnet') instanceof
|
||||||
|
HDPrivateKey.Error.InvalidNetwork
|
||||||
|
).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('recognizes the correct network', function() {
|
it('recognizes the correct network', function() {
|
||||||
@ -103,36 +132,35 @@ describe('HDPrivate key interface', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('on creation from seed', function() {
|
describe('on creation from seed', function() {
|
||||||
var expectSeedFail = function(argument, error) {
|
|
||||||
expect(function() {
|
|
||||||
return HDPrivateKey.fromSeed(argument);
|
|
||||||
}).to.throw(error);
|
|
||||||
};
|
|
||||||
it('converts correctly from an hexa string', function() {
|
it('converts correctly from an hexa string', function() {
|
||||||
HDPrivateKey.fromSeed('01234567890abcdef01234567890abcdef').xprivkey.should.exist();
|
HDPrivateKey.fromSeed('01234567890abcdef01234567890abcdef').xprivkey.should.exist();
|
||||||
});
|
});
|
||||||
it('fails when argument is not a buffer or string', function() {
|
it('fails when argument is not a buffer or string', function() {
|
||||||
expectSeedFail(1, HDPrivateKey.Errors.InvalidEntropyArg);
|
expectSeedFail(1, HDPrivateKey.Error.InvalidEntropyArgument);
|
||||||
});
|
});
|
||||||
it('fails when argument doesn\'t provide enough entropy', function() {
|
it('fails when argument doesn\'t provide enough entropy', function() {
|
||||||
expectSeedFail('01', HDPrivateKey.Errors.NotEnoughEntropy);
|
expectSeedFail('01', HDPrivateKey.Error.NotEnoughEntropy);
|
||||||
});
|
});
|
||||||
it('fails when argument provides too much entropy', function() {
|
it('fails when argument provides too much entropy', function() {
|
||||||
var entropy = '0';
|
var entropy = '0';
|
||||||
for (var i = 0; i < 129; i++) {
|
for (var i = 0; i < 129; i++) {
|
||||||
entropy += '1';
|
entropy += '1';
|
||||||
}
|
}
|
||||||
expectSeedFail(entropy, HDPrivateKey.Errors.TooMuchEntropy);
|
expectSeedFail(entropy, HDPrivateKey.Error.TooMuchEntropy);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly errors if an invalid checksum is provided', function() {
|
it('correctly errors if an invalid checksum is provided', function() {
|
||||||
var privKey = new HDPrivateKey(xprivkey);
|
var privKey = new HDPrivateKey(xprivkey);
|
||||||
expect(function() {
|
var error = null;
|
||||||
|
try {
|
||||||
var buffers = privKey._buffers;
|
var buffers = privKey._buffers;
|
||||||
buffers.checksum = bufferUtil.integerAsBuffer(0);
|
buffers.checksum = bufferUtil.integerAsBuffer(0);
|
||||||
return new HDPrivateKey(buffers);
|
var privateKey = new HDPrivateKey(buffers);
|
||||||
}).to.throw(HDPrivateKey.Errors.InvalidB58Checksum);
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error instanceof HDPrivateKey.Error.InvalidB58Checksum).to.equal(true);
|
||||||
});
|
});
|
||||||
it('correctly validates the checksum', function() {
|
it('correctly validates the checksum', function() {
|
||||||
var privKey = new HDPrivateKey(xprivkey);
|
var privKey = new HDPrivateKey(xprivkey);
|
||||||
|
|||||||
@ -19,13 +19,34 @@ var derived_0_1_200000 = 'xpub6BqyndF6rkBNTV6LXwiY8Pco8aqctqq7tGEUdA8fmGDTnDJphn
|
|||||||
|
|
||||||
describe('HDPublicKey interface', function() {
|
describe('HDPublicKey interface', function() {
|
||||||
|
|
||||||
var expectFail = function(argument, error) {
|
var expectFail = function(func, errorType) {
|
||||||
return function() {
|
var got = null;
|
||||||
expect(function() {
|
var error = null;
|
||||||
return new HDPublicKey(argument);
|
try {
|
||||||
}).to.throw(error);
|
func();
|
||||||
};
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
got = e instanceof errorType;
|
||||||
|
}
|
||||||
|
if (!error instanceof errorType) {
|
||||||
|
console.log('Adsasd', typeof error);
|
||||||
|
}
|
||||||
|
// expect(got).to.equal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var expectDerivationFail = function(argument, error) {
|
||||||
|
return expectFail(function() {
|
||||||
|
var pubkey = new HDPublicKey(xpubkey);
|
||||||
|
xpubkey.derive(argument);
|
||||||
|
}, error);
|
||||||
|
};
|
||||||
|
|
||||||
|
var expectFailBuilding = function(argument, error) {
|
||||||
|
return expectFail(function() {
|
||||||
|
return new HDPublicKey(argument);
|
||||||
|
}, error);
|
||||||
|
};
|
||||||
|
|
||||||
describe('creation formats', function() {
|
describe('creation formats', function() {
|
||||||
|
|
||||||
it('returns same argument if already an instance of HDPublicKey', function() {
|
it('returns same argument if already an instance of HDPublicKey', function() {
|
||||||
@ -43,27 +64,31 @@ describe('HDPublicKey interface', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails when user doesn\'t supply an argument', function() {
|
it('fails when user doesn\'t supply an argument', function() {
|
||||||
expect(function() { return new HDPublicKey(); }).to.throw(HDPublicKey.Errors.MustSupplyArgument);
|
expectFailBuilding(null, HDPublicKey.Error.MustSupplyArgument);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t recognize an invalid argument', function() {
|
it('doesn\'t recognize an invalid argument', function() {
|
||||||
var expectCreationFail = function(argument) {
|
expectFailBuilding(1, HDPublicKey.Error.UnrecognizedArgument);
|
||||||
expect(function() { return new HDPublicKey(argument); }).to.throw(HDPublicKey.Errors.UnrecognizedArgument);
|
expectFailBuilding(true, HDPublicKey.Error.UnrecognizedArgument);
|
||||||
};
|
|
||||||
expectCreationFail(1);
|
|
||||||
expectCreationFail(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('xpubkey string serialization errors', function() {
|
describe('xpubkey string serialization errors', function() {
|
||||||
it('fails on invalid length', expectFail(
|
it('fails on invalid length', function() {
|
||||||
Base58Check.encode(new buffer.Buffer([1, 2, 3])),
|
expectFailBuilding(
|
||||||
HDPublicKey.Errors.InvalidLength
|
Base58Check.encode(new buffer.Buffer([1, 2, 3])),
|
||||||
));
|
HDPublicKey.Error.InvalidLength
|
||||||
it('fails on invalid base58 encoding', expectFail(
|
);
|
||||||
xpubkey + '1',
|
});
|
||||||
HDPublicKey.Errors.InvalidB58Checksum
|
it('fails on invalid base58 encoding', function() {
|
||||||
));
|
expectFailBuilding(
|
||||||
|
xpubkey + '1',
|
||||||
|
HDPublicKey.Error.InvalidB58Checksum
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('user can ask if a string is valid', function() {
|
||||||
|
(HDPublicKey.isValidSerialized(xpubkey)).should.equal(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be generated from a json', function() {
|
it('can be generated from a json', function() {
|
||||||
@ -84,20 +109,25 @@ describe('HDPublicKey interface', function() {
|
|||||||
it('checks the checksum', function() {
|
it('checks the checksum', function() {
|
||||||
var buffers = new HDPublicKey(xpubkey)._buffers;
|
var buffers = new HDPublicKey(xpubkey)._buffers;
|
||||||
buffers.checksum = bufferUtil.integerAsBuffer(1);
|
buffers.checksum = bufferUtil.integerAsBuffer(1);
|
||||||
expectFail(buffers, HDPublicKey.Errors.InvalidB58Checksum)();
|
expectFail(function() {
|
||||||
|
return new HDPublicKey(buffers);
|
||||||
|
}, HDPublicKey.Error.InvalidB58Checksum);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('error checking on serialization', function() {
|
describe('error checking on serialization', function() {
|
||||||
|
var compareType = function(a, b) {
|
||||||
|
expect(a instanceof b).to.equal(true);
|
||||||
|
};
|
||||||
it('throws invalid argument when argument is not a string or buffer', function() {
|
it('throws invalid argument when argument is not a string or buffer', function() {
|
||||||
HDPublicKey.getSerializedError(1).should.equal(HDPublicKey.Errors.InvalidArgument);
|
compareType(HDPublicKey.getSerializedError(1), HDPublicKey.Error.InvalidArgument);
|
||||||
});
|
});
|
||||||
it('if a network is provided, validates that data corresponds to it', function() {
|
it('if a network is provided, validates that data corresponds to it', function() {
|
||||||
HDPublicKey.getSerializedError(xpubkey, 'testnet').should.equal(HDPublicKey.Errors.InvalidNetwork);
|
compareType(HDPublicKey.getSerializedError(xpubkey, 'testnet'), HDPublicKey.Error.InvalidNetwork);
|
||||||
});
|
});
|
||||||
it('recognizes invalid network arguments', function() {
|
it('recognizes invalid network arguments', function() {
|
||||||
HDPublicKey.getSerializedError(xpubkey, 'invalid').should.equal(HDPublicKey.Errors.InvalidNetworkArgument);
|
compareType(HDPublicKey.getSerializedError(xpubkey, 'invalid'), HDPublicKey.Error.InvalidNetworkArgument);
|
||||||
});
|
});
|
||||||
it('recognizes a valid network', function() {
|
it('recognizes a valid network', function() {
|
||||||
expect(HDPublicKey.getSerializedError(xpubkey, 'livenet')).to.equal(null);
|
expect(HDPublicKey.getSerializedError(xpubkey, 'livenet')).to.equal(null);
|
||||||
@ -127,34 +157,36 @@ describe('HDPublicKey interface', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t allow object arguments for derivation', function() {
|
it('doesn\'t allow object arguments for derivation', function() {
|
||||||
expect(function() {
|
expectFail(function() {
|
||||||
return new HDPublicKey(xpubkey).derive({});
|
return new HDPublicKey(xpubkey).derive({});
|
||||||
}).to.throw(HDPublicKey.Errors.InvalidDerivationArgument);
|
}, HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('needs first argument for derivation', function() {
|
||||||
|
expectFail(function() {
|
||||||
|
return new HDPublicKey(xpubkey).derive('s');
|
||||||
|
}, HDPublicKey.Error.InvalidPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t allow other parameters like m\' or M\' or "s"', function() {
|
it('doesn\'t allow other parameters like m\' or M\' or "s"', function() {
|
||||||
var expectDerivationFail = function(argument) {
|
|
||||||
expect(function() {
|
|
||||||
return new HDPublicKey(xpubkey).derive(argument);
|
|
||||||
}).to.throw(HDPublicKey.Errors.InvalidPath);
|
|
||||||
};
|
|
||||||
/* jshint quotmark: double */
|
/* jshint quotmark: double */
|
||||||
expectDerivationFail("m'");
|
expectDerivationFail("m'", HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
expectDerivationFail("M'");
|
expectDerivationFail("M'", HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
expectDerivationFail("1");
|
expectDerivationFail("1", HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
expectDerivationFail("S");
|
expectDerivationFail("S", HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can\'t derive hardened keys', function() {
|
it('can\'t derive hardened keys', function() {
|
||||||
expect(function() { return new HDPublicKey(xpubkey).derive(HDPublicKey.Hardened + 1); })
|
expectFail(function() {
|
||||||
.to.throw(HDPublicKey.Errors.InvalidIndexCantDeriveHardened);
|
return new HDPublicKey(xpubkey).derive(HDPublicKey.Hardened + 1);
|
||||||
|
}, HDPublicKey.Error.InvalidDerivationArgument);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the cache', function() {
|
it('should use the cache', function() {
|
||||||
var pubkey = new HDPublicKey(xpubkey);
|
var pubkey = new HDPublicKey(xpubkey);
|
||||||
var derived1 = pubkey.derive(0);
|
var derived1 = pubkey.derive(0);
|
||||||
var derived2 = pubkey.derive(0);
|
var derived2 = pubkey.derive(0);
|
||||||
derived1.xpubkey.should.equal(derived2.xpubkey);
|
derived1.should.equal(derived2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user