@bitcoinerlab/descriptors 3.0.6 → 3.1.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.
Files changed (44) hide show
  1. package/README.md +9 -487
  2. package/index.d.ts +13 -0
  3. package/index.js +27 -0
  4. package/package.json +25 -52
  5. package/dist/applyPR2137.d.ts +0 -2
  6. package/dist/applyPR2137.js +0 -153
  7. package/dist/bitcoinjs-lib-internals.d.ts +0 -10
  8. package/dist/bitcoinjs-lib-internals.js +0 -60
  9. package/dist/checksum.d.ts +0 -6
  10. package/dist/checksum.js +0 -58
  11. package/dist/descriptors.d.ts +0 -433
  12. package/dist/descriptors.js +0 -1743
  13. package/dist/index.d.ts +0 -21
  14. package/dist/index.js +0 -85
  15. package/dist/keyExpressions.d.ts +0 -83
  16. package/dist/keyExpressions.js +0 -247
  17. package/dist/ledger.d.ts +0 -167
  18. package/dist/ledger.js +0 -580
  19. package/dist/miniscript.d.ts +0 -123
  20. package/dist/miniscript.js +0 -305
  21. package/dist/multipath.d.ts +0 -13
  22. package/dist/multipath.js +0 -76
  23. package/dist/networkUtils.d.ts +0 -3
  24. package/dist/networkUtils.js +0 -16
  25. package/dist/parseUtils.d.ts +0 -7
  26. package/dist/parseUtils.js +0 -46
  27. package/dist/psbt.d.ts +0 -44
  28. package/dist/psbt.js +0 -193
  29. package/dist/re.d.ts +0 -31
  30. package/dist/re.js +0 -79
  31. package/dist/resourceLimits.d.ts +0 -25
  32. package/dist/resourceLimits.js +0 -89
  33. package/dist/scriptExpressions.d.ts +0 -95
  34. package/dist/scriptExpressions.js +0 -89
  35. package/dist/signers.d.ts +0 -84
  36. package/dist/signers.js +0 -215
  37. package/dist/stackResourceLimits.d.ts +0 -17
  38. package/dist/stackResourceLimits.js +0 -35
  39. package/dist/tapMiniscript.d.ts +0 -220
  40. package/dist/tapMiniscript.js +0 -510
  41. package/dist/tapTree.d.ts +0 -86
  42. package/dist/tapTree.js +0 -166
  43. package/dist/types.d.ts +0 -238
  44. package/dist/types.js +0 -4
