Skip to content

Commit 3e333f7

Browse files
author
AJ ONeal
committed
fix: type cleanup
1 parent 3d47f5d commit 3e333f7

File tree

1 file changed

+66
-45
lines changed

1 file changed

+66
-45
lines changed

dashhd.js

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
* @prop {HDDeriveChild} deriveChild - get the next child xkey (in a path segment)
55
* @prop {HDDerivePath} derivePath - derive a full hd path from the given key
66
* @prop {HDFingerprint} fingerprint
7-
* @prop {HDFromSeed} fromMasterSeed
8-
* @prop {HDFromXKey} fromExtendedKey
7+
* @prop {HDFromSeed} fromSeed
8+
* @prop {HDFromXKey} fromXKey
99
* @prop {HDGetXPrv} getPrivateExtendedKey
1010
* @prop {HDGetXPub} getPublicExtendedKey
1111
* @prop {HDUtils} utils
1212
* @prop {HDWipePrivates} wipePrivateData - randomizes private key buffer in-place
1313
* @prop {Number} HARDENED_OFFSET - 0x80000000
14+
* @prop {HDVersions} MAINNET - 'xprv' & 'xpub'
15+
* @prop {HDVersions} TESTNET - 'tprv' & 'tpub'
1416
* @prop {HDDeriveHelper} _derive - helper
1517
*/
1618

@@ -27,7 +29,7 @@
2729

2830
/**
2931
* @callback HDCreate
30-
* @param {hdkey} opts
32+
* @param {HDKey} opts
3133
* @returns {HDKey}
3234
*/
3335

@@ -212,12 +214,14 @@ var DashHd = ("object" === typeof module && exports) || {};
212214
let KEY_SIZE = 33;
213215
let INDEXED_KEY_SIZE = 4 + KEY_SIZE;
214216
let XKEY_SIZE = 74;
217+
let ACCOUNT_DEPTH = 3; // m/44'/5'/<0'[/0/0]
215218

216219
// Bitcoin hardcoded by default, can use package `coininfo` for others
217-
let BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
220+
DashHd.MAINNET = { private: 0x0488ade4, public: 0x0488b21e };
221+
DashHd.TESTNET = { private: 0x043587cf, public: 0x04358394 };
218222

