@bitcoinerlab/descriptors 3.0.5 → 3.1.0
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/README.md +9 -487
- package/index.d.ts +13 -0
- package/index.js +16 -0
- package/package.json +22 -53
- package/dist/applyPR2137.d.ts +0 -2
- package/dist/applyPR2137.js +0 -153
- package/dist/bitcoinjs-lib-internals.d.ts +0 -10
- package/dist/bitcoinjs-lib-internals.js +0 -50
- package/dist/checksum.d.ts +0 -6
- package/dist/checksum.js +0 -58
- package/dist/descriptors.d.ts +0 -433
- package/dist/descriptors.js +0 -1743
- package/dist/index.d.ts +0 -21
- package/dist/index.js +0 -85
- package/dist/keyExpressions.d.ts +0 -83
- package/dist/keyExpressions.js +0 -248
- package/dist/ledger.d.ts +0 -167
- package/dist/ledger.js +0 -580
- package/dist/miniscript.d.ts +0 -123
- package/dist/miniscript.js +0 -305
- package/dist/multipath.d.ts +0 -13
- package/dist/multipath.js +0 -76
- package/dist/networkUtils.d.ts +0 -3
- package/dist/networkUtils.js +0 -16
- package/dist/parseUtils.d.ts +0 -7
- package/dist/parseUtils.js +0 -46
- package/dist/psbt.d.ts +0 -44
- package/dist/psbt.js +0 -193
- package/dist/re.d.ts +0 -31
- package/dist/re.js +0 -79
- package/dist/resourceLimits.d.ts +0 -25
- package/dist/resourceLimits.js +0 -89
- package/dist/scriptExpressions.d.ts +0 -95
- package/dist/scriptExpressions.js +0 -89
- package/dist/signers.d.ts +0 -84
- package/dist/signers.js +0 -215
- package/dist/tapMiniscript.d.ts +0 -215
- package/dist/tapMiniscript.js +0 -515
- package/dist/tapTree.d.ts +0 -86
- package/dist/tapTree.js +0 -167
- package/dist/types.d.ts +0 -238
- package/dist/types.js +0 -4
package/dist/index.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export type { Expansion, ExpansionMap, KeyExpressionParser, KeyInfo, Preimage, TimeConstraints } from './types';
|
|
2
|
-
export { DescriptorsFactory, OutputInstance, OutputConstructor } from './descriptors';
|
|
3
|
-
export { DescriptorChecksum as checksum } from './checksum';
|
|
4
|
-
import * as signers from './signers';
|
|
5
|
-
export { signers };
|
|
6
|
-
export { keyExpressionBIP32, keyExpressionLedger } from './keyExpressions';
|
|
7
|
-
import * as scriptExpressions from './scriptExpressions';
|
|
8
|
-
export { scriptExpressions };
|
|
9
|
-
import { LedgerState, getLedgerMasterFingerPrint, getLedgerXpub, registerLedgerWallet, assertLedgerApp, LedgerManager } from './ledger';
|
|
10
|
-
/** @namespace */
|
|
11
|
-
export declare const ledger: {
|
|
12
|
-
/** @function */
|
|
13
|
-
getLedgerMasterFingerPrint: typeof getLedgerMasterFingerPrint;
|
|
14
|
-
/** @function */
|
|
15
|
-
getLedgerXpub: typeof getLedgerXpub;
|
|
16
|
-
/** @function */
|
|
17
|
-
registerLedgerWallet: typeof registerLedgerWallet;
|
|
18
|
-
/** @function */
|
|
19
|
-
assertLedgerApp: typeof assertLedgerApp;
|
|
20
|
-
};
|
|
21
|
-
export type { LedgerState, LedgerManager };
|
package/dist/index.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright (c) 2023 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
-
// Distributed under the MIT software license
|
|
4
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
-
if (k2 === undefined) k2 = k;
|
|
6
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
-
}
|
|
10
|
-
Object.defineProperty(o, k2, desc);
|
|
11
|
-
}) : (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
o[k2] = m[k];
|
|
14
|
-
}));
|
|
15
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
-
}) : function(o, v) {
|
|
18
|
-
o["default"] = v;
|
|
19
|
-
});
|
|
20
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
-
var ownKeys = function(o) {
|
|
22
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
-
var ar = [];
|
|
24
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
-
return ar;
|
|
26
|
-
};
|
|
27
|
-
return ownKeys(o);
|
|
28
|
-
};
|
|
29
|
-
return function (mod) {
|
|
30
|
-
if (mod && mod.__esModule) return mod;
|
|
31
|
-
var result = {};
|
|
32
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
-
__setModuleDefault(result, mod);
|
|
34
|
-
return result;
|
|
35
|
-
};
|
|
36
|
-
})();
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.ledger = exports.scriptExpressions = exports.keyExpressionLedger = exports.keyExpressionBIP32 = exports.signers = exports.checksum = exports.DescriptorsFactory = void 0;
|
|
39
|
-
// Some dependencies (like hash-base) assume process.version exists.
|
|
40
|
-
// In React Native / Hermes, process is defined but version is not.
|
|
41
|
-
// Note: we only polyfill if process already exists but is incomplete.
|
|
42
|
-
// The user is responsible for providing the process polyfill; this is just
|
|
43
|
-
// a small patch for environments (like Hermes) with partial implementations.
|
|
44
|
-
//
|
|
45
|
-
// More information: https://github.com/browserify/hash-base/issues/21#issuecomment-3476608003
|
|
46
|
-
const g = typeof globalThis !== 'undefined'
|
|
47
|
-
? globalThis
|
|
48
|
-
: typeof global !== 'undefined'
|
|
49
|
-
? global
|
|
50
|
-
: {};
|
|
51
|
-
if (typeof g.process !== 'undefined' &&
|
|
52
|
-
typeof g.process.version === 'undefined') {
|
|
53
|
-
const isDev = g['__DEV__'] === true ||
|
|
54
|
-
g.process?.env?.['NODE_ENV'] === 'development';
|
|
55
|
-
if (isDev) {
|
|
56
|
-
//only WARN while developing
|
|
57
|
-
console.warn(`[bitcoinerlab/descriptors] Polyfilled process.version (missing in this non-Node environment).
|
|
58
|
-
Learn more: https://github.com/bitcoinerlab/descriptors/blob/main/src/index.ts#L4`);
|
|
59
|
-
}
|
|
60
|
-
// @ts-expect-error Polyfill for environments missing process.version
|
|
61
|
-
global.process.version = '';
|
|
62
|
-
}
|
|
63
|
-
var descriptors_1 = require("./descriptors");
|
|
64
|
-
Object.defineProperty(exports, "DescriptorsFactory", { enumerable: true, get: function () { return descriptors_1.DescriptorsFactory; } });
|
|
65
|
-
var checksum_1 = require("./checksum");
|
|
66
|
-
Object.defineProperty(exports, "checksum", { enumerable: true, get: function () { return checksum_1.DescriptorChecksum; } });
|
|
67
|
-
const signers = __importStar(require("./signers"));
|
|
68
|
-
exports.signers = signers;
|
|
69
|
-
var keyExpressions_1 = require("./keyExpressions");
|
|
70
|
-
Object.defineProperty(exports, "keyExpressionBIP32", { enumerable: true, get: function () { return keyExpressions_1.keyExpressionBIP32; } });
|
|
71
|
-
Object.defineProperty(exports, "keyExpressionLedger", { enumerable: true, get: function () { return keyExpressions_1.keyExpressionLedger; } });
|
|
72
|
-
const scriptExpressions = __importStar(require("./scriptExpressions"));
|
|
73
|
-
exports.scriptExpressions = scriptExpressions;
|
|
74
|
-
const ledger_1 = require("./ledger");
|
|
75
|
-
/** @namespace */
|
|
76
|
-
exports.ledger = {
|
|
77
|
-
/** @function */
|
|
78
|
-
getLedgerMasterFingerPrint: ledger_1.getLedgerMasterFingerPrint,
|
|
79
|
-
/** @function */
|
|
80
|
-
getLedgerXpub: ledger_1.getLedgerXpub,
|
|
81
|
-
/** @function */
|
|
82
|
-
registerLedgerWallet: ledger_1.registerLedgerWallet,
|
|
83
|
-
/** @function */
|
|
84
|
-
assertLedgerApp: ledger_1.assertLedgerApp
|
|
85
|
-
};
|
package/dist/keyExpressions.d.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Network } from 'bitcoinjs-lib';
|
|
2
|
-
import type { ECPairAPI } from 'ecpair';
|
|
3
|
-
import type { BIP32API, BIP32Interface } from 'bip32';
|
|
4
|
-
import type { KeyInfo } from './types';
|
|
5
|
-
import { LedgerManager } from './ledger';
|
|
6
|
-
/**
|
|
7
|
-
* Parses a key expression (xpub, xprv, pubkey or wif) into {@link KeyInfo | `KeyInfo`}.
|
|
8
|
-
*
|
|
9
|
-
* For example, given this `keyExpression`: `"[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*"`, this is its parsed result:
|
|
10
|
-
*
|
|
11
|
-
* ```javascript
|
|
12
|
-
* {
|
|
13
|
-
* keyExpression:
|
|
14
|
-
* "[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*",
|
|
15
|
-
* keyPath: '/1/2/3/4/*',
|
|
16
|
-
* originPath: "/49'/0'/0'",
|
|
17
|
-
* path: "m/49'/0'/0'/1/2/3/4/*",
|
|
18
|
-
* // Other relevant properties of the type `KeyInfo`: `pubkey`, `ecpair` & `bip32` interfaces, `masterFingerprint`, etc.
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function parseKeyExpression({ keyExpression, isSegwit, isTaproot, ECPair, BIP32, network }: {
|
|
23
|
-
keyExpression: string;
|
|
24
|
-
/** @default networks.bitcoin */
|
|
25
|
-
network?: Network;
|
|
26
|
-
/**
|
|
27
|
-
* Indicates if this key expression belongs to a a SegWit output. When set,
|
|
28
|
-
* further checks are done to ensure the public key (if present in the
|
|
29
|
-
* expression) is compressed (33 bytes).
|
|
30
|
-
*/
|
|
31
|
-
isSegwit?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Indicates if this key expression belongs to a Taproot output. For Taproot,
|
|
34
|
-
* the key must be represented as an x-only public key (32 bytes).
|
|
35
|
-
* If a 33-byte compressed pubkey is derived, it is converted to its x-only
|
|
36
|
-
* representation.
|
|
37
|
-
*/
|
|
38
|
-
isTaproot?: boolean;
|
|
39
|
-
ECPair: ECPairAPI;
|
|
40
|
-
BIP32: BIP32API;
|
|
41
|
-
}): KeyInfo;
|
|
42
|
-
/**
|
|
43
|
-
* Constructs a key expression string for a Ledger device from the provided
|
|
44
|
-
* components.
|
|
45
|
-
*
|
|
46
|
-
* This function assists in crafting key expressions tailored for Ledger
|
|
47
|
-
* hardware wallets. It fetches the master fingerprint and xpub for a
|
|
48
|
-
* specified origin path and then combines them with the input parameters.
|
|
49
|
-
*
|
|
50
|
-
* For detailed understanding and examples of terms like `originPath`,
|
|
51
|
-
* `change`, and `keyPath`, refer to the documentation of
|
|
52
|
-
* {@link _Internal_.KeyExpressionParser | KeyExpressionParser}, which consists
|
|
53
|
-
* of the reverse procedure.
|
|
54
|
-
*
|
|
55
|
-
* @returns {string} - The formed key expression for the Ledger device.
|
|
56
|
-
*/
|
|
57
|
-
export declare function keyExpressionLedger({ ledgerManager, originPath, keyPath, change, index }: {
|
|
58
|
-
ledgerManager: LedgerManager;
|
|
59
|
-
originPath: string;
|
|
60
|
-
change?: number | undefined;
|
|
61
|
-
index?: number | undefined | '*';
|
|
62
|
-
keyPath?: string | undefined;
|
|
63
|
-
}): Promise<string>;
|
|
64
|
-
/**
|
|
65
|
-
* Constructs a key expression string from its constituent components.
|
|
66
|
-
*
|
|
67
|
-
* This function essentially performs the reverse operation of
|
|
68
|
-
* {@link _Internal_.KeyExpressionParser | KeyExpressionParser}. For detailed
|
|
69
|
-
* explanations and examples of the terms used here, refer to
|
|
70
|
-
* {@link _Internal_.KeyExpressionParser | KeyExpressionParser}.
|
|
71
|
-
*/
|
|
72
|
-
export declare function keyExpressionBIP32({ masterNode, originPath, keyPath, change, index, isPublic }: {
|
|
73
|
-
masterNode: BIP32Interface;
|
|
74
|
-
originPath: string;
|
|
75
|
-
change?: number | undefined;
|
|
76
|
-
index?: number | undefined | '*';
|
|
77
|
-
keyPath?: string | undefined;
|
|
78
|
-
/**
|
|
79
|
-
* Compute an xpub or xprv
|
|
80
|
-
* @default true
|
|
81
|
-
*/
|
|
82
|
-
isPublic?: boolean;
|
|
83
|
-
}): string;
|
package/dist/keyExpressions.js
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright (c) 2023 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
-
// Distributed under the MIT software license
|
|
4
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
-
if (k2 === undefined) k2 = k;
|
|
6
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
-
}
|
|
10
|
-
Object.defineProperty(o, k2, desc);
|
|
11
|
-
}) : (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
o[k2] = m[k];
|
|
14
|
-
}));
|
|
15
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
-
}) : function(o, v) {
|
|
18
|
-
o["default"] = v;
|
|
19
|
-
});
|
|
20
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
-
var ownKeys = function(o) {
|
|
22
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
-
var ar = [];
|
|
24
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
-
return ar;
|
|
26
|
-
};
|
|
27
|
-
return ownKeys(o);
|
|
28
|
-
};
|
|
29
|
-
return function (mod) {
|
|
30
|
-
if (mod && mod.__esModule) return mod;
|
|
31
|
-
var result = {};
|
|
32
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
-
__setModuleDefault(result, mod);
|
|
34
|
-
return result;
|
|
35
|
-
};
|
|
36
|
-
})();
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.parseKeyExpression = parseKeyExpression;
|
|
39
|
-
exports.keyExpressionLedger = keyExpressionLedger;
|
|
40
|
-
exports.keyExpressionBIP32 = keyExpressionBIP32;
|
|
41
|
-
const bitcoinjs_lib_1 = require("bitcoinjs-lib");
|
|
42
|
-
const ledger_1 = require("./ledger");
|
|
43
|
-
const uint8array_tools_1 = require("uint8array-tools");
|
|
44
|
-
const RE = __importStar(require("./re"));
|
|
45
|
-
const derivePath = (node, path) => {
|
|
46
|
-
if (typeof path !== 'string') {
|
|
47
|
-
throw new Error(`Error: invalid derivation path ${path}`);
|
|
48
|
-
}
|
|
49
|
-
const parsedPath = path.replaceAll('H', "'").replaceAll('h', "'").slice(1);
|
|
50
|
-
const splitPath = parsedPath.split('/');
|
|
51
|
-
for (const element of splitPath) {
|
|
52
|
-
const unhardened = element.endsWith("'") ? element.slice(0, -1) : element;
|
|
53
|
-
if (!Number.isInteger(Number(unhardened)) ||
|
|
54
|
-
Number(unhardened) >= 0x80000000)
|
|
55
|
-
throw new Error(`Error: BIP 32 path element overflow`);
|
|
56
|
-
}
|
|
57
|
-
return node.derivePath(parsedPath);
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Parses a key expression (xpub, xprv, pubkey or wif) into {@link KeyInfo | `KeyInfo`}.
|
|
61
|
-
*
|
|
62
|
-
* For example, given this `keyExpression`: `"[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*"`, this is its parsed result:
|
|
63
|
-
*
|
|
64
|
-
* ```javascript
|
|
65
|
-
* {
|
|
66
|
-
* keyExpression:
|
|
67
|
-
* "[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*",
|
|
68
|
-
* keyPath: '/1/2/3/4/*',
|
|
69
|
-
* originPath: "/49'/0'/0'",
|
|
70
|
-
* path: "m/49'/0'/0'/1/2/3/4/*",
|
|
71
|
-
* // Other relevant properties of the type `KeyInfo`: `pubkey`, `ecpair` & `bip32` interfaces, `masterFingerprint`, etc.
|
|
72
|
-
* }
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
function parseKeyExpression({ keyExpression, isSegwit, isTaproot, ECPair, BIP32, network = bitcoinjs_lib_1.networks.bitcoin }) {
|
|
76
|
-
if (isTaproot && isSegwit !== true)
|
|
77
|
-
throw new Error(`Error: taproot key expressions require isSegwit`);
|
|
78
|
-
let pubkey; //won't be computed for ranged keyExpressions
|
|
79
|
-
let ecpair;
|
|
80
|
-
let bip32;
|
|
81
|
-
let masterFingerprint;
|
|
82
|
-
let originPath;
|
|
83
|
-
let keyPath;
|
|
84
|
-
let path;
|
|
85
|
-
const isRanged = keyExpression.indexOf('*') !== -1;
|
|
86
|
-
const reKeyExp = isTaproot
|
|
87
|
-
? RE.reTaprootKeyExp
|
|
88
|
-
: isSegwit
|
|
89
|
-
? RE.reSegwitKeyExp
|
|
90
|
-
: RE.reNonSegwitKeyExp;
|
|
91
|
-
const rePubKey = isTaproot
|
|
92
|
-
? RE.reTaprootPubKey
|
|
93
|
-
: isSegwit
|
|
94
|
-
? RE.reSegwitPubKey
|
|
95
|
-
: RE.reNonSegwitPubKey;
|
|
96
|
-
//Validate the keyExpression:
|
|
97
|
-
const keyExpressions = keyExpression.match(reKeyExp);
|
|
98
|
-
if (keyExpressions === null || keyExpressions[0] !== keyExpression) {
|
|
99
|
-
throw new Error(`Error: expected a keyExpression but got ${keyExpression}`);
|
|
100
|
-
}
|
|
101
|
-
const reOriginAnchoredStart = RegExp(String.raw `^(${RE.reOrigin})?`); //starts with ^origin
|
|
102
|
-
const mOrigin = keyExpression.match(reOriginAnchoredStart);
|
|
103
|
-
if (mOrigin) {
|
|
104
|
-
const bareOrigin = mOrigin[0].replace(/[[\]]/g, ''); //strip the "[" and "]" in [origin]
|
|
105
|
-
const reMasterFingerprintAnchoredStart = String.raw `^(${RE.reMasterFingerprint})`;
|
|
106
|
-
const mMasterFingerprint = bareOrigin.match(reMasterFingerprintAnchoredStart);
|
|
107
|
-
const masterFingerprintHex = mMasterFingerprint
|
|
108
|
-
? mMasterFingerprint[0]
|
|
109
|
-
: '';
|
|
110
|
-
originPath = bareOrigin.replace(masterFingerprintHex, '');
|
|
111
|
-
if (masterFingerprintHex.length > 0) {
|
|
112
|
-
if (masterFingerprintHex.length !== 8)
|
|
113
|
-
throw new Error(`Error: masterFingerprint ${masterFingerprintHex} invalid for keyExpression: ${keyExpression}`);
|
|
114
|
-
masterFingerprint = (0, uint8array_tools_1.fromHex)(masterFingerprintHex);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
//Remove the origin (if it exists) and store result in actualKey
|
|
118
|
-
const actualKey = keyExpression.replace(reOriginAnchoredStart, '');
|
|
119
|
-
let mPubKey, mWIF, mXpubKey, mXprvKey;
|
|
120
|
-
//match pubkey:
|
|
121
|
-
if ((mPubKey = actualKey.match(RE.anchorStartAndEnd(rePubKey))) !== null) {
|
|
122
|
-
pubkey = (0, uint8array_tools_1.fromHex)(mPubKey[0]);
|
|
123
|
-
if (isTaproot && pubkey.length === 32)
|
|
124
|
-
//convert the xonly point to a compressed point assuming even parity
|
|
125
|
-
pubkey = (0, uint8array_tools_1.concat)([Uint8Array.from([0x02]), pubkey]);
|
|
126
|
-
ecpair = ECPair.fromPublicKey(pubkey, { network });
|
|
127
|
-
//Validate the pubkey (compressed or uncompressed)
|
|
128
|
-
if (!ECPair.isPoint(pubkey) ||
|
|
129
|
-
!(pubkey.length === 33 || pubkey.length === 65)) {
|
|
130
|
-
throw new Error(`Error: invalid pubkey`);
|
|
131
|
-
}
|
|
132
|
-
//Do an extra check in case we know this pubkey refers to a segwit input
|
|
133
|
-
//Taproot x-only keys are converted to 33-byte compressed form above.
|
|
134
|
-
if (typeof isSegwit === 'boolean' &&
|
|
135
|
-
isSegwit &&
|
|
136
|
-
pubkey.length !== 33 //Inside wpkh and wsh, only compressed public keys are permitted.
|
|
137
|
-
) {
|
|
138
|
-
throw new Error(`Error: invalid pubkey`);
|
|
139
|
-
}
|
|
140
|
-
//match WIF:
|
|
141
|
-
}
|
|
142
|
-
else if ((mWIF = actualKey.match(RE.anchorStartAndEnd(RE.reWIF))) !== null) {
|
|
143
|
-
ecpair = ECPair.fromWIF(mWIF[0], network);
|
|
144
|
-
//fromWIF will throw if the wif is not valid
|
|
145
|
-
pubkey = ecpair.publicKey;
|
|
146
|
-
//match xpub:
|
|
147
|
-
}
|
|
148
|
-
else if ((mXpubKey = actualKey.match(RE.anchorStartAndEnd(RE.reXpubKey))) !== null) {
|
|
149
|
-
const xPubKey = mXpubKey[0];
|
|
150
|
-
const xPub = xPubKey.match(RE.reXpub)?.[0];
|
|
151
|
-
if (!xPub)
|
|
152
|
-
throw new Error(`Error: xpub could not be matched`);
|
|
153
|
-
bip32 = BIP32.fromBase58(xPub, network);
|
|
154
|
-
const mPath = xPubKey.match(RE.rePath);
|
|
155
|
-
if (mPath !== null) {
|
|
156
|
-
keyPath = xPubKey.match(RE.rePath)?.[0];
|
|
157
|
-
if (!keyPath)
|
|
158
|
-
throw new Error(`Error: could not extract a path`);
|
|
159
|
-
//fromBase58 and derivePath will throw if xPub or path are not valid
|
|
160
|
-
if (!isRanged)
|
|
161
|
-
pubkey = derivePath(bip32, keyPath).publicKey;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
pubkey = bip32.publicKey;
|
|
165
|
-
}
|
|
166
|
-
//match xprv:
|
|
167
|
-
}
|
|
168
|
-
else if ((mXprvKey = actualKey.match(RE.anchorStartAndEnd(RE.reXprvKey))) !== null) {
|
|
169
|
-
const xPrvKey = mXprvKey[0];
|
|
170
|
-
const xPrv = xPrvKey.match(RE.reXprv)?.[0];
|
|
171
|
-
if (!xPrv)
|
|
172
|
-
throw new Error(`Error: xprv could not be matched`);
|
|
173
|
-
bip32 = BIP32.fromBase58(xPrv, network);
|
|
174
|
-
const mPath = xPrvKey.match(RE.rePath);
|
|
175
|
-
if (mPath !== null) {
|
|
176
|
-
keyPath = xPrvKey.match(RE.rePath)?.[0];
|
|
177
|
-
if (!keyPath)
|
|
178
|
-
throw new Error(`Error: could not extract a path`);
|
|
179
|
-
//fromBase58 and derivePath will throw if xPrv or path are not valid
|
|
180
|
-
if (!isRanged)
|
|
181
|
-
pubkey = derivePath(bip32, keyPath).publicKey;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
pubkey = bip32.publicKey;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
throw new Error(`Error: could not get pubkey for keyExpression ${keyExpression}`);
|
|
189
|
-
}
|
|
190
|
-
if (originPath || keyPath) {
|
|
191
|
-
path = `m${originPath ?? ''}${keyPath ?? ''}`;
|
|
192
|
-
}
|
|
193
|
-
if (pubkey !== undefined && isTaproot && pubkey.length === 33)
|
|
194
|
-
// If we get a 33-byte compressed key, drop the first byte.
|
|
195
|
-
pubkey = pubkey.slice(1, 33);
|
|
196
|
-
return {
|
|
197
|
-
keyExpression,
|
|
198
|
-
...(pubkey !== undefined ? { pubkey } : {}),
|
|
199
|
-
...(ecpair !== undefined ? { ecpair } : {}),
|
|
200
|
-
...(bip32 !== undefined ? { bip32 } : {}),
|
|
201
|
-
...(masterFingerprint !== undefined ? { masterFingerprint } : {}),
|
|
202
|
-
...(originPath !== undefined && originPath !== '' ? { originPath } : {}),
|
|
203
|
-
...(keyPath !== undefined && keyPath !== '' ? { keyPath } : {}),
|
|
204
|
-
...(path !== undefined ? { path } : {})
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
function assertChangeIndexKeyPath({ change, index, keyPath }) {
|
|
208
|
-
if (!((change === undefined && index === undefined) ||
|
|
209
|
-
(change !== undefined && index !== undefined)))
|
|
210
|
-
throw new Error(`Error: Pass change and index or neither`);
|
|
211
|
-
if ((change !== undefined) === (keyPath !== undefined))
|
|
212
|
-
throw new Error(`Error: Pass either change and index or a keyPath`);
|
|
213
|
-
}
|
|
214
|
-
/** @hidden */
|
|
215
|
-
async function keyExpressionLedger({ ledgerManager, originPath, keyPath, change, index }) {
|
|
216
|
-
assertChangeIndexKeyPath({ change, index, keyPath });
|
|
217
|
-
const masterFingerprint = await (0, ledger_1.getLedgerMasterFingerPrint)({
|
|
218
|
-
ledgerManager
|
|
219
|
-
});
|
|
220
|
-
const origin = `[${(0, uint8array_tools_1.toHex)(masterFingerprint)}${originPath}]`;
|
|
221
|
-
const xpub = await (0, ledger_1.getLedgerXpub)({ originPath, ledgerManager });
|
|
222
|
-
const keyRoot = `${origin}${xpub}`;
|
|
223
|
-
if (keyPath !== undefined)
|
|
224
|
-
return `${keyRoot}${keyPath}`;
|
|
225
|
-
else
|
|
226
|
-
return `${keyRoot}/${change}/${index}`;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Constructs a key expression string from its constituent components.
|
|
230
|
-
*
|
|
231
|
-
* This function essentially performs the reverse operation of
|
|
232
|
-
* {@link _Internal_.KeyExpressionParser | KeyExpressionParser}. For detailed
|
|
233
|
-
* explanations and examples of the terms used here, refer to
|
|
234
|
-
* {@link _Internal_.KeyExpressionParser | KeyExpressionParser}.
|
|
235
|
-
*/
|
|
236
|
-
function keyExpressionBIP32({ masterNode, originPath, keyPath, change, index, isPublic = true }) {
|
|
237
|
-
assertChangeIndexKeyPath({ change, index, keyPath });
|
|
238
|
-
const masterFingerprint = masterNode.fingerprint;
|
|
239
|
-
const origin = `[${(0, uint8array_tools_1.toHex)(masterFingerprint)}${originPath}]`;
|
|
240
|
-
const xpub = isPublic
|
|
241
|
-
? masterNode.derivePath(`m${originPath}`).neutered().toBase58().toString()
|
|
242
|
-
: masterNode.derivePath(`m${originPath}`).toBase58().toString();
|
|
243
|
-
const keyRoot = `${origin}${xpub}`;
|
|
244
|
-
if (keyPath !== undefined)
|
|
245
|
-
return `${keyRoot}${keyPath}`;
|
|
246
|
-
else
|
|
247
|
-
return `${keyRoot}/${change}/${index}`;
|
|
248
|
-
}
|
package/dist/ledger.d.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { OutputInstance } from './descriptors';
|
|
2
|
-
import { Network, Psbt } from 'bitcoinjs-lib';
|
|
3
|
-
import type { TinySecp256k1Interface } from './types';
|
|
4
|
-
/**
|
|
5
|
-
* Dynamically imports the '@ledgerhq/ledger-bitcoin' module and, if provided, checks if `ledgerClient` is an instance of `AppClient`.
|
|
6
|
-
*
|
|
7
|
-
* @async
|
|
8
|
-
* @param {unknown} ledgerClient - An optional parameter that, if provided, is checked to see if it's an instance of `AppClient`.
|
|
9
|
-
* @throws {Error} Throws an error if `ledgerClient` is provided but is not an instance of `AppClient`.
|
|
10
|
-
* @throws {Error} Throws an error if the '@ledgerhq/ledger-bitcoin' module cannot be imported. This typically indicates that the '@ledgerhq/ledger-bitcoin' peer dependency is not installed.
|
|
11
|
-
* @returns {Promise<unknown>} Returns a promise that resolves with the entire '@ledgerhq/ledger-bitcoin' module if it can be successfully imported. We force it to return an unknown type so that the declaration of this function won't break projects that don't use @ledgerhq/ledger-bitcoin as dependency
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
*
|
|
15
|
-
* importAndValidateLedgerBitcoin(ledgerClient)
|
|
16
|
-
* .then((module) => {
|
|
17
|
-
* const { AppClient, PsbtV2, DefaultWalletPolicy, WalletPolicy, DefaultDescriptorTemplate, PartialSignature } = module;
|
|
18
|
-
* // Use the imported objects...
|
|
19
|
-
* })
|
|
20
|
-
* .catch((error) => console.error(error));
|
|
21
|
-
*/
|
|
22
|
-
export declare function importAndValidateLedgerBitcoin(ledgerClient?: unknown): Promise<unknown>;
|
|
23
|
-
/**
|
|
24
|
-
* Verifies if the Ledger device is connected, if the required Bitcoin App is opened,
|
|
25
|
-
* and if the version of the app meets the minimum requirements.
|
|
26
|
-
*
|
|
27
|
-
* @throws Will throw an error if the Ledger device is not connected, the required
|
|
28
|
-
* Bitcoin App is not opened, or if the version is below the required number.
|
|
29
|
-
*
|
|
30
|
-
* @returns Promise<void> - A promise that resolves if all assertions pass, or throws otherwise.
|
|
31
|
-
*/
|
|
32
|
-
export declare function assertLedgerApp({ transport, name, minVersion }: {
|
|
33
|
-
/**
|
|
34
|
-
* Connection transport with the Ledger device.
|
|
35
|
-
* One of these: https://github.com/LedgerHQ/ledger-live#libs---libraries
|
|
36
|
-
*/
|
|
37
|
-
transport: any;
|
|
38
|
-
/**
|
|
39
|
-
* The name of the Bitcoin App. "Bitcoin" for mainnet or "Bitcoin Test" for testnet.
|
|
40
|
-
*/
|
|
41
|
-
name: string;
|
|
42
|
-
/**
|
|
43
|
-
* The minimum acceptable version of the Bitcoin App in semver format (major.minor.patch).
|
|
44
|
-
*/
|
|
45
|
-
minVersion: string;
|
|
46
|
-
}): Promise<void>;
|
|
47
|
-
export type LedgerPolicy = {
|
|
48
|
-
policyName?: string;
|
|
49
|
-
ledgerTemplate: string;
|
|
50
|
-
keyRoots: string[];
|
|
51
|
-
policyId?: Uint8Array;
|
|
52
|
-
policyHmac?: Uint8Array;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* Ledger devices operate in a state-less manner. Therefore, policy information
|
|
56
|
-
* needs to be maintained in a separate data structure, `ledgerState`. For optimization,
|
|
57
|
-
* `ledgerState` also stores cached xpubs and the masterFingerprint.
|
|
58
|
-
*/
|
|
59
|
-
export type LedgerState = {
|
|
60
|
-
masterFingerprint?: Uint8Array;
|
|
61
|
-
policies?: LedgerPolicy[];
|
|
62
|
-
xpubs?: {
|
|
63
|
-
[key: string]: string;
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
export type LedgerManager = {
|
|
67
|
-
ledgerClient: unknown;
|
|
68
|
-
ledgerState: LedgerState;
|
|
69
|
-
ecc: TinySecp256k1Interface;
|
|
70
|
-
network: Network;
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Retrieves the masterFingerPrint of a Ledger device
|
|
74
|
-
*/
|
|
75
|
-
export declare function getLedgerMasterFingerPrint({ ledgerManager }: {
|
|
76
|
-
ledgerManager: LedgerManager;
|
|
77
|
-
}): Promise<Uint8Array>;
|
|
78
|
-
/**
|
|
79
|
-
* Retrieves the xpub of a certain originPath of a Ledger device
|
|
80
|
-
*/
|
|
81
|
-
export declare function getLedgerXpub({ originPath, ledgerManager }: {
|
|
82
|
-
originPath: string;
|
|
83
|
-
ledgerManager: LedgerManager;
|
|
84
|
-
}): Promise<string>;
|
|
85
|
-
/**
|
|
86
|
-
* Checks whether there is a policy in ledgerState that the ledger
|
|
87
|
-
* could use to sign this psbt input.
|
|
88
|
-
*
|
|
89
|
-
* It found return the policy, otherwise, return undefined
|
|
90
|
-
*
|
|
91
|
-
* All considerations in the header of this file are applied
|
|
92
|
-
*/
|
|
93
|
-
export declare function ledgerPolicyFromPsbtInput({ ledgerManager, psbt, index }: {
|
|
94
|
-
ledgerManager: LedgerManager;
|
|
95
|
-
psbt: Psbt;
|
|
96
|
-
index: number;
|
|
97
|
-
}): Promise<LedgerPolicy | undefined>;
|
|
98
|
-
/**
|
|
99
|
-
* Given an output, it extracts its descriptor and converts it to a Ledger
|
|
100
|
-
* Wallet Policy, that is, its keyRoots and template.
|
|
101
|
-
*
|
|
102
|
-
* keyRoots and template follow Ledger's specifications:
|
|
103
|
-
* https://github.com/LedgerHQ/app-bitcoin-new/blob/develop/doc/wallet.md
|
|
104
|
-
*
|
|
105
|
-
* keyRoots and template are a generalization of a descriptor and serve to
|
|
106
|
-
* describe internal and external addresses and any index.
|
|
107
|
-
*
|
|
108
|
-
* So, this function starts from a descriptor and obtains generalized Ledger
|
|
109
|
-
* wallet policy.
|
|
110
|
-
*
|
|
111
|
-
* keyRoots is an array of strings, encoding xpub-type key expressions up to the origin.
|
|
112
|
-
* F.ex.: [76223a6e/48'/1'/0'/2']tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF
|
|
113
|
-
*
|
|
114
|
-
* Template encodes the descriptor script expression, where its key
|
|
115
|
-
* expressions are represented using variables for each keyRoot and finished with "/**"
|
|
116
|
-
* (for change 1 or 0 and any index). F.ex.:
|
|
117
|
-
* wsh(sortedmulti(2,@0/**,@1/**)), where @0 corresponds the first element in the keyRoots array.
|
|
118
|
-
*
|
|
119
|
-
* If this descriptor does not contain any key that can be signed with the ledger
|
|
120
|
-
* (non-matching masterFingerprint), then this function returns null.
|
|
121
|
-
*
|
|
122
|
-
* This function takes into account all the considerations regarding Ledger
|
|
123
|
-
* policy implementation details expressed in the header of this file.
|
|
124
|
-
*/
|
|
125
|
-
export declare function ledgerPolicyFromOutput({ output, ledgerManager }: {
|
|
126
|
-
output: OutputInstance;
|
|
127
|
-
ledgerManager: LedgerManager;
|
|
128
|
-
}): Promise<{
|
|
129
|
-
ledgerTemplate: string;
|
|
130
|
-
keyRoots: string[];
|
|
131
|
-
} | null>;
|
|
132
|
-
/**
|
|
133
|
-
* Registers a policy based on a provided descriptor.
|
|
134
|
-
*
|
|
135
|
-
* This function will:
|
|
136
|
-
* 1. Store the policy in `ledgerState` inside the `ledgerManager`.
|
|
137
|
-
* 2. Avoid re-registering if the policy was previously registered.
|
|
138
|
-
* 3. Skip registration if the policy is considered "standard".
|
|
139
|
-
*
|
|
140
|
-
* It's important to understand the nature of the Ledger Policy being registered:
|
|
141
|
-
* - While a descriptor might point to a specific output index of a particular change address,
|
|
142
|
-
* the corresponding Ledger Policy abstracts this and represents potential outputs for
|
|
143
|
-
* all addresses (both external and internal).
|
|
144
|
-
* - This means that the registered Ledger Policy is a generalized version of the descriptor,
|
|
145
|
-
* not assuming specific values for the keyPath.
|
|
146
|
-
*/
|
|
147
|
-
export declare function registerLedgerWallet({ descriptor, ledgerManager, policyName }: {
|
|
148
|
-
descriptor: string;
|
|
149
|
-
ledgerManager: LedgerManager;
|
|
150
|
-
/** The Name we want to assign to this specific policy */
|
|
151
|
-
policyName: string;
|
|
152
|
-
}): Promise<void>;
|
|
153
|
-
/**
|
|
154
|
-
* Retrieve a standard ledger policy or null if it does correspond.
|
|
155
|
-
**/
|
|
156
|
-
export declare function ledgerPolicyFromStandard({ output, ledgerManager }: {
|
|
157
|
-
output: OutputInstance;
|
|
158
|
-
ledgerManager: LedgerManager;
|
|
159
|
-
}): Promise<LedgerPolicy | null>;
|
|
160
|
-
export declare function comparePolicies(policyA: LedgerPolicy, policyB: LedgerPolicy): boolean;
|
|
161
|
-
/**
|
|
162
|
-
* Retrieve a ledger policy from ledgerState or null if it does not exist yet.
|
|
163
|
-
**/
|
|
164
|
-
export declare function ledgerPolicyFromState({ output, ledgerManager }: {
|
|
165
|
-
output: OutputInstance;
|
|
166
|
-
ledgerManager: LedgerManager;
|
|
167
|
-
}): Promise<LedgerPolicy | null>;
|