@bitcoinerlab/descriptors-core 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.
Files changed (76) hide show
  1. package/README.md +710 -0
  2. package/dist/adapters/applyPR2137.d.ts +2 -0
  3. package/dist/adapters/applyPR2137.js +150 -0
  4. package/dist/adapters/bitcoinjs.d.ts +8 -0
  5. package/dist/adapters/bitcoinjs.js +36 -0
  6. package/dist/adapters/scure/address.d.ts +2 -0
  7. package/dist/adapters/scure/address.js +50 -0
  8. package/dist/adapters/scure/bip32.d.ts +2 -0
  9. package/dist/adapters/scure/bip32.js +16 -0
  10. package/dist/adapters/scure/common.d.ts +14 -0
  11. package/dist/adapters/scure/common.js +36 -0
  12. package/dist/adapters/scure/ecpair.d.ts +2 -0
  13. package/dist/adapters/scure/ecpair.js +58 -0
  14. package/dist/adapters/scure/payments.d.ts +2 -0
  15. package/dist/adapters/scure/payments.js +216 -0
  16. package/dist/adapters/scure/psbt.d.ts +43 -0
  17. package/dist/adapters/scure/psbt.js +382 -0
  18. package/dist/adapters/scure/script.d.ts +20 -0
  19. package/dist/adapters/scure/script.js +163 -0
  20. package/dist/adapters/scure/transaction.d.ts +2 -0
  21. package/dist/adapters/scure/transaction.js +32 -0
  22. package/dist/adapters/scure.d.ts +6 -0
  23. package/dist/adapters/scure.js +37 -0
  24. package/dist/adapters/scureKeys.d.ts +4 -0
  25. package/dist/adapters/scureKeys.js +135 -0
  26. package/dist/bip174.d.ts +87 -0
  27. package/dist/bip174.js +12 -0
  28. package/dist/bitcoinLib.d.ts +385 -0
  29. package/dist/bitcoinLib.js +19 -0
  30. package/dist/bitcoinjs-lib-internals.d.ts +6 -0
  31. package/dist/bitcoinjs-lib-internals.js +60 -0
  32. package/dist/bitcoinjs.d.ts +12 -0
  33. package/dist/bitcoinjs.js +18 -0
  34. package/dist/checksum.d.ts +6 -0
  35. package/dist/checksum.js +58 -0
  36. package/dist/crypto.d.ts +3 -0
  37. package/dist/crypto.js +79 -0
  38. package/dist/descriptors.d.ts +481 -0
  39. package/dist/descriptors.js +1888 -0
  40. package/dist/index.d.ts +23 -0
  41. package/dist/index.js +87 -0
  42. package/dist/keyExpressions.d.ts +124 -0
  43. package/dist/keyExpressions.js +310 -0
  44. package/dist/keyInterfaces.d.ts +5 -0
  45. package/dist/keyInterfaces.js +50 -0
  46. package/dist/ledger.d.ts +183 -0
  47. package/dist/ledger.js +618 -0
  48. package/dist/miniscript.d.ts +125 -0
  49. package/dist/miniscript.js +310 -0
  50. package/dist/multipath.d.ts +13 -0
  51. package/dist/multipath.js +76 -0
  52. package/dist/networkUtils.d.ts +3 -0
  53. package/dist/networkUtils.js +16 -0
  54. package/dist/networks.d.ts +16 -0
  55. package/dist/networks.js +31 -0
  56. package/dist/parseUtils.d.ts +7 -0
  57. package/dist/parseUtils.js +46 -0
  58. package/dist/psbt.d.ts +40 -0
  59. package/dist/psbt.js +228 -0
  60. package/dist/re.d.ts +31 -0
  61. package/dist/re.js +79 -0
  62. package/dist/resourceLimits.d.ts +28 -0
  63. package/dist/resourceLimits.js +84 -0
  64. package/dist/scriptExpressions.d.ts +95 -0
  65. package/dist/scriptExpressions.js +98 -0
  66. package/dist/scure.d.ts +4 -0
  67. package/dist/scure.js +10 -0
  68. package/dist/signers.d.ts +161 -0
  69. package/dist/signers.js +324 -0
  70. package/dist/tapMiniscript.d.ts +231 -0
  71. package/dist/tapMiniscript.js +524 -0
  72. package/dist/tapTree.d.ts +91 -0
  73. package/dist/tapTree.js +166 -0
  74. package/dist/types.d.ts +296 -0
  75. package/dist/types.js +4 -0
  76. package/package.json +148 -0
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ // Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
3
+ // Distributed under the MIT software license
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.wrapScurePrivateKey = wrapScurePrivateKey;
6
+ exports.wrapScurePublicKey = wrapScurePublicKey;
7
+ exports.wrapScureHDKey = wrapScureHDKey;
8
+ const bip32_1 = require("@scure/bip32");
9
+ const base_1 = require("@scure/base");
10
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
11
+ const utils_js_1 = require("@noble/curves/utils.js");
12
+ const common_1 = require("./scure/common");
13
+ const CURVE_N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
14
+ function mod(a, n) {
15
+ const result = a % n;
16
+ return result >= 0n ? result : result + n;
17
+ }
18
+ function tweakPrivateKey(privateKey, tweak, publicKey) {
19
+ if (tweak.length !== 32)
20
+ throw new Error('Error: invalid tweak value');
21
+ const tweakNum = (0, utils_js_1.bytesToNumberBE)(tweak);
22
+ if (tweakNum <= 0n || tweakNum >= CURVE_N)
23
+ throw new Error('Error: invalid tweak value');
24
+ let d = (0, utils_js_1.bytesToNumberBE)(privateKey);
25
+ if (publicKey[0] === 0x03)
26
+ d = mod(-d, CURVE_N);
27
+ const tweaked = mod(d + tweakNum, CURVE_N);
28
+ if (tweaked === 0n)
29
+ throw new Error('Error: invalid tweak value');
30
+ return (0, utils_js_1.numberToBytesBE)(tweaked, 32);
31
+ }
32
+ function wrapScurePrivateKey(privateKey, compressed = true) {
33
+ if (!secp256k1_js_1.secp256k1.utils.isValidSecretKey(privateKey))
34
+ throw new Error('Error: invalid private key');
35
+ const compressedPublicKey = secp256k1_js_1.secp256k1.getPublicKey(privateKey, true);
36
+ const publicKey = compressed
37
+ ? compressedPublicKey
38
+ : secp256k1_js_1.secp256k1.getPublicKey(privateKey, false);
39
+ const xOnlyPubkey = compressedPublicKey.slice(1, 33);
40
+ return {
41
+ publicKey,
42
+ privateKey,
43
+ sign(hash) {
44
+ return secp256k1_js_1.secp256k1.sign(hash, privateKey, {
45
+ prehash: false,
46
+ lowS: true,
47
+ format: 'compact'
48
+ });
49
+ },
50
+ verify(hash, signature) {
51
+ return secp256k1_js_1.secp256k1.verify(signature, hash, publicKey, {
52
+ prehash: false,
53
+ lowS: true,
54
+ format: 'compact'
55
+ });
56
+ },
57
+ tweak(t) {
58
+ return wrapScurePrivateKey(tweakPrivateKey(privateKey, t, compressedPublicKey), compressed);
59
+ },
60
+ signSchnorr(hash) {
61
+ return secp256k1_js_1.schnorr.sign(hash, privateKey);
62
+ },
63
+ verifySchnorr(hash, signature) {
64
+ return secp256k1_js_1.schnorr.verify(signature, hash, xOnlyPubkey);
65
+ }
66
+ };
67
+ }
68
+ function wrapScurePublicKey(publicKey) {
69
+ if (!secp256k1_js_1.secp256k1.utils.isValidPublicKey(publicKey))
70
+ throw new Error('Error: invalid public key point');
71
+ const compressedPubkey = publicKey.length === 33
72
+ ? publicKey
73
+ : secp256k1_js_1.secp256k1.Point.fromHex(base_1.hex.encode(publicKey)).toBytes(true);
74
+ const xOnlyPubkey = compressedPubkey.slice(1, 33);
75
+ return {
76
+ publicKey,
77
+ sign() {
78
+ throw new Error('Error: private key is required for signing');
79
+ },
80
+ verify(hash, signature) {
81
+ return secp256k1_js_1.secp256k1.verify(signature, hash, publicKey, {
82
+ prehash: false,
83
+ lowS: true,
84
+ format: 'compact'
85
+ });
86
+ },
87
+ tweak() {
88
+ throw new Error('Error: private key is required for tweak');
89
+ },
90
+ verifySchnorr(hash, signature) {
91
+ return secp256k1_js_1.schnorr.verify(signature, hash, xOnlyPubkey);
92
+ }
93
+ };
94
+ }
95
+ function normalizePath(path) {
96
+ const p = path.replaceAll('H', "'").replaceAll('h', "'");
97
+ if (p === 'm' || p === "m'")
98
+ return 'm';
99
+ if (p.startsWith('m/'))
100
+ return p;
101
+ if (p.startsWith('/'))
102
+ return `m${p}`;
103
+ return `m/${p}`;
104
+ }
105
+ function wrapScureHDKey(node) {
106
+ if (!node.publicKey)
107
+ throw new Error('Error: scure HDKey is missing publicKey for BIP32 usage');
108
+ return {
109
+ publicKey: node.publicKey,
110
+ ...(node.privateKey ? { privateKey: node.privateKey } : {}),
111
+ fingerprint: (0, common_1.uint32ToBytesBE)(node.fingerprint),
112
+ derive(index) {
113
+ return wrapScureHDKey(node.deriveChild(index));
114
+ },
115
+ derivePath(path) {
116
+ return wrapScureHDKey(node.derive(normalizePath(path)));
117
+ },
118
+ neutered() {
119
+ return wrapScureHDKey(bip32_1.HDKey.fromExtendedKey(node.publicExtendedKey, node.versions));
120
+ },
121
+ toBase58() {
122
+ return node.privateKey ? node.privateExtendedKey : node.publicExtendedKey;
123
+ },
124
+ sign(hash) {
125
+ if (!node.privateKey)
126
+ throw new Error('Error: cannot sign with neutered ScureHDKeyLike');
127
+ return node.sign(hash);
128
+ },
129
+ tweak(t) {
130
+ if (!node.privateKey)
131
+ throw new Error('Error: cannot tweak a neutered ScureHDKeyLike');
132
+ return wrapScurePrivateKey(node.privateKey).tweak(t);
133
+ }
134
+ };
135
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Minimal local subset of the bip174 type surface used by this codebase.
3
+ *
4
+ * This file is intentionally self-contained so the library can stop exposing
5
+ * `bip174` as a dependency.
6
+ */
7
+ /** @internal */
8
+ export interface KeyValue {
9
+ key: Uint8Array;
10
+ value: Uint8Array;
11
+ }
12
+ /** @internal */
13
+ export interface PartialSig {
14
+ pubkey: Uint8Array;
15
+ signature: Uint8Array;
16
+ }
17
+ /** @internal */
18
+ export interface Bip32Derivation {
19
+ masterFingerprint: Uint8Array;
20
+ pubkey: Uint8Array;
21
+ path: string;
22
+ }
23
+ /** @internal */
24
+ export interface WitnessUtxo {
25
+ script: Uint8Array;
26
+ value: bigint;
27
+ }
28
+ /** @internal */
29
+ export type NonWitnessUtxo = Uint8Array;
30
+ /** @internal */
31
+ export type SighashType = number;
32
+ /** @internal */
33
+ export type RedeemScript = Uint8Array;
34
+ /** @internal */
35
+ export type WitnessScript = Uint8Array;
36
+ /** @internal */
37
+ export type FinalScriptSig = Uint8Array;
38
+ /** @internal */
39
+ export type FinalScriptWitness = Uint8Array;
40
+ /** @internal */
41
+ export type TapKeySig = Uint8Array;
42
+ /** @internal */
43
+ export type TapInternalKey = Uint8Array;
44
+ /** @internal */
45
+ export type TapMerkleRoot = Uint8Array;
46
+ /** @internal */
47
+ export interface TapScriptSig extends PartialSig {
48
+ leafHash: Uint8Array;
49
+ }
50
+ /** @internal */
51
+ export interface TapLeafScript {
52
+ controlBlock: Uint8Array;
53
+ leafVersion: number;
54
+ script: Uint8Array;
55
+ }
56
+ /** @internal */
57
+ export interface TapBip32Derivation extends Bip32Derivation {
58
+ leafHashes: Uint8Array[];
59
+ }
60
+ /** @internal */
61
+ export interface PsbtInputUpdate {
62
+ partialSig?: PartialSig[];
63
+ nonWitnessUtxo?: NonWitnessUtxo;
64
+ witnessUtxo?: WitnessUtxo;
65
+ sighashType?: SighashType;
66
+ redeemScript?: RedeemScript;
67
+ witnessScript?: WitnessScript;
68
+ bip32Derivation?: Bip32Derivation[];
69
+ finalScriptSig?: FinalScriptSig;
70
+ finalScriptWitness?: FinalScriptWitness;
71
+ tapKeySig?: TapKeySig;
72
+ tapScriptSig?: TapScriptSig[];
73
+ tapLeafScript?: TapLeafScript[];
74
+ tapBip32Derivation?: TapBip32Derivation[];
75
+ tapInternalKey?: TapInternalKey;
76
+ tapMerkleRoot?: TapMerkleRoot;
77
+ }
78
+ /** @internal */
79
+ export interface PsbtInput extends PsbtInputUpdate {
80
+ unknownKeyVals?: KeyValue[];
81
+ }
82
+ /** @internal */
83
+ export interface PsbtInputExtended extends PsbtInput {
84
+ [index: string]: unknown;
85
+ }
86
+ /** @internal */
87
+ export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput;
package/dist/bip174.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ // Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
3
+ // Distributed under the MIT software license
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.checkForInput = checkForInput;
6
+ /** @internal */
7
+ function checkForInput(inputs, inputIndex) {
8
+ const input = inputs[inputIndex];
9
+ if (!input)
10
+ throw new Error(`No input #${inputIndex}`);
11
+ return input;
12
+ }
@@ -0,0 +1,385 @@
1
+ /**
2
+ * This module defines the BitcoinLib interface – the abstraction boundary
3
+ * between the descriptor library core and the underlying Bitcoin
4
+ * implementation (bitcoinjs-lib, @scure/btc-signer, or any other).
5
+ *
6
+ * Adapters implement this interface. The core library receives it via
7
+ * DescriptorsFactory and threads it through closures.
8
+ */
9
+ import type { Network } from './networks';
10
+ import type { PsbtInput } from './bip174';
11
+ /**
12
+ * Structural signer interface accepted by this library for single-key signing.
13
+ *
14
+ * In practice, pass an object from
15
+ * {@link https://github.com/bitcoinjs/ecpair | `ecpair`} (bitcoinjs stack).
16
+ *
17
+ * Example (bitcoinjs stack):
18
+ * ```ts
19
+ * import * as ecc from '@bitcoinerlab/secp256k1';
20
+ * import { ECPairFactory } from 'ecpair';
21
+ *
22
+ * const ECPair = ECPairFactory(ecc);
23
+ * const signer = ECPair.fromWIF('L1...');
24
+ * ```
25
+ */
26
+ export interface ECPairInterfaceLike {
27
+ publicKey: Uint8Array;
28
+ privateKey?: Uint8Array;
29
+ sign(hash: Uint8Array, lowR?: boolean): Uint8Array;
30
+ verify(hash: Uint8Array, signature: Uint8Array): boolean;
31
+ tweak(t: Uint8Array): ECPairInterfaceLike;
32
+ signSchnorr?(hash: Uint8Array): Uint8Array;
33
+ verifySchnorr?(hash: Uint8Array, signature: Uint8Array): boolean;
34
+ }
35
+ /**
36
+ * Full bitcoinjs ecpair-compatible interface.
37
+ *
38
+ * This is exposed only for factory return typing when the adapter is the
39
+ * native bitcoinjs stack. Internal code should continue using
40
+ * `ECPairInterfaceLike`.
41
+ */
42
+ /** @internal */
43
+ interface ECPairInterface extends ECPairInterfaceLike {
44
+ compressed: boolean;
45
+ network: Network;
46
+ lowR: boolean;
47
+ toWIF(): string;
48
+ signSchnorr(hash: Uint8Array): Uint8Array;
49
+ verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean;
50
+ tweak(t: Uint8Array): ECPairInterface;
51
+ }
52
+ /**
53
+ * Structural HD node interface accepted by this library.
54
+ *
55
+ * In practice, pass a node from
56
+ * {@link https://github.com/bitcoinjs/bip32 | `bip32`} (bitcoinjs stack).
57
+ *
58
+ * Example (bitcoinjs stack):
59
+ * ```ts
60
+ * import * as ecc from '@bitcoinerlab/secp256k1';
61
+ * import { BIP32Factory } from 'bip32';
62
+ *
63
+ * const BIP32 = BIP32Factory(ecc);
64
+ * const node = BIP32.fromSeed(seedBytes);
65
+ * ```
66
+ */
67
+ export interface BIP32InterfaceLike {
68
+ publicKey: Uint8Array;
69
+ privateKey?: Uint8Array;
70
+ fingerprint: Uint8Array;
71
+ derive(index: number): BIP32InterfaceLike;
72
+ derivePath(path: string): BIP32InterfaceLike;
73
+ neutered(): BIP32InterfaceLike;
74
+ toBase58(): string;
75
+ sign(hash: Uint8Array): Uint8Array;
76
+ tweak(t: Uint8Array): Omit<ECPairInterfaceLike, 'tweak' | 'privateKey'>;
77
+ }
78
+ /**
79
+ * Full bitcoinjs bip32-compatible interface.
80
+ *
81
+ * This is exposed only for factory return typing when the adapter is the
82
+ * native bitcoinjs stack. Internal code should continue using
83
+ * `BIP32InterfaceLike`.
84
+ */
85
+ /** @internal */
86
+ interface BIP32Interface extends BIP32InterfaceLike {
87
+ chainCode: Uint8Array;
88
+ network: Network;
89
+ depth: number;
90
+ index: number;
91
+ parentFingerprint: number;
92
+ identifier: Uint8Array;
93
+ isNeutered(): boolean;
94
+ neutered(): BIP32Interface;
95
+ derive(index: number): BIP32Interface;
96
+ deriveHardened(index: number): BIP32Interface;
97
+ derivePath(path: string): BIP32Interface;
98
+ toWIF(): string;
99
+ tweak(t: Uint8Array): Omit<ECPairInterface, 'tweak' | 'privateKey'>;
100
+ lowR: boolean;
101
+ verify(hash: Uint8Array, signature: Uint8Array): boolean;
102
+ signSchnorr(hash: Uint8Array): Uint8Array;
103
+ verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean;
104
+ }
105
+ /**
106
+ * Structural subset of
107
+ * {@link https://github.com/paulmillr/scure-bip32 | `@scure/bip32` `HDKey`}.
108
+ *
109
+ * Use this when signing with the scure stack.
110
+ *
111
+ * Example (scure stack):
112
+ * ```ts
113
+ * import { HDKey } from '@scure/bip32';
114
+ *
115
+ * const masterNode = HDKey.fromMasterSeed(seedBytes);
116
+ * ```
117
+ */
118
+ export interface ScureHDKeyLike {
119
+ publicKey: Uint8Array | null;
120
+ privateKey: Uint8Array | null;
121
+ fingerprint: number;
122
+ versions?: {
123
+ public: number;
124
+ private: number;
125
+ };
126
+ derive(path: string): ScureHDKeyLike;
127
+ deriveChild(index: number): ScureHDKeyLike;
128
+ sign(hash: Uint8Array): Uint8Array;
129
+ publicExtendedKey: string;
130
+ privateExtendedKey: string;
131
+ }
132
+ /**
133
+ * Internal key-factory shape used by this library.
134
+ *
135
+ * In user code, this usually corresponds to
136
+ * {@link https://github.com/bitcoinjs/ecpair | `ECPairFactory` output}.
137
+ * @internal
138
+ */
139
+ export interface ECPairAPILike {
140
+ isPoint(maybePoint: unknown): boolean;
141
+ fromPublicKey(buffer: Uint8Array, options?: {
142
+ compressed?: boolean;
143
+ network?: Network;
144
+ }): ECPairInterfaceLike;
145
+ fromWIF(wifString: string, network?: Network | Network[]): ECPairInterfaceLike;
146
+ }
147
+ /** Full bitcoinjs ecpair-compatible API.
148
+ * @internal
149
+ */
150
+ export interface ECPairAPI {
151
+ isPoint(maybePoint: unknown): boolean;
152
+ fromPrivateKey(buffer: Uint8Array, options?: {
153
+ compressed?: boolean;
154
+ network?: Network;
155
+ }): ECPairInterface;
156
+ fromPublicKey(buffer: Uint8Array, options?: {
157
+ compressed?: boolean;
158
+ network?: Network;
159
+ }): ECPairInterface;
160
+ makeRandom(options?: {
161
+ compressed?: boolean;
162
+ network?: Network;
163
+ rng?: (arg?: number) => Uint8Array;
164
+ }): ECPairInterface;
165
+ fromWIF(wifString: string, network?: Network | Network[]): ECPairInterface;
166
+ }
167
+ /**
168
+ * Internal HD-factory shape used by this library.
169
+ *
170
+ * In user code, this usually corresponds to
171
+ * {@link https://github.com/bitcoinjs/bip32 | `BIP32Factory` output}.
172
+ * @internal
173
+ */
174
+ export interface BIP32APILike {
175
+ fromBase58(inString: string, network?: Network): BIP32InterfaceLike;
176
+ }
177
+ /** Full bitcoinjs bip32-compatible API.
178
+ * @internal
179
+ */
180
+ export interface BIP32API {
181
+ fromSeed(seed: Uint8Array, network?: Network): BIP32Interface;
182
+ fromBase58(inString: string, network?: Network): BIP32Interface;
183
+ fromPublicKey(publicKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface;
184
+ fromPrivateKey(privateKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface;
185
+ }
186
+ /** @internal */
187
+ export interface Payment {
188
+ output?: Uint8Array;
189
+ address?: string;
190
+ input?: Uint8Array;
191
+ witness?: Uint8Array[];
192
+ redeem?: Payment;
193
+ hash?: Uint8Array;
194
+ pubkey?: Uint8Array;
195
+ /** Taproot x-only internal pubkey (32 bytes). */
196
+ internalPubkey?: Uint8Array;
197
+ network?: Network;
198
+ }
199
+ /**
200
+ * Minimal PSBT interface consumed by this library.
201
+ *
202
+ * This is intentionally a bitcoinjs-compatible structural subset so raw
203
+ * `bitcoinjs-lib.Psbt` instances can be passed directly to public APIs.
204
+ * The scure adapter maps `@scure/btc-signer.Transaction` to this surface.
205
+ * @internal
206
+ */
207
+ export interface PsbtTxInput {
208
+ hash: Uint8Array;
209
+ index: number;
210
+ sequence?: number;
211
+ }
212
+ /** @internal */
213
+ export type PsbtLikeInputUpdate = Partial<PsbtInput>;
214
+ /**
215
+ * Minimal interface compatible with bitcoinjs-lib Psbt.
216
+ *
217
+ * In user code, simply pass a concrete
218
+ * {@link https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/psbt.ts | bitcoinjs-lib `Psbt`}.
219
+ *
220
+ * Example (bitcoinjs stack):
221
+ * ```ts
222
+ * import { Psbt, networks } from 'bitcoinjs-lib';
223
+ *
224
+ * const psbt = new Psbt({ network: networks.bitcoin });
225
+ * ```
226
+ *
227
+ * Notes:
228
+ * - This interface is structural and intentionally minimal.
229
+ * - Some nested fields use internal helper types (for docs bloat control).
230
+ */
231
+ export interface PsbtLike {
232
+ addInput(input: PsbtInput): void;
233
+ addOutput(output: {
234
+ script: Uint8Array;
235
+ value: bigint;
236
+ }): void;
237
+ readonly inputCount: number;
238
+ readonly data: {
239
+ inputs: PsbtInput[];
240
+ };
241
+ readonly txInputs: PsbtTxInput[];
242
+ setLocktime(locktime: number): void;
243
+ readonly locktime: number;
244
+ signInput(index: number, signer: ECPairInterfaceLike): void;
245
+ signAllInputs(signer: ECPairInterfaceLike): void;
246
+ signInputHD(index: number, hdSigner: BIP32InterfaceLike): void;
247
+ signAllInputsHD(hdSigner: BIP32InterfaceLike): void;
248
+ finalizeInput(index: number, finalizer?: FinalScriptsFunc): void;
249
+ finalizeTaprootInput(index: number, tapLeafHashToFinalize: Uint8Array | undefined, finalizer: () => {
250
+ finalScriptWitness: Uint8Array;
251
+ }): void;
252
+ validateSignaturesOfInput(index: number, validator: (pubkey: Uint8Array, msghash: Uint8Array, signature: Uint8Array) => boolean): boolean;
253
+ updateInput(index: number, data: PsbtLikeInputUpdate): void;
254
+ toBase64(): string;
255
+ }
256
+ /** @internal */
257
+ export type FinalScriptsFunc = (inputIndex: number, input: PsbtInput, script: Uint8Array, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
258
+ finalScriptSig: Uint8Array | undefined;
259
+ finalScriptWitness: Uint8Array | undefined;
260
+ };
261
+ /**
262
+ * Minimal interface compatible with @scure/btc-signer Transaction.
263
+ *
264
+ * In user code, simply pass a concrete
265
+ * {@link https://github.com/paulmillr/scure-btc-signer | `@scure/btc-signer` `Transaction`}.
266
+ *
267
+ * Example (scure stack):
268
+ * ```ts
269
+ * import { Transaction } from '@scure/btc-signer';
270
+ *
271
+ * const tx = new Transaction({ allowUnknownOutputs: true });
272
+ * ```
273
+ */
274
+ export interface ScureTransactionLike {
275
+ inputsLength: number;
276
+ outputsLength: number;
277
+ getInput(index: number): unknown;
278
+ getOutput(index: number): unknown;
279
+ addInput(input: unknown): void;
280
+ addOutput(output: {
281
+ script: Uint8Array;
282
+ amount: bigint;
283
+ }): void;
284
+ sign(signer: unknown): number;
285
+ signIdx(signer: unknown, index: number): boolean;
286
+ finalize(): void;
287
+ finalizeIdx(index: number): void;
288
+ toPSBT(): Uint8Array;
289
+ lockTime: number;
290
+ }
291
+ /**
292
+ * Type guard to detect if a transaction object is a
293
+ * `@scure/btc-signer` `Transaction`.
294
+ * Checks for scure-specific properties that distinguish it from bitcoinjs-lib Psbt.
295
+ * @internal
296
+ */
297
+ export declare function isScureTransaction(psbt: PsbtLike | ScureTransactionLike): psbt is ScureTransactionLike;
298
+ /** @internal */
299
+ export interface Transaction {
300
+ getId(): string;
301
+ outs: Array<{
302
+ script: Uint8Array;
303
+ value: bigint;
304
+ }>;
305
+ toBuffer(): Uint8Array;
306
+ }
307
+ /** @internal */
308
+ export type Tapleaf = {
309
+ output: Uint8Array;
310
+ version?: number;
311
+ };
312
+ /** @internal */
313
+ export type Taptree = [Taptree | Tapleaf, Taptree | Tapleaf] | Tapleaf;
314
+ /**
315
+ * The complete Bitcoin backend adapter.
316
+ *
317
+ * Implementations wrap either bitcoinjs-lib or @scure/btc-signer.
318
+ * Received by `DescriptorsFactory` and threaded through the library.
319
+ * @internal
320
+ */
321
+ export interface BitcoinLib {
322
+ payments: {
323
+ p2pk(a: {
324
+ pubkey: Uint8Array;
325
+ network?: Network;
326
+ }): Payment;
327
+ p2pkh(a: {
328
+ pubkey?: Uint8Array;
329
+ hash?: Uint8Array;
330
+ output?: Uint8Array;
331
+ network?: Network;
332
+ }): Payment;
333
+ p2sh(a: {
334
+ redeem?: Payment;
335
+ output?: Uint8Array;
336
+ network?: Network;
337
+ }): Payment;
338
+ p2wpkh(a: {
339
+ pubkey?: Uint8Array;
340
+ hash?: Uint8Array;
341
+ output?: Uint8Array;
342
+ network?: Network;
343
+ }): Payment;
344
+ p2wsh(a: {
345
+ redeem?: Payment;
346
+ output?: Uint8Array;
347
+ network?: Network;
348
+ }): Payment;
349
+ p2ms(a: {
350
+ m: number;
351
+ pubkeys: Uint8Array[];
352
+ network?: Network;
353
+ }): Payment;
354
+ p2tr(a: {
355
+ internalPubkey?: Uint8Array;
356
+ scriptTree?: Taptree;
357
+ redeem?: {
358
+ output: Uint8Array;
359
+ redeemVersion?: number;
360
+ };
361
+ output?: Uint8Array;
362
+ network?: Network;
363
+ }): Payment;
364
+ };
365
+ script: {
366
+ fromASM(asm: string): Uint8Array;
367
+ toStack(scriptBuf: Uint8Array): Uint8Array[];
368
+ decompile(scriptBuf: Uint8Array): Array<number | Uint8Array> | null;
369
+ countNonPushOnlyOPs(chunks: Array<number | Uint8Array>): number;
370
+ number: {
371
+ encode(n: number): Uint8Array;
372
+ };
373
+ };
374
+ Transaction: {
375
+ fromHex(hex: string): Transaction;
376
+ fromBuffer(buf: Uint8Array): Transaction;
377
+ };
378
+ address: {
379
+ toOutputScript(addr: string, network?: Network): Uint8Array;
380
+ };
381
+ ECPair: ECPairAPILike;
382
+ BIP32: BIP32APILike;
383
+ verifySchnorr(msghash: Uint8Array, pubkey: Uint8Array, signature: Uint8Array): boolean;
384
+ }
385
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ // Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
3
+ // Distributed under the MIT software license
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.isScureTransaction = isScureTransaction;
6
+ /**
7
+ * Type guard to detect if a transaction object is a
8
+ * `@scure/btc-signer` `Transaction`.
9
+ * Checks for scure-specific properties that distinguish it from bitcoinjs-lib Psbt.
10
+ * @internal
11
+ */
12
+ function isScureTransaction(psbt) {
13
+ const candidate = psbt;
14
+ return ('inputsLength' in candidate &&
15
+ 'outputsLength' in candidate &&
16
+ 'toPSBT' in candidate &&
17
+ typeof candidate.toPSBT === 'function' &&
18
+ 'lockTime' in candidate);
19
+ }
@@ -0,0 +1,6 @@
1
+ import type { PsbtInput } from './bip174';
2
+ import { type Tapleaf } from './bitcoinLib';
3
+ export declare function tapleafHash(leaf: Tapleaf): Uint8Array;
4
+ export declare function tapTweakHash(pubKey: Uint8Array, h?: Uint8Array): Uint8Array;
5
+ export declare function witnessStackToScriptWitness(witness: Uint8Array[]): Uint8Array;
6
+ export declare function isTaprootInput(input: PsbtInput | undefined): boolean;