@leather.io/crypto 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +9 -5
- package/dist/index.mjs +10 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -23,10 +23,10 @@ declare function createKeyOriginPath(fingerprint: string, path: string): string;
|
|
|
23
23
|
declare function validateKeyOriginPath(keyOriginPath: string): boolean;
|
|
24
24
|
/**
|
|
25
25
|
* @description
|
|
26
|
-
* Creates a descriptor with key origin and xpub
|
|
27
|
-
* @
|
|
26
|
+
* Creates a descriptor with key origin and xpub or public key
|
|
27
|
+
* @returns `[0a3fd8ef/84'/0'/0']xpuba1b…2c3`
|
|
28
28
|
*/
|
|
29
|
-
declare function
|
|
29
|
+
declare function createDescriptor(keyOriginPath: string, key: string): string;
|
|
30
30
|
/**
|
|
31
31
|
* @example `[0a3fd8ef/84'/0'/0']xpuba1b…2c3` -> `0a3fd8ef/84'/0'/0'`
|
|
32
32
|
*/
|
|
@@ -43,6 +43,10 @@ declare function extractFingerprintFromDescriptor(descriptor: string): string;
|
|
|
43
43
|
* @example `[0a3fd8ef/84'/0'/6']xpuba1b…2c3` -> `6`
|
|
44
44
|
*/
|
|
45
45
|
declare function extractAccountIndexFromDescriptor(descriptor: string): number;
|
|
46
|
+
/**
|
|
47
|
+
* @example `[0a3fd8ef/84'/0'/6']xpuba1b…2c3` -> `xpuba1b…2c3`
|
|
48
|
+
*/
|
|
49
|
+
declare function extractKeyFromDescriptor(descriptor: string): string;
|
|
46
50
|
|
|
47
51
|
declare function generateMnemonic(): string;
|
|
48
52
|
declare function deriveBip39SeedFromMnemonic(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
|
|
@@ -55,8 +59,8 @@ declare function deriveKeychainFromXpub(xpub: string): HDKey;
|
|
|
55
59
|
* referencing a mnemonic safely by an identifier.
|
|
56
60
|
*/
|
|
57
61
|
declare function getMnemonicRootKeyFingerprint(mnemonic: string, passphrase?: string): Promise<string>;
|
|
58
|
-
declare function
|
|
62
|
+
declare function deriveKeychainExtendedPublicKeyDescriptor(rootKeychain: HDKey, path: string): string;
|
|
59
63
|
declare function isValidMnemonicWord(word: string): boolean;
|
|
60
64
|
declare function isValidMnemonic(mnemonic: string): boolean;
|
|
61
65
|
|
|
62
|
-
export { DerivationPathDepth,
|
|
66
|
+
export { DerivationPathDepth, createDescriptor, createKeyOriginPath, deriveBip39MnemonicFromSeed, deriveBip39SeedFromMnemonic, deriveKeychainExtendedPublicKeyDescriptor, deriveKeychainFromXpub, deriveRootBip32Keychain, extractAccountIndexFromDescriptor, extractAccountIndexFromPath, extractAddressIndexFromPath, extractDerivationPathFromDescriptor, extractFingerprintFromDescriptor, extractFingerprintFromKeyOriginPath, extractKeyFromDescriptor, extractKeyOriginPathFromDescriptor, generateMnemonic, getMnemonicRootKeyFingerprint, isValidMnemonic, isValidMnemonicWord, validateKeyOriginPath };
|
package/dist/index.mjs
CHANGED
|
@@ -43,9 +43,9 @@ function validateKeyOriginPath(keyOriginPath) {
|
|
|
43
43
|
throw new Error("Key origin path is too short. Should describe at least to the account level");
|
|
44
44
|
return true;
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function createDescriptor(keyOriginPath, key) {
|
|
47
47
|
validateKeyOriginPath(keyOriginPath);
|
|
48
|
-
return `[${keyOriginPath}]${
|
|
48
|
+
return `[${keyOriginPath}]${key}`;
|
|
49
49
|
}
|
|
50
50
|
function extractKeyOriginPathFromDescriptor(descriptor) {
|
|
51
51
|
const keyOriginPath = descriptor.split("]")[0].replace("[", "");
|
|
@@ -62,6 +62,9 @@ function extractFingerprintFromDescriptor(descriptor) {
|
|
|
62
62
|
function extractAccountIndexFromDescriptor(descriptor) {
|
|
63
63
|
return extractAccountIndexFromPath(extractKeyOriginPathFromDescriptor(descriptor));
|
|
64
64
|
}
|
|
65
|
+
function extractKeyFromDescriptor(descriptor) {
|
|
66
|
+
return descriptor.split("]")[1];
|
|
67
|
+
}
|
|
65
68
|
|
|
66
69
|
// src/keychain.ts
|
|
67
70
|
import { HDKey } from "@scure/bip32";
|
|
@@ -89,13 +92,13 @@ async function getMnemonicRootKeyFingerprint(mnemonic, passphrase) {
|
|
|
89
92
|
const keychain = deriveRootBip32Keychain(await deriveBip39SeedFromMnemonic(mnemonic, passphrase));
|
|
90
93
|
return toHexString(keychain.fingerprint);
|
|
91
94
|
}
|
|
92
|
-
function
|
|
95
|
+
function deriveKeychainExtendedPublicKeyDescriptor(rootKeychain, path) {
|
|
93
96
|
const masterFingerprint = toHexString(rootKeychain.fingerprint);
|
|
94
97
|
const keyOriginPath = createKeyOriginPath(masterFingerprint, path);
|
|
95
98
|
if (rootKeychain.depth !== 0 /* Root */)
|
|
96
99
|
throw new Error("Cannot derive account keychain from non-root keychain");
|
|
97
100
|
const accountKeychain = rootKeychain.derive(path);
|
|
98
|
-
return
|
|
101
|
+
return createDescriptor(keyOriginPath, accountKeychain.publicExtendedKey);
|
|
99
102
|
}
|
|
100
103
|
function isValidMnemonicWord(word) {
|
|
101
104
|
return wordlist.includes(word);
|
|
@@ -105,11 +108,11 @@ function isValidMnemonic(mnemonic) {
|
|
|
105
108
|
}
|
|
106
109
|
export {
|
|
107
110
|
DerivationPathDepth,
|
|
108
|
-
|
|
111
|
+
createDescriptor,
|
|
109
112
|
createKeyOriginPath,
|
|
110
113
|
deriveBip39MnemonicFromSeed,
|
|
111
114
|
deriveBip39SeedFromMnemonic,
|
|
112
|
-
|
|
115
|
+
deriveKeychainExtendedPublicKeyDescriptor,
|
|
113
116
|
deriveKeychainFromXpub,
|
|
114
117
|
deriveRootBip32Keychain,
|
|
115
118
|
extractAccountIndexFromDescriptor,
|
|
@@ -118,6 +121,7 @@ export {
|
|
|
118
121
|
extractDerivationPathFromDescriptor,
|
|
119
122
|
extractFingerprintFromDescriptor,
|
|
120
123
|
extractFingerprintFromKeyOriginPath,
|
|
124
|
+
extractKeyFromDescriptor,
|
|
121
125
|
extractKeyOriginPathFromDescriptor,
|
|
122
126
|
generateMnemonic,
|
|
123
127
|
getMnemonicRootKeyFingerprint,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/derivation-path-utils.ts","../src/keychain.ts"],"sourcesContent":["import { isHexString } from '@leather.io/utils';\n\nexport enum DerivationPathDepth {\n Root = 0,\n Purpose = 1,\n CoinType = 2,\n Account = 3,\n ChangeReceive = 4,\n AddressIndex = 5,\n}\n\nfunction extractSectionFromDerivationPath(depth: DerivationPathDepth) {\n return (path: string) => {\n const segments = path.split('/');\n const accountNum = parseInt(segments[depth].replaceAll(\"'\", ''), 10);\n if (isNaN(accountNum)) throw new Error(`Cannot parse ${DerivationPathDepth[depth]} from path`);\n return accountNum;\n };\n}\n\nexport const extractAccountIndexFromPath = extractSectionFromDerivationPath(\n DerivationPathDepth.Account\n);\n\nexport const extractAddressIndexFromPath = extractSectionFromDerivationPath(\n DerivationPathDepth.AddressIndex\n);\n\nexport function extractFingerprintFromKeyOriginPath(keyOriginPath: string) {\n const fingerprint = keyOriginPath.split('/')[0];\n if (!isHexString(fingerprint)) throw new Error('Fingerprint must be a hexadecimal string');\n return fingerprint;\n}\n\n/**\n * @description\n * A key origin path refers to the identifier commonly used as part of the key\n * information provided as part of a Output Descriptor described in BIP-380. It\n * replaces the `m/` part of a derivation path with the master key fingerprint to which the\n * key it describes belongs.\n * @example `0a3fd8ef/84'/0'/0'`\n */\nexport function createKeyOriginPath(fingerprint: string, path: string) {\n if (!isHexString(fingerprint)) throw new Error('Fingerprint must be a hexadecimal string');\n return `${fingerprint}/${path.replace('m/', '')}`;\n}\n\nexport function validateKeyOriginPath(keyOriginPath: string) {\n if (keyOriginPath.includes('[') || keyOriginPath.includes(']'))\n throw new Error('Key origin path should not contain square brackets');\n\n if (!keyOriginPath.includes('/'))\n throw new Error('Key origin path must contain a fingerprint and derivation path');\n\n if (!isHexString(extractFingerprintFromKeyOriginPath(keyOriginPath)))\n throw new Error('Fingerprint must be a hexadecimal string');\n\n if (keyOriginPath.split('/').length < 4)\n throw new Error('Key origin path is too short. Should describe at least to the account level');\n\n return true;\n}\n\n/**\n * @description\n * Creates a descriptor with key origin and xpub\n * @
|
|
1
|
+
{"version":3,"sources":["../src/derivation-path-utils.ts","../src/keychain.ts"],"sourcesContent":["import { isHexString } from '@leather.io/utils';\n\nexport enum DerivationPathDepth {\n Root = 0,\n Purpose = 1,\n CoinType = 2,\n Account = 3,\n ChangeReceive = 4,\n AddressIndex = 5,\n}\n\nfunction extractSectionFromDerivationPath(depth: DerivationPathDepth) {\n return (path: string) => {\n const segments = path.split('/');\n const accountNum = parseInt(segments[depth].replaceAll(\"'\", ''), 10);\n if (isNaN(accountNum)) throw new Error(`Cannot parse ${DerivationPathDepth[depth]} from path`);\n return accountNum;\n };\n}\n\nexport const extractAccountIndexFromPath = extractSectionFromDerivationPath(\n DerivationPathDepth.Account\n);\n\nexport const extractAddressIndexFromPath = extractSectionFromDerivationPath(\n DerivationPathDepth.AddressIndex\n);\n\nexport function extractFingerprintFromKeyOriginPath(keyOriginPath: string) {\n const fingerprint = keyOriginPath.split('/')[0];\n if (!isHexString(fingerprint)) throw new Error('Fingerprint must be a hexadecimal string');\n return fingerprint;\n}\n\n/**\n * @description\n * A key origin path refers to the identifier commonly used as part of the key\n * information provided as part of a Output Descriptor described in BIP-380. It\n * replaces the `m/` part of a derivation path with the master key fingerprint to which the\n * key it describes belongs.\n * @example `0a3fd8ef/84'/0'/0'`\n */\nexport function createKeyOriginPath(fingerprint: string, path: string) {\n if (!isHexString(fingerprint)) throw new Error('Fingerprint must be a hexadecimal string');\n return `${fingerprint}/${path.replace('m/', '')}`;\n}\n\nexport function validateKeyOriginPath(keyOriginPath: string) {\n if (keyOriginPath.includes('[') || keyOriginPath.includes(']'))\n throw new Error('Key origin path should not contain square brackets');\n\n if (!keyOriginPath.includes('/'))\n throw new Error('Key origin path must contain a fingerprint and derivation path');\n\n if (!isHexString(extractFingerprintFromKeyOriginPath(keyOriginPath)))\n throw new Error('Fingerprint must be a hexadecimal string');\n\n if (keyOriginPath.split('/').length < 4)\n throw new Error('Key origin path is too short. Should describe at least to the account level');\n\n return true;\n}\n\n/**\n * @description\n * Creates a descriptor with key origin and xpub or public key\n * @returns `[0a3fd8ef/84'/0'/0']xpuba1b…2c3`\n */\nexport function createDescriptor(keyOriginPath: string, key: string) {\n validateKeyOriginPath(keyOriginPath);\n return `[${keyOriginPath}]${key}`;\n}\n\n/**\n * @example `[0a3fd8ef/84'/0'/0']xpuba1b…2c3` -> `0a3fd8ef/84'/0'/0'`\n */\nexport function extractKeyOriginPathFromDescriptor(descriptor: string) {\n const keyOriginPath = descriptor.split(']')[0].replace('[', '');\n validateKeyOriginPath(keyOriginPath);\n return keyOriginPath;\n}\n\n/**\n * @example `[0a3fd8ef/84'/0'/0']xpuba1b…2c3` -> `m/84'/0'/0'`\n */\nexport function extractDerivationPathFromDescriptor(descriptor: string) {\n const keyOriginPath = extractKeyOriginPathFromDescriptor(descriptor);\n return 'm/' + keyOriginPath.split('/').slice(1).join('/');\n}\n\n/**\n * @example `[0a3fd8ef/84'/0'/0']xpuba1b…2c3` -> `0a3fd8ef`\n */\nexport function extractFingerprintFromDescriptor(descriptor: string) {\n return extractFingerprintFromKeyOriginPath(extractKeyOriginPathFromDescriptor(descriptor));\n}\n\n/**\n * @example `[0a3fd8ef/84'/0'/6']xpuba1b…2c3` -> `6`\n */\nexport function extractAccountIndexFromDescriptor(descriptor: string) {\n return extractAccountIndexFromPath(extractKeyOriginPathFromDescriptor(descriptor));\n}\n\n/**\n * @example `[0a3fd8ef/84'/0'/6']xpuba1b…2c3` -> `xpuba1b…2c3`\n */\nexport function extractKeyFromDescriptor(descriptor: string) {\n return descriptor.split(']')[1];\n}\n","import { HDKey } from '@scure/bip32';\nimport {\n mnemonicToSeed,\n generateMnemonic as scureGenerateMnemonic,\n validateMnemonic,\n} from '@scure/bip39';\nimport { wordlist } from '@scure/bip39/wordlists/english';\n\nimport { toHexString } from '@leather.io/utils';\n\nimport {\n DerivationPathDepth,\n createDescriptor,\n createKeyOriginPath,\n} from './derivation-path-utils';\n\nexport function generateMnemonic() {\n return scureGenerateMnemonic(wordlist, 256);\n}\n\nexport async function deriveBip39SeedFromMnemonic(mnemonic: string, passphrase?: string) {\n return mnemonicToSeed(mnemonic, passphrase);\n}\n/** @deprecated Inaccurately named fn, use `deriveBip39SeedFromMnemonic` */\nexport const deriveBip39MnemonicFromSeed = deriveBip39SeedFromMnemonic;\n\nexport function deriveRootBip32Keychain(seed: Uint8Array) {\n return HDKey.fromMasterSeed(seed);\n}\n\nexport function deriveKeychainFromXpub(xpub: string) {\n return HDKey.fromExtendedKey(xpub);\n}\n\n/**\n * Gets keychain fingerprint directly from mnemonic. This is useful for\n * referencing a mnemonic safely by an identifier.\n */\nexport async function getMnemonicRootKeyFingerprint(mnemonic: string, passphrase?: string) {\n const keychain = deriveRootBip32Keychain(await deriveBip39SeedFromMnemonic(mnemonic, passphrase));\n return toHexString(keychain.fingerprint);\n}\n\nexport function deriveKeychainExtendedPublicKeyDescriptor(rootKeychain: HDKey, path: string) {\n const masterFingerprint = toHexString(rootKeychain.fingerprint);\n const keyOriginPath = createKeyOriginPath(masterFingerprint, path);\n\n if (rootKeychain.depth !== DerivationPathDepth.Root)\n throw new Error('Cannot derive account keychain from non-root keychain');\n\n const accountKeychain = rootKeychain.derive(path);\n return createDescriptor(keyOriginPath, accountKeychain.publicExtendedKey);\n}\n\nexport function isValidMnemonicWord(word: string): boolean {\n return wordlist.includes(word);\n}\n\nexport function isValidMnemonic(mnemonic: string): boolean {\n return validateMnemonic(mnemonic, wordlist);\n}\n"],"mappings":"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","names":["DerivationPathDepth"]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@leather.io/crypto",
|
|
3
3
|
"author": "leather.io",
|
|
4
4
|
"description": "Generic crypto utils package for Leather",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.3.1",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/index.mjs"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@scure/bip32": "1.4.0",
|
|
12
12
|
"@scure/bip39": "1.3.0",
|
|
13
|
-
"@leather.io/utils": "0.
|
|
13
|
+
"@leather.io/utils": "0.12.1"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@vitest/coverage-istanbul": "0.34.6",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsup",
|
|
29
|
-
"build:watch": "tsup --watch",
|
|
29
|
+
"build:watch": "tsup --watch --onSuccess 'tsup --dts-only'",
|
|
30
30
|
"prepublish": "pnpm build",
|
|
31
31
|
"test:unit": "vitest run",
|
|
32
32
|
"typecheck": "tsc --noEmit"
|