package/dist/psbt.js DELETED
@@ -1,193 +0,0 @@
1
- "use strict";
2
- // Copyright (c) 2025 Jose-Luis Landabaso - https://bitcoinerlab.com
3
- // Distributed under the MIT software license
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.finalScriptsFuncFactory = finalScriptsFuncFactory;
6
- exports.addPsbtInput = addPsbtInput;
7
- const bitcoinjs_lib_1 = require("bitcoinjs-lib");
8
- const uint8array_tools_1 = require("uint8array-tools");
9
- const bitcoinjs_lib_internals_1 = require("./bitcoinjs-lib-internals");
10
- function reverseBytes(buffer) {
11
- if (buffer.length < 1)
12
- return buffer;
13
- const copy = Uint8Array.from(buffer);
14
- let j = copy.length - 1;
15
- let tmp = 0;
16
- for (let i = 0; i < copy.length / 2; i++) {
17
- tmp = copy[i];
18
- copy[i] = copy[j];
19
- copy[j] = tmp;
20
- j--;
21
- }
22
- return copy;
23
- }
24
- function finalScriptsFuncFactory(scriptSatisfaction, network) {
25
- const finalScriptsFunc = (_index, _input, lockingScript /*witnessScript or redeemScript*/, isSegwit, isP2SH, _isP2WSH) => {
26
- let finalScriptWitness;
27
- let finalScriptSig;
28
- //p2wsh
29
- if (isSegwit && !isP2SH) {
30
- const payment = bitcoinjs_lib_1.payments.p2wsh({
31
- redeem: { input: scriptSatisfaction, output: lockingScript },
32
- network
33
- });
34
- if (!payment.witness)
35
- throw new Error(`Error: p2wsh failed producing a witness`);
36
- finalScriptWitness = (0, bitcoinjs_lib_internals_1.witnessStackToScriptWitness)(payment.witness);
37
- }
38
- //p2sh-p2wsh
39
- else if (isSegwit && isP2SH) {
40
- const payment = bitcoinjs_lib_1.payments.p2sh({
41
- redeem: bitcoinjs_lib_1.payments.p2wsh({
42
- redeem: { input: scriptSatisfaction, output: lockingScript },
43
- network
44
- }),
45
- network
46
- });
47
- if (!payment.witness)
48
- throw new Error(`Error: p2sh-p2wsh failed producing a witness`);
49
- finalScriptWitness = (0, bitcoinjs_lib_internals_1.witnessStackToScriptWitness)(payment.witness);
50
- finalScriptSig = payment.input;
51
- }
52
- //p2sh
53
- else {
54
- finalScriptSig = bitcoinjs_lib_1.payments.p2sh({
55
- redeem: { input: scriptSatisfaction, output: lockingScript },
56
- network
57
- }).input;
58
- }
59
- return {
60
- finalScriptWitness,
61
- finalScriptSig
62
- };
63
- };
64
- return finalScriptsFunc;
65
- }
66
- /**
67
- * Important: Read comments on Output.updatePsbtAsInput regarding not passing txHex
68
- */
69
- function addPsbtInput({ psbt, vout, txHex, txId, value, sequence, locktime, keysInfo, scriptPubKey, isSegwit, tapInternalKey, tapLeafScript, tapBip32Derivation, witnessScript, redeemScript, rbf }) {
70
- if (value !== undefined && typeof value !== 'bigint')
71
- throw new Error(`Error: value must be a bigint`);
72
- if (value !== undefined && value < 0n)
73
- throw new Error(`Error: value must be >= 0n`);
74
- let normalizedValue = value;
75
- //Some data-sanity checks:
76
- if (sequence !== undefined && rbf && sequence > 0xfffffffd)
77
- throw new Error(`Error: incompatible sequence and rbf settings`);
78
- if (!isSegwit && txHex === undefined)
79
- throw new Error(`Error: txHex is mandatory for Non-Segwit inputs`);
80
- if (isSegwit &&
81
- txHex === undefined &&
82
- (txId === undefined || value === undefined))
83
- throw new Error(`Error: pass txHex or txId+value for Segwit inputs`);
84
- if (txHex !== undefined) {
85
- const tx = bitcoinjs_lib_1.Transaction.fromHex(txHex);
86
- const out = tx?.outs?.[vout];
87
- if (!out)
88
- throw new Error(`Error: tx ${txHex} does not have vout ${vout}`);
89
- const outputScript = out.script;
90
- if (!outputScript)
91
- throw new Error(`Error: could not extract outputScript for txHex ${txHex} and vout ${vout}`);
92
- if ((0, uint8array_tools_1.compare)(outputScript, scriptPubKey) !== 0)
93
- throw new Error(`Error: txHex ${txHex} for vout ${vout} does not correspond to scriptPubKey ${scriptPubKey}`);
94
- if (txId !== undefined) {
95
- if (tx.getId() !== txId)
96
- throw new Error(`Error: txId for ${txHex} and vout ${vout} does not correspond to ${txId}`);
97
- }
98
- else {
99
- txId = tx.getId();
100
- }
101
- if (normalizedValue !== undefined) {
102
- if (out.value !== normalizedValue)
103
- throw new Error(`Error: value for ${txHex} and vout ${vout} does not correspond to ${value}`);
104
- }
105
- else {
106
- normalizedValue = out.value;
107
- }
108
- }
109
- if (txId === undefined || normalizedValue === undefined)
110
- throw new Error(`Error: txHex+vout required. Alternatively, but ONLY for Segwit inputs, txId+value can also be passed.`);
111
- if (locktime) {
112
- if (psbt.locktime && psbt.locktime !== locktime)
113
- throw new Error(`Error: transaction locktime was already set with a different value: ${locktime} != ${psbt.locktime}`);
114
- // nLockTime only works if at least one of the transaction inputs has an
115
- // nSequence value that is below 0xffffffff. Let's make sure that at least
116
- // this input's sequence < 0xffffffff
117
- if (sequence === undefined) {
118
- //NOTE: if sequence is undefined, bitcoinjs-lib uses 0xffffffff as default
119
- sequence = rbf ? 0xfffffffd : 0xfffffffe;
120
- }
121
- else if (sequence > 0xfffffffe) {
122
- throw new Error(`Error: incompatible sequence: ${sequence} and locktime: ${locktime}`);
123
- }
124
- if (sequence === undefined && rbf)
125
- sequence = 0xfffffffd;
126
- psbt.setLocktime(locktime);
127
- }
128
- else {
129
- if (sequence === undefined) {
130
- if (rbf)
131
- sequence = 0xfffffffd;
132
- else
133
- sequence = 0xffffffff;
134
- }
135
- }
136
- const input = {
137
- hash: reverseBytes((0, uint8array_tools_1.fromHex)(txId)),
138
- index: vout
139
- };
140
- if (txHex !== undefined) {
141
- input.nonWitnessUtxo = bitcoinjs_lib_1.Transaction.fromHex(txHex).toBuffer();
142
- }
143
- if (tapInternalKey) {
144
- //Taproot
145
- const fallbackTapBip32Derivation = keysInfo
146
- .filter((keyInfo) => keyInfo.pubkey && keyInfo.masterFingerprint && keyInfo.path)
147
- .map((keyInfo) => {
148
- const pubkey = keyInfo.pubkey;
149
- if (!pubkey)
150
- throw new Error(`key ${keyInfo.keyExpression} missing pubkey`);
151
- return {
152
- masterFingerprint: keyInfo.masterFingerprint,
153
- pubkey,
154
- path: keyInfo.path,
155
- leafHashes: []
156
- };
157
- });
158
- const resolvedTapBip32Derivation = tapBip32Derivation || fallbackTapBip32Derivation;
159
- if (resolvedTapBip32Derivation.length)
160
- input.tapBip32Derivation = resolvedTapBip32Derivation;
161
- input.tapInternalKey = tapInternalKey;
162
- if (tapLeafScript && tapLeafScript.length > 0)
163
- input.tapLeafScript = tapLeafScript;
164
- }
165
- else {
166
- const bip32Derivation = keysInfo
167
- .filter((keyInfo) => keyInfo.pubkey && keyInfo.masterFingerprint && keyInfo.path)
168
- .map((keyInfo) => {
169
- const pubkey = keyInfo.pubkey;
170
- if (!pubkey)
171
- throw new Error(`key ${keyInfo.keyExpression} missing pubkey`);
172
- return {
173
- masterFingerprint: keyInfo.masterFingerprint,
174
- pubkey,
175
- path: keyInfo.path
176
- };
177
- });
178
- if (bip32Derivation.length)
179
- input.bip32Derivation = bip32Derivation;
180
- }
181
- if (isSegwit && txHex !== undefined) {
182
- //There's no need to put both witnessUtxo and nonWitnessUtxo
183
- input.witnessUtxo = { script: scriptPubKey, value: normalizedValue };
184
- }
185
- if (sequence !== undefined)
186
- input.sequence = sequence;
187
- if (witnessScript)
188
- input.witnessScript = witnessScript;
189
- if (redeemScript)
190
- input.redeemScript = redeemScript;
191
- psbt.addInput(input);
192
- return psbt.data.inputs.length - 1;
193
- }
package/dist/re.d.ts DELETED
@@ -1,31 +0,0 @@
1
- export declare const reOriginPath: string;
2
- export declare const reMasterFingerprint: string;
3
- export declare const reOrigin: string;
4
- export declare const reChecksum: string;
5
- export declare const reNonSegwitPubKey: string;
6
- export declare const reSegwitPubKey: string;
7
- export declare const reTaprootPubKey: string;
8
- export declare const reWIF: string;
9
- export declare const reXpub: string;
10
- export declare const reXprv: string;
11
- export declare const rePath: string;
12
- export declare const reXpubKey: string;
13
- export declare const reXprvKey: string;
14
- export declare const reNonSegwitKeyExp: string;
15
- export declare const reSegwitKeyExp: string;
16
- export declare const reTaprootKeyExp: string;
17
- export declare const reNonSegwitSortedMulti: string;
18
- export declare const reSegwitSortedMulti: string;
19
- export declare const anchorStartAndEnd: (re: string) => string;
20
- export declare const rePkAnchored: string;
21
- export declare const reAddrAnchored: string;
22
- export declare const rePkhAnchored: string;
23
- export declare const reWpkhAnchored: string;
24
- export declare const reShWpkhAnchored: string;
25
- export declare const reTrSingleKeyAnchored: string;
26
- export declare const reShSortedMultiAnchored: string;
27
- export declare const reWshSortedMultiAnchored: string;
28
- export declare const reShWshSortedMultiAnchored: string;
29
- export declare const reShMiniscriptAnchored: string;
30
- export declare const reShWshMiniscriptAnchored: string;
31
- export declare const reWshMiniscriptAnchored: string;
package/dist/re.js DELETED
@@ -1,79 +0,0 @@
1
- "use strict";
2
- // Copyright (c) 2025 Jose-Luis Landabaso - https://bitcoinerlab.com
3
- // Distributed under the MIT software license
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.reWshMiniscriptAnchored = exports.reShWshMiniscriptAnchored = exports.reShMiniscriptAnchored = exports.reShWshSortedMultiAnchored = exports.reWshSortedMultiAnchored = exports.reShSortedMultiAnchored = exports.reTrSingleKeyAnchored = exports.reShWpkhAnchored = exports.reWpkhAnchored = exports.rePkhAnchored = exports.reAddrAnchored = exports.rePkAnchored = exports.anchorStartAndEnd = exports.reSegwitSortedMulti = exports.reNonSegwitSortedMulti = exports.reTaprootKeyExp = exports.reSegwitKeyExp = exports.reNonSegwitKeyExp = exports.reXprvKey = exports.reXpubKey = exports.rePath = exports.reXprv = exports.reXpub = exports.reWIF = exports.reTaprootPubKey = exports.reSegwitPubKey = exports.reNonSegwitPubKey = exports.reChecksum = exports.reOrigin = exports.reMasterFingerprint = exports.reOriginPath = void 0;
6
- const checksum_1 = require("./checksum");
7
- //Regular expressions cheat sheet:
8
- //https://www.keycdn.com/support/regex-cheat-sheet
9
- //hardened characters
10
- const reHardened = String.raw `(['hH])`;
11
- //a level is a series of integers followed (optional) by a hardener char
12
- const reLevel = String.raw `(\d+${reHardened}?)`;
13
- //a path component is a level followed by a slash "/" char
14
- const rePathComponent = String.raw `(${reLevel}\/)`;
15
- //A path formed by a series of path components that can be hardened: /2'/23H/23
16
- exports.reOriginPath = String.raw `(\/${rePathComponent}*${reLevel})`; //The "*" means: "match 0 or more of the previous"
17
- //an origin is something like this: [d34db33f/44'/0'/0'] where the path is optional. The fingerPrint is 8 chars hex
18
- exports.reMasterFingerprint = String.raw `[0-9a-fA-F]{8}`;
19
- exports.reOrigin = String.raw `(\[${exports.reMasterFingerprint}(${exports.reOriginPath})?\])`;
20
- exports.reChecksum = String.raw `(#[${checksum_1.CHECKSUM_CHARSET}]{8})`;
21
- //Something like this: 0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2
22
- //as explained here: github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#reference
23
- const reCompressedPubKey = String.raw `((02|03)[0-9a-fA-F]{64})`;
24
- const reUncompressedPubKey = String.raw `(04[0-9a-fA-F]{128})`;
25
- const reXOnlyPubKey = String.raw `([0-9a-fA-F]{64})`;
26
- exports.reNonSegwitPubKey = String.raw `(${reCompressedPubKey}|${reUncompressedPubKey})`;
27
- exports.reSegwitPubKey = String.raw `(${reCompressedPubKey})`;
28
- exports.reTaprootPubKey = String.raw `(${reCompressedPubKey}|${reXOnlyPubKey})`;
29
- //https://learnmeabitcoin.com/technical/wif
30
- //5, K, L for mainnet, 5: uncompressed, {K, L}: compressed
31
- //c, 9, testnet, c: compressed, 9: uncompressed
32
- exports.reWIF = String.raw `([5KLc9][1-9A-HJ-NP-Za-km-z]{50,51})`;
33
- //x for mainnet, t for testnet
34
- exports.reXpub = String.raw `([xXtT]pub[1-9A-HJ-NP-Za-km-z]{79,108})`;
35
- exports.reXprv = String.raw `([xXtT]prv[1-9A-HJ-NP-Za-km-z]{79,108})`;
36
- //reRangeLevel is like reLevel but using a wildcard "*"
37
- const reRangeLevel = String.raw `(\*(${reHardened})?)`;
38
- //A path can be finished with stuff like this: /23 or /23h or /* or /*'
39
- exports.rePath = String.raw `(\/(${rePathComponent})*(${reRangeLevel}|${reLevel}))`;
40
- //rePath is optional (note the "zero"): Followed by zero or more /NUM or /NUM' path elements to indicate unhardened or hardened derivation steps between the fingerprint and the key or xpub/xprv root that follows
41
- exports.reXpubKey = String.raw `(${exports.reXpub})(${exports.rePath})?`;
42
- exports.reXprvKey = String.raw `(${exports.reXprv})(${exports.rePath})?`;
43
- //actualKey is the keyExpression without optional origin
44
- const reNonSegwitActualKey = String.raw `(${exports.reXpubKey}|${exports.reXprvKey}|${exports.reNonSegwitPubKey}|${exports.reWIF})`;
45
- const reSegwitActualKey = String.raw `(${exports.reXpubKey}|${exports.reXprvKey}|${exports.reSegwitPubKey}|${exports.reWIF})`;
46
- const reTaprootActualKey = String.raw `(${exports.reXpubKey}|${exports.reXprvKey}|${exports.reTaprootPubKey}|${exports.reWIF})`;
47
- //reOrigin is optional: Optionally, key origin information, consisting of:
48
- //Matches a key expression: wif, xpub, xprv or pubkey:
49
- exports.reNonSegwitKeyExp = String.raw `(${exports.reOrigin})?(${reNonSegwitActualKey})`;
50
- exports.reSegwitKeyExp = String.raw `(${exports.reOrigin})?(${reSegwitActualKey})`;
51
- exports.reTaprootKeyExp = String.raw `(${exports.reOrigin})?(${reTaprootActualKey})`;
52
- const rePk = String.raw `pk\((.*?)\)`; //Matches anything. We assert later in the code that the pubkey is valid.
53
- const reAddr = String.raw `addr\((.*?)\)`; //Matches anything. We assert later in the code that the address is valid.
54
- const rePkh = String.raw `pkh\(${exports.reNonSegwitKeyExp}\)`;
55
- const reWpkh = String.raw `wpkh\(${exports.reSegwitKeyExp}\)`;
56
- const reShWpkh = String.raw `sh\(wpkh\(${exports.reSegwitKeyExp}\)\)`;
57
- const reTrSingleKey = String.raw `tr\(${exports.reTaprootKeyExp}\)`; // TODO: tr(KEY,TREE) not yet supported. TrSingleKey used for tr(KEY)
58
- exports.reNonSegwitSortedMulti = String.raw `sortedmulti\(((?:1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)(?:,${exports.reNonSegwitKeyExp})+)\)`;
59
- exports.reSegwitSortedMulti = String.raw `sortedmulti\(((?:1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)(?:,${exports.reSegwitKeyExp})+)\)`;
60
- const reMiniscript = String.raw `(.*?)`; //Matches anything. We assert later in the code that miniscripts are valid and sane.
61
- //RegExp makers:
62
- const makeReSh = (re) => String.raw `sh\(${re}\)`;
63
- const makeReWsh = (re) => String.raw `wsh\(${re}\)`;
64
- const makeReShWsh = (re) => makeReSh(makeReWsh(re));
65
- const anchorStartAndEnd = (re) => String.raw `^${re}$`; //starts and finishes like re (not composable)
66
- exports.anchorStartAndEnd = anchorStartAndEnd;
67
- const composeChecksum = (re) => String.raw `${re}(${exports.reChecksum})?`; //it's optional (note the "?")
68
- exports.rePkAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(rePk));
69
- exports.reAddrAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(reAddr));
70
- exports.rePkhAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(rePkh));
71
- exports.reWpkhAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(reWpkh));
72
- exports.reShWpkhAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(reShWpkh));
73
- exports.reTrSingleKeyAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(reTrSingleKey));
74
- exports.reShSortedMultiAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReSh(exports.reNonSegwitSortedMulti)));
75
- exports.reWshSortedMultiAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReWsh(exports.reSegwitSortedMulti)));
76
- exports.reShWshSortedMultiAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReShWsh(exports.reSegwitSortedMulti)));
77
- exports.reShMiniscriptAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReSh(reMiniscript)));
78
- exports.reShWshMiniscriptAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReShWsh(reMiniscript)));
79
- exports.reWshMiniscriptAnchored = (0, exports.anchorStartAndEnd)(composeChecksum(makeReWsh(reMiniscript)));
@@ -1,25 +0,0 @@
1
- import type { Network } from 'bitcoinjs-lib';
2
- export declare const MAX_SCRIPT_ELEMENT_SIZE = 520;
3
- export declare const MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
4
- export declare function assertScriptNonPushOnlyOpsLimit({ script }: {
5
- script: Uint8Array;
6
- }): void;
7
- /**
8
- * Enforces consensus stack resource limits.
9
- */
10
- export declare function assertConsensusStackResourceLimits({ stackItems, stackLabel, stackItemLabel }: {
11
- stackItems: Uint8Array[];
12
- stackLabel?: string;
13
- stackItemLabel?: string;
14
- }): void;
15
- export declare function assertWitnessV0SatisfactionResourceLimits({ stackItems }: {
16
- stackItems: Uint8Array[];
17
- }): void;
18
- export declare function assertTaprootScriptPathSatisfactionResourceLimits({ stackItems }: {
19
- stackItems: Uint8Array[];
20
- }): void;
21
- export declare function assertP2shScriptSigStandardSize({ scriptSatisfaction, redeemScript, network }: {
22
- scriptSatisfaction: Uint8Array;
23
- redeemScript: Uint8Array;
24
- network: Network;
25
- }): void;
@@ -1,89 +0,0 @@
1
- "use strict";
2
- // Copyright (c) 2026 Jose-Luis Landabaso
3
- // Distributed under the MIT software license
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.MAX_STANDARD_P2WSH_SCRIPT_SIZE = exports.MAX_SCRIPT_ELEMENT_SIZE = void 0;
6
- exports.assertScriptNonPushOnlyOpsLimit = assertScriptNonPushOnlyOpsLimit;
7
- exports.assertConsensusStackResourceLimits = assertConsensusStackResourceLimits;
8
- exports.assertWitnessV0SatisfactionResourceLimits = assertWitnessV0SatisfactionResourceLimits;
9
- exports.assertTaprootScriptPathSatisfactionResourceLimits = assertTaprootScriptPathSatisfactionResourceLimits;
10
- exports.assertP2shScriptSigStandardSize = assertP2shScriptSigStandardSize;
11
- const bitcoinjs_lib_1 = require("bitcoinjs-lib");
12
- const { p2sh } = bitcoinjs_lib_1.payments;
13
- // See Sipa's Miniscript "Resource limitations":
14
- // https://bitcoin.sipa.be/miniscript/
15
- // and Bitcoin Core policy/consensus constants.
16
- //https://github.com/bitcoin/bitcoin/blob/master/src/policy/policy.h
17
- // Consensus: max number of elements in initial stack (and stack+altstack after
18
- // each opcode execution).
19
- const MAX_STACK_SIZE = 1000;
20
- // Consensus: max size for any stack element is 520 bytes.
21
- // This is a per-element limit, not a full script-size limit.
22
- // In legacy P2SH, redeemScript is pushed as a stack element,
23
- // ( this is why we typically say that the redeemScript cannot be larger than 520 ).
24
- // But the same per-element rule applies to other stack items as well.
25
- exports.MAX_SCRIPT_ELEMENT_SIZE = 520;
26
- // Standardness policy limits.
27
- // See Sipa's Miniscript "Resource limitations":
28
- // https://bitcoin.sipa.be/miniscript/
29
- // and Bitcoin Core policy/consensus constants.
30
- //https://github.com/bitcoin/bitcoin/blob/master/src/policy/policy.h
31
- exports.MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
32
- const MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
33
- const MAX_OPS_PER_SCRIPT = 201;
34
- const MAX_STANDARD_SCRIPTSIG_SIZE = 1650;
35
- const MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
36
- const MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE = 80;
37
- function countNonPushOnlyOPs(script) {
38
- const chunks = bitcoinjs_lib_1.script.decompile(script);
39
- if (!chunks)
40
- throw new Error(`Error: could not decompile ${script}`);
41
- return bitcoinjs_lib_1.script.countNonPushOnlyOPs(chunks);
42
- }
43
- function assertScriptNonPushOnlyOpsLimit({ script }) {
44
- const nonPushOnlyOps = countNonPushOnlyOPs(script);
45
- if (nonPushOnlyOps > MAX_OPS_PER_SCRIPT)
46
- throw new Error(`Error: too many non-push ops, ${nonPushOnlyOps} non-push ops is larger than ${MAX_OPS_PER_SCRIPT}`);
47
- }
48
- /**
49
- * Enforces consensus stack resource limits.
50
- */
51
- function assertConsensusStackResourceLimits({ stackItems, stackLabel = 'stack', stackItemLabel = 'stack item' }) {
52
- if (stackItems.length > MAX_STACK_SIZE)
53
- throw new Error(`Error: ${stackLabel} has too many items, ${stackItems.length} is larger than ${MAX_STACK_SIZE}`);
54
- for (const stackItem of stackItems) {
55
- if (stackItem.length > exports.MAX_SCRIPT_ELEMENT_SIZE)
56
- throw new Error(`Error: ${stackItemLabel} is too large, ${stackItem.length} bytes is larger than ${exports.MAX_SCRIPT_ELEMENT_SIZE} bytes`);
57
- }
58
- }
59
- function assertWitnessV0SatisfactionResourceLimits({ stackItems }) {
60
- assertConsensusStackResourceLimits({ stackItems });
61
- if (stackItems.length > MAX_STANDARD_P2WSH_STACK_ITEMS)
62
- throw new Error(`Error: witness stack has too many items, ${stackItems.length} is larger than ${MAX_STANDARD_P2WSH_STACK_ITEMS}`);
63
- for (const stackItem of stackItems) {
64
- if (stackItem.length > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
65
- throw new Error(`Error: witness stack item exceeds standard policy, ${stackItem.length} bytes is larger than ${MAX_STANDARD_P2WSH_STACK_ITEM_SIZE} bytes`);
66
- }
67
- }
68
- function assertTaprootScriptPathSatisfactionResourceLimits({ stackItems }) {
69
- assertConsensusStackResourceLimits({
70
- stackItems,
71
- stackLabel: 'taproot script-path stack',
72
- stackItemLabel: 'taproot script-path stack item'
73
- });
74
- // Standardness policy for tapscript (leaf version 0xc0): <= 80 bytes.
75
- for (const stackItem of stackItems) {
76
- if (stackItem.length > MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE)
77
- throw new Error(`Error: taproot script-path stack item exceeds standard policy, ${stackItem.length} bytes is larger than ${MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE} bytes`);
78
- }
79
- }
80
- function assertP2shScriptSigStandardSize({ scriptSatisfaction, redeemScript, network }) {
81
- const scriptSig = p2sh({
82
- redeem: { input: scriptSatisfaction, output: redeemScript, network },
83
- network
84
- }).input;
85
- if (!scriptSig)
86
- throw new Error(`Error: could not build scriptSig from satisfaction`);
87
- if (scriptSig.length > MAX_STANDARD_SCRIPTSIG_SIZE)
88
- throw new Error(`Error: scriptSig is too large, ${scriptSig.length} bytes is larger than ${MAX_STANDARD_SCRIPTSIG_SIZE} bytes`);
89
- }
@@ -1,95 +0,0 @@
1
- import { Network } from 'bitcoinjs-lib';
2
- import type { LedgerManager } from './ledger';
3
- import type { BIP32Interface } from 'bip32';
4
- /** @function */
5
- export declare const pkhBIP32: ({ masterNode, network, keyPath, account, change, index, isPublic }: {
6
- masterNode: BIP32Interface;
7
- /** @default networks.bitcoin */
8
- network?: Network;
9
- account: number;
10
- change?: number | undefined;
11
- index?: number | undefined | "*";
12
- keyPath?: string;
13
- /**
14
- * Compute an xpub or xprv
15
- * @default true
16
- */
17
- isPublic?: boolean;
18
- }) => string;
19
- /** @function */
20
- export declare const shWpkhBIP32: ({ masterNode, network, keyPath, account, change, index, isPublic }: {
21
- masterNode: BIP32Interface;
22
- /** @default networks.bitcoin */
23
- network?: Network;
24
- account: number;
25
- change?: number | undefined;
26
- index?: number | undefined | "*";
27
- keyPath?: string;
28
- /**
29
- * Compute an xpub or xprv
30
- * @default true
31
- */
32
- isPublic?: boolean;
33
- }) => string;
34
- /** @function */
35
- export declare const wpkhBIP32: ({ masterNode, network, keyPath, account, change, index, isPublic }: {
36
- masterNode: BIP32Interface;
37
- /** @default networks.bitcoin */
38
- network?: Network;
39
- account: number;
40
- change?: number | undefined;
41
- index?: number | undefined | "*";
42
- keyPath?: string;
43
- /**
44
- * Compute an xpub or xprv
45
- * @default true
46
- */
47
- isPublic?: boolean;
48
- }) => string;
49
- /** @function */
50
- export declare const trBIP32: ({ masterNode, network, keyPath, account, change, index, isPublic }: {
51
- masterNode: BIP32Interface;
52
- /** @default networks.bitcoin */
53
- network?: Network;
54
- account: number;
55
- change?: number | undefined;
56
- index?: number | undefined | "*";
57
- keyPath?: string;
58
- /**
59
- * Compute an xpub or xprv
60
- * @default true
61
- */
62
- isPublic?: boolean;
63
- }) => string;
64
- /** @function */
65
- export declare const pkhLedger: ({ ledgerManager, account, keyPath, change, index }: {
66
- ledgerManager: LedgerManager;
67
- account: number;
68
- keyPath?: string;
69
- change?: number | undefined;
70
- index?: number | undefined | "*";
71
- }) => Promise<string>;
72
- /** @function */
73
- export declare const shWpkhLedger: ({ ledgerManager, account, keyPath, change, index }: {
74
- ledgerManager: LedgerManager;
75
- account: number;
76
- keyPath?: string;
77
- change?: number | undefined;
78
- index?: number | undefined | "*";
79
- }) => Promise<string>;
80
- /** @function */
81
- export declare const wpkhLedger: ({ ledgerManager, account, keyPath, change, index }: {
82
- ledgerManager: LedgerManager;
83
- account: number;
84
- keyPath?: string;
85
- change?: number | undefined;
86
- index?: number | undefined | "*";
87
- }) => Promise<string>;
88
- /** @function */
89
- export declare const trLedger: ({ ledgerManager, account, keyPath, change, index }: {
90
- ledgerManager: LedgerManager;
91
- account: number;
92
- keyPath?: string;
93
- change?: number | undefined;
94
- index?: number | undefined | "*";
95
- }) => Promise<string>;
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.trLedger = exports.wpkhLedger = exports.shWpkhLedger = exports.pkhLedger = exports.trBIP32 = exports.wpkhBIP32 = exports.shWpkhBIP32 = exports.pkhBIP32 = void 0;
4
- const bitcoinjs_lib_1 = require("bitcoinjs-lib");
5
- const keyExpressions_1 = require("./keyExpressions");
6
- const networkUtils_1 = require("./networkUtils");
7
- function assertStandardKeyPath(keyPath) {
8
- // Regular expression to match "/change/index" or "/change/*" format
9
- const regex = /^\/[01]\/(\d+|\*)$/;
10
- if (!regex.test(keyPath)) {
11
- throw new Error("Error: Key path must be in the format '/change/index', where change is either 0 or 1 and index is a non-negative integer.");
12
- }
13
- }
14
- function standardExpressionsBIP32Maker(purpose, scriptTemplate) {
15
- /**
16
- * Computes the standard descriptor based on given parameters.
17
- *
18
- * You can define the output location either by:
19
- * - Providing the full `keyPath` (e.g., "/0/2").
20
- * OR
21
- * - Specifying the `change` and `index` values separately (e.g., `{change:0, index:2}`).
22
- *
23
- * For ranged indexing, the `index` can be set as a wildcard '*'. For example:
24
- * - `keyPath="/0/*"`
25
- * OR
26
- * - `{change:0, index:'*'}`.
27
- */
28
- function standardScriptExpressionBIP32({ masterNode, network = bitcoinjs_lib_1.networks.bitcoin, keyPath, account, change, index, isPublic = true }) {
29
- const originPath = `/${purpose}'/${(0, networkUtils_1.coinTypeFromNetwork)(network)}'/${account}'`;
30
- if (keyPath !== undefined)
31
- assertStandardKeyPath(keyPath);
32
- const keyExpression = (0, keyExpressions_1.keyExpressionBIP32)({
33
- masterNode,
34
- originPath,
35
- keyPath,
36
- change,
37
- index,
38
- isPublic
39
- });
40
- return scriptTemplate.replace('KEYEXPRESSION', keyExpression);
41
- }
42
- return standardScriptExpressionBIP32;
43
- }
44
- /** @function */
45
- exports.pkhBIP32 = standardExpressionsBIP32Maker(44, 'pkh(KEYEXPRESSION)');
46
- /** @function */
47
- exports.shWpkhBIP32 = standardExpressionsBIP32Maker(49, 'sh(wpkh(KEYEXPRESSION))');
48
- /** @function */
49
- exports.wpkhBIP32 = standardExpressionsBIP32Maker(84, 'wpkh(KEYEXPRESSION)');
50
- /** @function */
51
- exports.trBIP32 = standardExpressionsBIP32Maker(86, 'tr(KEYEXPRESSION)');
52
- function standardExpressionsLedgerMaker(purpose, scriptTemplate) {
53
- /**
54
- * Computes the standard descriptor based on given parameters.
55
- *
56
- * You can define the output location either by:
57
- * - Providing the full `keyPath` (e.g., "/0/2").
58
- * OR
59
- * - Specifying the `change` and `index` values separately (e.g., `{change:0, index:2}`).
60
- *
61
- * For ranged indexing, the `index` can be set as a wildcard '*'. For example:
62
- * - `keyPath="/0/*"`
63
- * OR
64
- * - `{change:0, index:'*'}`.
65
- */
66
- async function standardScriptExpressionLedger({ ledgerManager, account, keyPath, change, index }) {
67
- const { network } = ledgerManager;
68
- const originPath = `/${purpose}'/${(0, networkUtils_1.coinTypeFromNetwork)(network)}'/${account}'`;
69
- if (keyPath !== undefined)
70
- assertStandardKeyPath(keyPath);
71
- const keyExpression = await (0, keyExpressions_1.keyExpressionLedger)({
72
- ledgerManager,
73
- originPath,
74
- keyPath,
75
- change,
76
- index
77
- });
78
- return scriptTemplate.replace('KEYEXPRESSION', keyExpression);
79
- }
80
- return standardScriptExpressionLedger;
81
- }
82
- /** @function */
83
- exports.pkhLedger = standardExpressionsLedgerMaker(44, 'pkh(KEYEXPRESSION)');
84
- /** @function */
85
- exports.shWpkhLedger = standardExpressionsLedgerMaker(49, 'sh(wpkh(KEYEXPRESSION))');
86
- /** @function */
87
- exports.wpkhLedger = standardExpressionsLedgerMaker(84, 'wpkh(KEYEXPRESSION)');
88
- /** @function */
89
- exports.trLedger = standardExpressionsLedgerMaker(86, 'tr(KEYEXPRESSION)');