219223
DashHd.create = function ({
220-
versions = BITCOIN_VERSIONS,
224+
versions = DashHd.MAINNET,
221225
depth = 0,
222226
parentFingerprint = 0,
223227
index,
@@ -400,7 +404,7 @@ var DashHd = ("object" === typeof module && exports) || {};
400404
return n;
401405
}
402406

403-
DashHd.fromMasterSeed = async function (seed, versions = BITCOIN_VERSIONS) {
407+
DashHd.fromSeed = async function ({ seed, versions = DashHd.MAINNET }) {
404408
let chainAndKeys = await DashHd._derive(seed, {
405409
chainCode: ROOT_CHAIN,
406410
});
@@ -416,27 +420,20 @@ var DashHd = ("object" === typeof module && exports) || {};
416420
);
417421
};
418422

419-
DashHd.fromExtendedKey = async function (
420-
base58key,
421-
versions,
422-
skipVerification,
423-
) {
423+
DashHd.fromXKey = async function ({
424+
xkey, // base58key,
425+
versions = DashHd.MAINNET,
426+
normalizePublicKey = false,
427+
bip32 = false,
428+
}) {
424429
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
425-
versions = versions || BITCOIN_VERSIONS;
426-
skipVerification = skipVerification || false;
427430

428-
//@ts-ignore - wth?
429-
let keyInfo = await Utils.decode(base58key);
431+
let keyInfo = await Utils.decode(xkey);
430432
let keyBytes = DashKeys.utils.hexToBytes(keyInfo.xprv || keyInfo.xpub);
431433
let keyDv = new DataView(keyBytes.buffer, 0, keyBytes.byteLength);
432434

433435
//let version = keyDv.getUint32(0, BUFFER_BE);
434-
// TODO tprv, tpub
435436
let version = parseInt(keyInfo.version, 16);
436-
assert(
437-
version === versions.private || version === versions.public,
438-
"Version mismatch: does not match private or public",
439-
);
440437

441438
let privateKey;
442439
let publicKey;
@@ -448,35 +445,47 @@ var DashHd = ("object" === typeof module && exports) || {};
448445
publicKey = key;
449446
}
450447

448+
let xprvHex = "0x0" + versions.private.toString(16);
449+
let xpubHex = "0x0" + versions.public.toString(16);
451450
if (publicKey) {
452451
assert(
453452
version === versions.public,
454-
"Version mismatch: version does not match public",
455-
);
456-
assert(
457-
key.length === 33 || key.length === 65,
458-
"Public key must be 33 or 65 bytes.",
453+
`Version mismatch: version does not match ${xpubHex} (public)`,
459454
);
460-
if (!skipVerification) {
455+
// at one point xy pubs (1 + 64 bytes) were allowed (per spec)
456+
// but nothing in the ecosystem actually works that way
457+
assert(key.length === 33, "Public key must be 33 (1 + 32) bytes.");
458+
if (normalizePublicKey) {
461459
publicKey = await Utils.publicKeyNormalize(publicKey);
462460
}
463461
} else {
464462
assert(
465463
version === versions.private,
466-
"Version mismatch: version does not match private",
464+
`Version mismatch: version does not match ${xprvHex} (private)`,
467465
);
468466
publicKey = await Utils.toPublicKey(privateKey);
469467
}
470468

471-
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
469+
let depth = keyDv.getUint8(0);
470+
if (!bip32) {
471+
if (depth !== ACCOUNT_DEPTH) {
472+
throw new Error(
473+
`XKey with depth=${depth} does not represent an account (depth=${ACCOUNT_DEPTH})`,
474+
);
475+
}
476+
}
477+
478+
let parentFingerprint = keyDv.getUint32(1, BUFFER_BE);
479+
let index = keyDv.getUint32(5, BUFFER_BE);
480+
let chainCode = keyBytes.subarray(9, 41);
472481
let hdkey = DashHd.create({
473-
versions: versions,
474-
depth: keyDv.getUint8(0),
475-
parentFingerprint: keyDv.getUint32(1, BUFFER_BE),
476-
index: keyDv.getUint32(5, BUFFER_BE),
477-
chainCode: keyBytes.subarray(9, 41),
478-
privateKey: privateKey,
479-
publicKey: publicKey,
482+
versions,
483+
depth,
484+
parentFingerprint,
485+
index,
486+
chainCode,
487+
privateKey,
488+
publicKey,
480489
});
481490

482491
return hdkey;
@@ -539,7 +548,7 @@ if ("object" === typeof module) {
539548

540549
/**
541550
* @callback HDDeriveChild
542-
* @param {hdkey} hdkey
551+
* @param {HDKey} hdkey
543552
* @param {Number} index - includes HARDENED_OFFSET, if applicable
544553
* @param {Boolean} hardened
545554
* returns {Promise<HDKey>}
@@ -561,7 +570,7 @@ if ("object" === typeof module) {
561570

562571
/**
563572
* @callback HDDerivePath
564-
* @param {hdkey} hdkey
573+
* @param {HDKey} hdkey
565574
* @param {String} path
566575
* returns {Promise<HDKey>}
567576
*/
@@ -574,33 +583,45 @@ if ("object" === typeof module) {
574583

575584
/**
576585
* @callback HDFromXKey
577-
* @param {String} base58key - base58check-encoded xkey
578-
* @param {HDVersions} [versions]
579-
* @param {Boolean} [skipVerification]
586+
* @param {HDFromXKeyOptions} opts
587+
* returns {Promise<HDKey>}
588+
*/
589+
590+
/**
591+
* @typedef HDFromXKeyOptions
592+
* @prop {HDVersions} [versions]
593+
* @prop {String} xkey - base58check-encoded xkey
594+
* @prop {Boolean} [bip32] - allow non-account depths
595+
* @prop {Boolean} [normalizePublicKey]
580596
* returns {Promise<HDKey>}
581597
*/
582598

583599
/**
584600
* @callback HDFromSeed
585-
* @param {Uint8Array} seedBuffer
586-
* @param {HDVersions} [versions]
601+
* @param {HDFromSeedOptions} opts
587602
* @returns {Promise<HDKey>}
588603
*/
589604

605+
/**
606+
* @typedef HDFromSeedOptions
607+
* @prop {Uint8Array} seed
608+
* @prop {HDVersions} [versions]
609+
*/
610+
590611
/**
591612
* @callback HDGetBuffer
592613
* @returns {Uint8Array}
593614
*/
594615

595616
/**
596617
* @callback HDGetXPrv
597-
* @param {hdkey} hdkey
618+
* @param {HDKey} hdkey
598619
* @returns {Promise<String>}
599620
*/
600621

601622
/**
602623
* @callback HDGetXPub
603-
* @param {hdkey} hdkey
624+
* @param {HDKey} hdkey
604625
* @returns {Promise<String>}
605626
*/
606627

@@ -643,5 +664,5 @@ if ("object" === typeof module) {
643664

644665
/**
645666
* @callback HDWipePrivates
646-
* @param {hdkey} hdkey
667+
* @param {HDKey} hdkey
647668
*/

0 commit comments

Comments
 (0)