bip388 1.0.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.
@@ -0,0 +1,1020 @@
1
+ import { BIP32Interface } from 'bip32';
2
+ import { Network } from 'bitcoinjs-lib';
3
+
4
+ /**
5
+ * BIP-379 Miniscript Fragment Builders
6
+ *
7
+ * Provides typesafe construction of miniscript fragments for use in
8
+ * Bitcoin Script descriptors (wsh, tr).
9
+ *
10
+ * @see https://github.com/bitcoin/bips/blob/master/bip-0379.mediawiki
11
+ */
12
+ /**
13
+ * Base interface for all miniscript fragments.
14
+ * Each fragment knows how to serialize itself to a string.
15
+ */
16
+ interface MiniscriptFragment {
17
+ readonly type: string;
18
+ toString(): string;
19
+ }
20
+ /**
21
+ * pk(@N/**) - Public key check
22
+ */
23
+ interface PkFragment extends MiniscriptFragment {
24
+ readonly type: "pk";
25
+ readonly key: string;
26
+ }
27
+ /**
28
+ * pkh(@N/**) - Public key hash check
29
+ */
30
+ interface PkhFragment extends MiniscriptFragment {
31
+ readonly type: "pkh";
32
+ readonly key: string;
33
+ }
34
+ /**
35
+ * sha256(H) - SHA256 preimage check
36
+ */
37
+ interface Sha256Fragment extends MiniscriptFragment {
38
+ readonly type: "sha256";
39
+ readonly hash: string;
40
+ }
41
+ /**
42
+ * hash256(H) - Double SHA256 preimage check
43
+ */
44
+ interface Hash256Fragment extends MiniscriptFragment {
45
+ readonly type: "hash256";
46
+ readonly hash: string;
47
+ }
48
+ /**
49
+ * hash160(H) - HASH160 preimage check
50
+ */
51
+ interface Hash160Fragment extends MiniscriptFragment {
52
+ readonly type: "hash160";
53
+ readonly hash: string;
54
+ }
55
+ /**
56
+ * ripemd160(H) - RIPEMD160 preimage check
57
+ */
58
+ interface Ripemd160Fragment extends MiniscriptFragment {
59
+ readonly type: "ripemd160";
60
+ readonly hash: string;
61
+ }
62
+ /**
63
+ * older(N) - Relative timelock (CSV)
64
+ */
65
+ interface OlderFragment extends MiniscriptFragment {
66
+ readonly type: "older";
67
+ readonly blocks: number;
68
+ }
69
+ /**
70
+ * after(N) - Absolute timelock (CLTV)
71
+ */
72
+ interface AfterFragment extends MiniscriptFragment {
73
+ readonly type: "after";
74
+ readonly time: number;
75
+ }
76
+ /**
77
+ * and_v(X, Y) - Verify AND
78
+ */
79
+ interface AndVFragment extends MiniscriptFragment {
80
+ readonly type: "and_v";
81
+ readonly left: Fragment;
82
+ readonly right: Fragment;
83
+ }
84
+ /**
85
+ * or_d(X, Y) - Dissatisfiable OR
86
+ */
87
+ interface OrDFragment extends MiniscriptFragment {
88
+ readonly type: "or_d";
89
+ readonly left: Fragment;
90
+ readonly right: Fragment;
91
+ }
92
+ /**
93
+ * or_i(X, Z) - IF/ELSE OR
94
+ */
95
+ interface OrIFragment extends MiniscriptFragment {
96
+ readonly type: "or_i";
97
+ readonly left: Fragment;
98
+ readonly right: Fragment;
99
+ }
100
+ /**
101
+ * v:X - Verify wrapper
102
+ */
103
+ interface VerifyWrapper extends MiniscriptFragment {
104
+ readonly type: "v";
105
+ readonly inner: Fragment;
106
+ }
107
+ /**
108
+ * multi(k, key1, key2, ...) - k-of-n multisig (SegWit)
109
+ */
110
+ interface MultiFragment extends MiniscriptFragment {
111
+ readonly type: "multi";
112
+ readonly threshold: number;
113
+ readonly keys: string[];
114
+ }
115
+ /**
116
+ * sortedmulti(k, key1, key2, ...) - k-of-n multisig with sorted keys (SegWit)
117
+ */
118
+ interface SortedMultiFragment extends MiniscriptFragment {
119
+ readonly type: "sortedmulti";
120
+ readonly threshold: number;
121
+ readonly keys: string[];
122
+ }
123
+ /**
124
+ * multi_a(k, key1, key2, ...) - k-of-n multisig (Taproot)
125
+ */
126
+ interface MultiAFragment extends MiniscriptFragment {
127
+ readonly type: "multi_a";
128
+ readonly threshold: number;
129
+ readonly keys: string[];
130
+ }
131
+ /**
132
+ * sortedmulti_a(k, key1, key2, ...) - k-of-n multisig with sorted keys (Taproot)
133
+ */
134
+ interface SortedMultiAFragment extends MiniscriptFragment {
135
+ readonly type: "sortedmulti_a";
136
+ readonly threshold: number;
137
+ readonly keys: string[];
138
+ }
139
+ /**
140
+ * Union of all fragment types
141
+ */
142
+ type Fragment = PkFragment | PkhFragment | Sha256Fragment | Hash256Fragment | Hash160Fragment | Ripemd160Fragment | OlderFragment | AfterFragment | AndVFragment | OrDFragment | OrIFragment | VerifyWrapper | MultiFragment | SortedMultiFragment | MultiAFragment | SortedMultiAFragment;
143
+ /**
144
+ * Create a pk() fragment for a key placeholder.
145
+ * @param key Key placeholder string (e.g., "@0/**")
146
+ */
147
+ declare function pk(key: string): PkFragment;
148
+ /**
149
+ * Create a pkh() fragment for a key placeholder.
150
+ * @param key Key placeholder string (e.g., "@0/**")
151
+ */
152
+ declare function pkh(key: string): PkhFragment;
153
+ /**
154
+ * Create a sha256() fragment with a preimage hash.
155
+ * @param hash 32-byte hash as 64 hex characters
156
+ */
157
+ declare function sha256(hash: string): Sha256Fragment;
158
+ /**
159
+ * Create a hash256() fragment (double SHA256).
160
+ * @param hash 32-byte hash as 64 hex characters
161
+ */
162
+ declare function hash256(hash: string): Hash256Fragment;
163
+ /**
164
+ * Create a hash160() fragment (SHA256 + RIPEMD160).
165
+ * @param hash 20-byte hash as 40 hex characters
166
+ */
167
+ declare function hash160(hash: string): Hash160Fragment;
168
+ /**
169
+ * Create a ripemd160() fragment.
170
+ * @param hash 20-byte hash as 40 hex characters
171
+ */
172
+ declare function ripemd160(hash: string): Ripemd160Fragment;
173
+ /**
174
+ * Create an older() fragment for relative timelocks.
175
+ * @param blocks Number of blocks (must be positive, max 2^31-1)
176
+ */
177
+ declare function older(blocks: number): OlderFragment;
178
+ /**
179
+ * Create an after() fragment for absolute timelocks.
180
+ * @param time Block height or timestamp
181
+ */
182
+ declare function after(time: number): AfterFragment;
183
+ /**
184
+ * Create an and_v() fragment combining two conditions.
185
+ */
186
+ declare function and_v(left: Fragment, right: Fragment): AndVFragment;
187
+ /**
188
+ * Create an or_d() fragment for alternative conditions.
189
+ * Requires X to be Bdu (dissatisfiable).
190
+ */
191
+ declare function or_d(left: Fragment, right: Fragment): OrDFragment;
192
+ /**
193
+ * Create an or_i() fragment for IF/ELSE alternatives.
194
+ * Compiles to: IF [X] ELSE [Z] ENDIF
195
+ * Satisfaction: sat(X) 1; sat(Z) 0
196
+ */
197
+ declare function or_i(left: Fragment, right: Fragment): OrIFragment;
198
+ /**
199
+ * Wrap a fragment with v: (verify).
200
+ */
201
+ declare function v(inner: Fragment): VerifyWrapper;
202
+ /**
203
+ * Create a multi() fragment for k-of-n multisig (SegWit).
204
+ * @param threshold Number of required signatures
205
+ * @param keys Key placeholder strings
206
+ */
207
+ declare function multi(threshold: number, keys: string[]): MultiFragment;
208
+ /**
209
+ * Create a sortedmulti() fragment for k-of-n multisig with sorted keys (SegWit).
210
+ * Keys are sorted lexicographically in the resulting script.
211
+ * @param threshold Number of required signatures
212
+ * @param keys Key placeholder strings
213
+ */
214
+ declare function sortedmulti(threshold: number, keys: string[]): SortedMultiFragment;
215
+ /**
216
+ * Create a multi_a() fragment for k-of-n multisig (Taproot).
217
+ * Uses OP_CHECKSIGADD for efficient Taproot multisig.
218
+ * @param threshold Number of required signatures
219
+ * @param keys Key placeholder strings
220
+ */
221
+ declare function multi_a(threshold: number, keys: string[]): MultiAFragment;
222
+ /**
223
+ * Create a sortedmulti_a() fragment for k-of-n multisig with sorted keys (Taproot).
224
+ * Keys are sorted lexicographically in the resulting script.
225
+ * @param threshold Number of required signatures
226
+ * @param keys Key placeholder strings
227
+ */
228
+ declare function sortedmulti_a(threshold: number, keys: string[]): SortedMultiAFragment;
229
+
230
+ type NetworkName = "mainnet" | "testnet" | "regtest";
231
+ /** Key with xpub - enables BIP-388 policy generation and child derivation */
232
+ interface XpubKey {
233
+ /** Master fingerprint (8 hex chars) */
234
+ fingerprint?: string;
235
+ /** Origin path e.g. "48'/1'/0'/2'" */
236
+ originPath?: string;
237
+ /** Extended public key (xpub/tpub) */
238
+ xpub: string;
239
+ /** Child index for derivation (default: 0) */
240
+ index?: number;
241
+ /** Change path: 0 = receive, 1 = change (default: 0) */
242
+ change?: 0 | 1;
243
+ }
244
+ /** Raw public key - no policy generation, just script building */
245
+ interface RawKey {
246
+ /** Compressed (33 bytes / 66 hex) or x-only (32 bytes / 64 hex) */
247
+ pubkey: string;
248
+ }
249
+ /** Either xpub-based or raw pubkey */
250
+ type Key = XpubKey | RawKey;
251
+ /** Type guard for XpubKey */
252
+ declare function isXpubKey(key: Key): key is XpubKey;
253
+ /** Type guard for RawKey */
254
+ declare function isRawKey(key: Key): key is RawKey;
255
+ interface KeyInfo {
256
+ fingerprint?: string;
257
+ originPath?: string;
258
+ xpub: string;
259
+ }
260
+ interface TapLeaf {
261
+ script: Buffer;
262
+ hash: Buffer;
263
+ }
264
+ interface TaprootOutput {
265
+ /** The P2TR address */
266
+ address: string;
267
+ /** The scriptPubkey for this output */
268
+ scriptPubkey: Buffer;
269
+ /** Internal public key (x-only, 32 bytes) */
270
+ internalPubkey: Buffer;
271
+ /** Merkle root of the tap tree (32 bytes) */
272
+ merkleRoot: Buffer;
273
+ /** Tweak applied to internal key */
274
+ tweak: Buffer;
275
+ /** Tweaked output key (x-only, 32 bytes) */
276
+ outputKey: Buffer;
277
+ }
278
+ interface SegwitOutput {
279
+ /** The P2WSH address */
280
+ address: string;
281
+ /** The scriptPubkey for this output */
282
+ scriptPubkey: Buffer;
283
+ /** The witness script (redeemScript) */
284
+ witnessScript: Buffer;
285
+ /** SHA256 hash of witness script */
286
+ scriptHash: Buffer;
287
+ }
288
+
289
+ /**
290
+ * BIP-388 Wallet Policy Builder
291
+ *
292
+ * Provides typesafe construction of wallet policy templates for Ledger devices.
293
+ * Wallet policies are a compact representation of descriptor templates with
294
+ * a separate key information vector.
295
+ *
296
+ * @see https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki
297
+ */
298
+
299
+ /**
300
+ * A key placeholder in a policy template.
301
+ * Format: @N/** where N is the index into the keys array.
302
+ */
303
+ type KeyPlaceholder = `@${number}/**`;
304
+ /**
305
+ * Create a key placeholder for a given index.
306
+ */
307
+ declare function keyPlaceholder(index: number): KeyPlaceholder;
308
+ /**
309
+ * A tap tree node - either a leaf or a branch with two children.
310
+ */
311
+ type TapTree = Fragment | [TapTree, TapTree];
312
+ /**
313
+ * Build a tr() descriptor template string.
314
+ * @param internalKeyIndex Index of the internal key in the keys array
315
+ * @param tree Optional tap tree of script leaves
316
+ */
317
+ declare function trDescriptor(internalKeyIndex: number, tree?: TapTree): string;
318
+ /**
319
+ * Build a wsh() descriptor template string.
320
+ * @param script The miniscript fragment inside wsh()
321
+ */
322
+ declare function wshDescriptor(script: Fragment): string;
323
+ /**
324
+ * Build a wpkh() descriptor template string.
325
+ * @param keyIndex Index of the key in the keys array
326
+ */
327
+ declare function wpkhDescriptor(keyIndex: number): string;
328
+ /**
329
+ * BIP-388 Wallet Policy
330
+ */
331
+ interface WalletPolicy {
332
+ /** Human-readable name for the policy */
333
+ name: string;
334
+ /** Descriptor template with @N/** placeholders */
335
+ template: string;
336
+ /** Ordered list of key origins */
337
+ keys: KeyInfo[];
338
+ }
339
+ /**
340
+ * Options for building a wallet policy.
341
+ */
342
+ interface PolicyOptions {
343
+ /** Human-readable name (max 64 chars recommended) */
344
+ name: string;
345
+ /** Keys in the order they're referenced (@0, @1, ...) */
346
+ keys: KeyInfo[];
347
+ }
348
+ /**
349
+ * Build a complete wallet policy for a Taproot output.
350
+ */
351
+ declare function buildTaprootPolicy(internalKeyIndex: number, tree: TapTree | undefined, options: PolicyOptions): WalletPolicy;
352
+ /**
353
+ * Build a complete wallet policy for a SegWit (P2WSH) output.
354
+ */
355
+ declare function buildSegwitPolicy(script: Fragment, options: PolicyOptions): WalletPolicy;
356
+ /**
357
+ * Format KeyInfo as a string for BIP-388 key vector.
358
+ * e.g., "[d34db33f/48'/0'/0'/2']xpub6ERApfZ..."
359
+ */
360
+ declare function formatKeyInfo(info: KeyInfo): string;
361
+ /**
362
+ * Create a KeyInfo for a bare xpub (no origin info).
363
+ * Used for external keys like NUMS.
364
+ */
365
+ declare function bareKey(xpub: string): KeyInfo;
366
+
367
+ /**
368
+ * HTLC (Hash Time-Locked Contract) Policy Builders
369
+ *
370
+ * Constructs BIP-388 wallet policies for HTLC patterns in both
371
+ * Taproot and SegWit variants.
372
+ */
373
+
374
+ /**
375
+ * Parameters for building a Taproot HTLC policy.
376
+ */
377
+ interface TaprootHtlcPolicyParams {
378
+ /** Name for the policy */
379
+ name: string;
380
+ /** SHA256 hash of the secret (64 hex chars) */
381
+ secretHash: string;
382
+ /** Timelock value for the refund path */
383
+ timelock: number;
384
+ /** Key info for NUMS (internal key) */
385
+ numsKey: KeyInfo;
386
+ /** Key info for the payee */
387
+ payeeKey: KeyInfo;
388
+ /** Key info for the payer */
389
+ payerKey: KeyInfo;
390
+ }
391
+ /**
392
+ * Build a Taproot HTLC wallet policy.
393
+ *
394
+ * Creates a policy with:
395
+ * - Internal key: NUMS (index 0) - no key path spend
396
+ * - Secret leaf: and_v(v:sha256(H), pk(@1))
397
+ * - Timeout leaf: and_v(v:older(N), pk(@2))
398
+ */
399
+ declare function buildTaprootHtlcPolicy(params: TaprootHtlcPolicyParams): WalletPolicy;
400
+ /**
401
+ * Parameters for building a SegWit HTLC policy.
402
+ */
403
+ interface SegwitHtlcPolicyParams {
404
+ /** Name for the policy */
405
+ name: string;
406
+ /** SHA256 hash of the secret (64 hex chars) */
407
+ secretHash: string;
408
+ /** Timelock value for the refund path */
409
+ timelock: number;
410
+ /** Key info for the payee */
411
+ payeeKey: KeyInfo;
412
+ /** Key info for the payer */
413
+ payerKey: KeyInfo;
414
+ }
415
+ /**
416
+ * Build a SegWit HTLC wallet policy.
417
+ *
418
+ * Creates a policy with:
419
+ * - Secret path (IF): and_v(v:sha256(H), pk(@0))
420
+ * - Timeout path (ELSE): and_v(v:pk(@1), after(N))
421
+ *
422
+ * Uses or_i which compiles to IF [X] ELSE [Z] ENDIF
423
+ */
424
+ declare function buildSegwitHtlcPolicy(params: SegwitHtlcPolicyParams): WalletPolicy;
425
+
426
+ /**
427
+ * Multisig Policy Builders
428
+ *
429
+ * Constructs BIP-388 wallet policies for multisig patterns in both
430
+ * Taproot (multi_a/sortedmulti_a) and SegWit (multi/sortedmulti) variants.
431
+ */
432
+
433
+ /**
434
+ * Parameters for building a SegWit multisig policy.
435
+ */
436
+ interface SegwitMultisigPolicyParams {
437
+ /** Name for the policy */
438
+ name: string;
439
+ /** Number of required signatures */
440
+ threshold: number;
441
+ /** Keys (order matters for non-sorted multisig) */
442
+ keys: KeyInfo[];
443
+ /** Sort keys lexicographically (default: true) */
444
+ sorted?: boolean;
445
+ }
446
+ /**
447
+ * Build a SegWit multisig wallet policy.
448
+ *
449
+ * Creates a policy with:
450
+ * - wsh(sortedmulti(k, @0/**, @1/**, ...)) for sorted (default)
451
+ * - wsh(multi(k, @0/**, @1/**, ...)) for non-sorted
452
+ */
453
+ declare function buildSegwitMultisigPolicy(params: SegwitMultisigPolicyParams): WalletPolicy;
454
+ /**
455
+ * Parameters for building a Taproot multisig policy.
456
+ */
457
+ interface TaprootMultisigPolicyParams {
458
+ /** Name for the policy */
459
+ name: string;
460
+ /** Number of required signatures */
461
+ threshold: number;
462
+ /** Keys (order matters for non-sorted multisig) */
463
+ keys: KeyInfo[];
464
+ /** Sort keys lexicographically (default: true) */
465
+ sorted?: boolean;
466
+ }
467
+ /**
468
+ * Build a Taproot multisig wallet policy (script path spend).
469
+ *
470
+ * Creates a policy with:
471
+ * - tr(@0/**, sortedmulti_a(k, @1/**, @2/**, ...)) for sorted (default)
472
+ * - tr(@0/**, multi_a(k, @1/**, @2/**, ...)) for non-sorted
473
+ *
474
+ * Note: First key is used as internal key. For script-only spend,
475
+ * use a NUMS key as the first key.
476
+ */
477
+ declare function buildTaprootMultisigPolicy(params: TaprootMultisigPolicyParams): WalletPolicy;
478
+
479
+ /**
480
+ * pk() Script Builder
481
+ *
482
+ * Compiles to: <pubkey> OP_CHECKSIG
483
+ *
484
+ * Used in:
485
+ * - wsh(pk(...)) for P2WSH single-key outputs
486
+ * - Taproot script leaves
487
+ */
488
+ /**
489
+ * Build a pk() script.
490
+ *
491
+ * @param pubkey - Compressed public key (33 bytes) or x-only pubkey (32 bytes for Taproot)
492
+ * @returns Compiled script buffer
493
+ *
494
+ * @example
495
+ * ```ts
496
+ * const script = pkScript(pubkey);
497
+ * // <pubkey> OP_CHECKSIG
498
+ * ```
499
+ */
500
+ declare function pkScript(pubkey: Buffer): Buffer;
501
+
502
+ /**
503
+ * pkh() Script Builder
504
+ *
505
+ * Compiles to: OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG
506
+ *
507
+ * Used in:
508
+ * - wsh(pkh(...)) for P2WSH with pubkey hash
509
+ * - Legacy P2PKH (though typically handled by bitcoinjs-lib payments)
510
+ */
511
+ /**
512
+ * Build a pkh() script from a public key.
513
+ *
514
+ * @param pubkey - Compressed public key (33 bytes)
515
+ * @returns Compiled script buffer
516
+ *
517
+ * @example
518
+ * ```ts
519
+ * const script = pkhScript(pubkey);
520
+ * // OP_DUP OP_HASH160 <hash160(pubkey)> OP_EQUALVERIFY OP_CHECKSIG
521
+ * ```
522
+ */
523
+ declare function pkhScript(pubkey: Buffer): Buffer;
524
+ /**
525
+ * Build a pkh() script from a pubkey hash directly.
526
+ *
527
+ * @param pubkeyHash - 20-byte HASH160 of the public key
528
+ * @returns Compiled script buffer
529
+ */
530
+ declare function pkhScriptFromHash(pubkeyHash: Buffer): Buffer;
531
+
532
+ /**
533
+ * multi() / sortedmulti() Script Builder
534
+ *
535
+ * Compiles to: OP_M <pubkey1> <pubkey2> ... <pubkeyN> OP_N OP_CHECKMULTISIG
536
+ *
537
+ * Used in:
538
+ * - wsh(multi(...)) for P2WSH multisig
539
+ * - wsh(sortedmulti(...)) with lexicographically sorted keys
540
+ * - Bare multisig (top-level, limited to 3 keys)
541
+ * - sh(multi(...)) for P2SH multisig (limited to 15 keys)
542
+ */
543
+ /**
544
+ * Encode a number for use in Bitcoin Script.
545
+ * For values 0, uses OP_0.
546
+ * For values 1-16, uses OP_1 through OP_16.
547
+ * For values > 16, uses minimal push encoding per BIP-383.
548
+ *
549
+ * @param n - Number to encode
550
+ * @returns Opcode number or Buffer for values > 16
551
+ */
552
+ declare function encodeScriptInt(n: number): number | Buffer;
553
+ /**
554
+ * Build a multi() script (k-of-n multisig) for SegWit.
555
+ *
556
+ * @param threshold - Number of required signatures (k), max 20
557
+ * @param pubkeys - Array of compressed public keys (33 bytes each)
558
+ * @param sorted - If true, sort keys lexicographically (sortedmulti behavior)
559
+ * @returns Compiled script buffer
560
+ *
561
+ * @example
562
+ * ```ts
563
+ * const script = multiScript(2, [pubkey1, pubkey2, pubkey3]);
564
+ * // OP_2 <pk1> <pk2> <pk3> OP_3 OP_CHECKMULTISIG
565
+ * ```
566
+ */
567
+ declare function multiScript(threshold: number, pubkeys: Buffer[], sorted?: boolean): Buffer;
568
+ /**
569
+ * Build a sortedmulti() script (k-of-n multisig with sorted keys).
570
+ *
571
+ * Keys are sorted lexicographically for deterministic script generation.
572
+ *
573
+ * @param threshold - Number of required signatures (k)
574
+ * @param pubkeys - Array of compressed public keys (33 bytes each)
575
+ * @returns Compiled script buffer
576
+ */
577
+ declare function sortedMultiScript(threshold: number, pubkeys: Buffer[]): Buffer;
578
+ /**
579
+ * Build a bare multi() script that supports both compressed and uncompressed keys.
580
+ *
581
+ * This is used for:
582
+ * - Top-level bare multisig (limited to 3 keys per BIP-383)
583
+ * - Legacy P2SH multisig (limited to 15 keys)
584
+ *
585
+ * Unlike multiScript(), this function accepts uncompressed pubkeys (65 bytes).
586
+ *
587
+ * @param threshold - Number of required signatures (k)
588
+ * @param pubkeys - Array of public keys (33 or 65 bytes each)
589
+ * @param sorted - If true, sort keys lexicographically (sortedmulti behavior)
590
+ * @returns Compiled script buffer
591
+ *
592
+ * @example
593
+ * ```ts
594
+ * const script = bareMultiScript(1, [compressedKey, uncompressedKey]);
595
+ * // OP_1 <pk1> <pk2> OP_2 OP_CHECKMULTISIG
596
+ * ```
597
+ */
598
+ declare function bareMultiScript(threshold: number, pubkeys: Buffer[], sorted?: boolean): Buffer;
599
+ /**
600
+ * Build a sortedmulti() script for bare/legacy multisig with sorted keys.
601
+ *
602
+ * Supports both compressed and uncompressed keys.
603
+ *
604
+ * @param threshold - Number of required signatures (k)
605
+ * @param pubkeys - Array of public keys (33 or 65 bytes each)
606
+ * @returns Compiled script buffer
607
+ */
608
+ declare function sortedBareMultiScript(threshold: number, pubkeys: Buffer[]): Buffer;
609
+
610
+ /**
611
+ * Hashlock Script Builders
612
+ *
613
+ * Scripts that require revealing a preimage to spend.
614
+ *
615
+ * Used in HTLCs and other hash-locked contracts.
616
+ */
617
+ /**
618
+ * Hash types supported for hashlock scripts.
619
+ */
620
+ type HashType$1 = "sha256" | "hash256" | "hash160" | "ripemd160";
621
+ /**
622
+ * Build a hashlock script with pubkey check.
623
+ *
624
+ * Miniscript: and_v(v:sha256(H), pk(K))
625
+ * Compiles to: SIZE <32> EQUALVERIFY <HASHOP> <hash> EQUALVERIFY <pubkey> CHECKSIG
626
+ *
627
+ * The SIZE check ensures the preimage is exactly the expected length.
628
+ *
629
+ * @param hash - The hash that the preimage must match
630
+ * @param pubkey - Public key that must sign (32 or 33 bytes)
631
+ * @param hashType - Hash function to use (default: sha256)
632
+ * @returns Compiled script buffer
633
+ *
634
+ * @example
635
+ * ```ts
636
+ * const script = hashlockScript(secretHash, payeePubkey);
637
+ * // SIZE 32 EQUALVERIFY SHA256 <hash> EQUALVERIFY <pubkey> CHECKSIG
638
+ * ```
639
+ */
640
+ declare function hashlockScript(hash: Buffer, pubkey: Buffer, hashType?: HashType$1): Buffer;
641
+ /**
642
+ * Build a simple hashlock script without pubkey (just hash verification).
643
+ *
644
+ * Compiles to: SIZE <len> EQUALVERIFY <HASHOP> <hash> EQUAL
645
+ *
646
+ * @param hash - The hash that the preimage must match
647
+ * @param hashType - Hash function to use (default: sha256)
648
+ * @returns Compiled script buffer
649
+ */
650
+ declare function simpleHashlockScript(hash: Buffer, hashType?: HashType$1): Buffer;
651
+
652
+ /**
653
+ * Timelock Script Builders
654
+ *
655
+ * Scripts that can only be spent after a certain time/block.
656
+ *
657
+ * - CLTV (OP_CHECKLOCKTIMEVERIFY): Absolute timelock
658
+ * - CSV (OP_CHECKSEQUENCEVERIFY): Relative timelock
659
+ */
660
+ /**
661
+ * Encode a number for use in Bitcoin Script.
662
+ *
663
+ * Numbers in Script use a minimal encoding:
664
+ * - 0 is OP_0
665
+ * - 1-16 are OP_1 through OP_16
666
+ * - Larger numbers use little-endian encoding with sign bit
667
+ */
668
+ declare function encodeScriptNumber(n: number): Buffer | number;
669
+ /**
670
+ * Build an absolute timelock script with pubkey check.
671
+ *
672
+ * Miniscript: and_v(v:after(N), pk(K))
673
+ * Compiles to: <N> CHECKLOCKTIMEVERIFY VERIFY <pubkey> CHECKSIG
674
+ *
675
+ * @param locktime - Block height or Unix timestamp
676
+ * @param pubkey - Public key that must sign (32 or 33 bytes)
677
+ * @param useDrop - Use OP_DROP instead of OP_VERIFY after CLTV
678
+ * @returns Compiled script buffer
679
+ *
680
+ * @example
681
+ * ```ts
682
+ * // Spend only after block 800000
683
+ * const script = cltvScript(800000, payerPubkey);
684
+ * ```
685
+ */
686
+ declare function cltvScript(locktime: number, pubkey: Buffer, useDrop?: boolean): Buffer;
687
+ /**
688
+ * Build a relative timelock script with pubkey check.
689
+ *
690
+ * Miniscript: and_v(v:older(N), pk(K))
691
+ * Compiles to: <N> CHECKSEQUENCEVERIFY VERIFY <pubkey> CHECKSIG
692
+ *
693
+ * @param sequence - Relative locktime in blocks or time units
694
+ * @param pubkey - Public key that must sign (32 or 33 bytes)
695
+ * @param useDrop - Use DROP instead of VERIFY (for Taproot compatibility)
696
+ * @returns Compiled script buffer
697
+ *
698
+ * @example
699
+ * ```ts
700
+ * // Spend only after 144 blocks (~1 day)
701
+ * const script = csvScript(144, recoveryPubkey);
702
+ * ```
703
+ */
704
+ declare function csvScript(sequence: number, pubkey: Buffer, useDrop?: boolean): Buffer;
705
+ /**
706
+ * Build a simple absolute timelock script (no pubkey).
707
+ *
708
+ * Compiles to: <N> CHECKLOCKTIMEVERIFY DROP OP_TRUE
709
+ *
710
+ * @param locktime - Block height or Unix timestamp
711
+ * @returns Compiled script buffer
712
+ */
713
+ declare function simpleCltvScript(locktime: number): Buffer;
714
+
715
+ declare function getNetwork(name: NetworkName): Network;
716
+ /**
717
+ * Derive a child public key from an xpub at the given path.
718
+ * @param xpub Extended public key
719
+ * @param change 0 for receive, 1 for change
720
+ * @param index Child index
721
+ * @param network Network for xpub parsing
722
+ * @returns BIP32 node at the derived path
723
+ */
724
+ declare function deriveFromXpub(xpub: string, change: number, index: number, network: Network): BIP32Interface;
725
+ /**
726
+ * Resolve a Key to its compressed public key (33 bytes).
727
+ * For XpubKey, derives the child key. For RawKey, validates and returns the pubkey.
728
+ */
729
+ declare function resolveCompressedPubkey(key: Key, network: NetworkName): Buffer;
730
+ /**
731
+ * Resolve a Key to its x-only public key (32 bytes) for Taproot.
732
+ */
733
+ declare function resolveXOnlyPubkey(key: Key, network: NetworkName): Buffer;
734
+ /**
735
+ * Convert compressed (33 byte) or uncompressed (65 byte) pubkey to x-only (32 byte).
736
+ */
737
+ declare function toXOnly(pubkey: Buffer): Buffer;
738
+ /**
739
+ * Parse a hex public key string to Buffer, validating format.
740
+ * Accepts compressed (66 hex), x-only (64 hex), or uncompressed (130 hex).
741
+ */
742
+ declare function parsePublicKey(pubkeyHex: string): Buffer;
743
+ /**
744
+ * Check if a compressed public key is a valid secp256k1 point.
745
+ */
746
+ declare function isValidPoint(pubkey: Buffer): boolean;
747
+ /**
748
+ * Convert an XpubKey to KeyInfo for BIP-388 policy.
749
+ */
750
+ declare function toKeyInfo(key: XpubKey): KeyInfo;
751
+ /**
752
+ * Try to extract KeyInfo from an array of Keys.
753
+ * Returns null if any key is a RawKey (no xpub info available).
754
+ */
755
+ declare function extractKeyInfos(keys: Key[]): KeyInfo[] | null;
756
+
757
+ type HashType = "sha256" | "hash256" | "ripemd160" | "hash160";
758
+ type TimelockType = "blocks" | "timestamp";
759
+ interface HtlcParams<K extends Key = Key> {
760
+ /** Recipient key - spends by revealing preimage */
761
+ payee: K;
762
+ /** Sender key - refund after timeout */
763
+ payer: K;
764
+ /** Hash of the secret (hex string) */
765
+ secretHash: string;
766
+ /** Timelock value (block height or timestamp) */
767
+ timelock: number;
768
+ /** Network */
769
+ network: NetworkName;
770
+ }
771
+ interface TaprootHtlcParams<K extends Key = Key> extends HtlcParams<K> {
772
+ /** Optional name for BIP-388 policy */
773
+ name?: string;
774
+ }
775
+ interface SegwitHtlcParams<K extends Key = Key> extends HtlcParams<K> {
776
+ /** Hash function used (default: sha256) */
777
+ hashType?: HashType;
778
+ /** Timelock type (default: blocks) */
779
+ timelockType?: TimelockType;
780
+ /** Optional name for BIP-388 policy */
781
+ name?: string;
782
+ }
783
+ /** Witness builders for HTLC spending */
784
+ interface HtlcWitness {
785
+ /** Build witness stack for secret reveal spend (payee) */
786
+ secret: (signature: Buffer, preimage: Buffer) => Buffer[];
787
+ /** Build witness stack for timeout refund spend (payer) */
788
+ timeout: (signature: Buffer) => Buffer[];
789
+ }
790
+ interface TaprootHtlc extends TaprootOutput {
791
+ /** Secret reveal leaf (payee spends with preimage) */
792
+ secretLeaf: TapLeaf;
793
+ /** Timeout leaf (payer spends after timelock) */
794
+ timeoutLeaf: TapLeaf;
795
+ /** Get control block for spending a specific leaf */
796
+ controlBlock: (leaf: "secret" | "timeout") => Buffer;
797
+ /** Witness builders */
798
+ witness: HtlcWitness;
799
+ /** BIP-388 policy (only if xpub keys provided) */
800
+ policy: WalletPolicy | null;
801
+ /** The timelock value */
802
+ timelock: number;
803
+ }
804
+ interface SegwitHtlc extends SegwitOutput {
805
+ /** Witness builders */
806
+ witness: HtlcWitness;
807
+ /** BIP-388 policy (only if xpub keys provided) */
808
+ policy: WalletPolicy | null;
809
+ /** The timelock value */
810
+ timelock: number;
811
+ }
812
+ interface MultisigParams<K extends Key = Key> {
813
+ /** Number of required signatures */
814
+ threshold: number;
815
+ /** Public keys */
816
+ keys: K[];
817
+ /** Sort keys lexicographically (default: true) */
818
+ sorted?: boolean;
819
+ /** Network */
820
+ network: NetworkName;
821
+ /** Optional name for BIP-388 policy */
822
+ name?: string;
823
+ }
824
+ interface TaprootMultisigParams<K extends Key = Key> extends MultisigParams<K> {
825
+ /** Use key path spend with MuSig2 (default: false = script-only) */
826
+ keyPathSpend?: boolean;
827
+ }
828
+ /** Witness builder for multisig spending */
829
+ interface MultisigWitness {
830
+ /** Build witness stack for spending */
831
+ (signatures: Buffer[]): Buffer[];
832
+ }
833
+ interface TaprootMultisig extends TaprootOutput {
834
+ /** BIP-388 policy (only if xpub keys provided) */
835
+ policy: WalletPolicy | null;
836
+ /** Build witness stack for script path spend */
837
+ witness: MultisigWitness;
838
+ /** The tap leaf containing the multisig script */
839
+ scriptLeaf: TapLeaf;
840
+ /** Get control block for script path spend */
841
+ controlBlock: Buffer;
842
+ }
843
+ interface SegwitMultisig extends SegwitOutput {
844
+ /** BIP-388 policy (only if xpub keys provided) */
845
+ policy: WalletPolicy | null;
846
+ /** Build witness stack for spending */
847
+ witness: MultisigWitness;
848
+ }
849
+
850
+ /**
851
+ * Create a Taproot HTLC with two script paths:
852
+ * - Secret path: payee can spend by revealing the preimage
853
+ * - Timeout path: payer can refund after the timelock expires
854
+ *
855
+ * Secret leaf script:
856
+ * ```
857
+ * OP_SHA256 <secretHash> OP_EQUALVERIFY <payeePubkey> OP_CHECKSIG
858
+ * ```
859
+ *
860
+ * Timeout leaf script:
861
+ * ```
862
+ * <timelock> OP_CHECKLOCKTIMEVERIFY OP_DROP <payerPubkey> OP_CHECKSIG
863
+ * ```
864
+ *
865
+ * Uses NUMS as internal key (script-only spend, no key path).
866
+ *
867
+ * @example
868
+ * ```ts
869
+ * const htlc = taprootHtlc({
870
+ * payee: { pubkey: '02abc...' },
871
+ * payer: { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: "86'/1'/0'" },
872
+ * secretHash: 'deadbeef...',
873
+ * timelock: 800000,
874
+ * network: 'testnet'
875
+ * });
876
+ *
877
+ * // Fund it
878
+ * console.log(htlc.address);
879
+ *
880
+ * // Spend with preimage
881
+ * const witness = htlc.witnessSecret(signature, preimage);
882
+ * ```
883
+ */
884
+ declare function taprootHtlc<K extends Key>(params: TaprootHtlcParams<K>): TaprootHtlc;
885
+ /**
886
+ * Extract the preimage from a spent HTLC witness.
887
+ * @param witness The witness stack from a transaction input
888
+ * @param secretHash Optional hash to validate the preimage against
889
+ * @returns The preimage hex string, or null if not found/invalid
890
+ */
891
+ declare function extractSecret$1(witness: Buffer[], secretHash?: string): string | null;
892
+
893
+ /**
894
+ * Create a Taproot multisig output using script path spend.
895
+ *
896
+ * Uses multi_a / sortedmulti_a which leverages OP_CHECKSIGADD for
897
+ * efficient k-of-n multisig in Tapscript.
898
+ *
899
+ * Script structure (for 2-of-3):
900
+ * ```
901
+ * <pubkey1> OP_CHECKSIG
902
+ * <pubkey2> OP_CHECKSIGADD
903
+ * <pubkey3> OP_CHECKSIGADD
904
+ * OP_2 OP_NUMEQUAL
905
+ * ```
906
+ *
907
+ * Uses NUMS as internal key (script-only spend, no key path).
908
+ *
909
+ * @example
910
+ * ```ts
911
+ * const multisig = taprootMultisig({
912
+ * threshold: 2,
913
+ * keys: [
914
+ * { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: "86'/1'/0'" },
915
+ * { xpub: 'tpub...', fingerprint: 'eeff0011', originPath: "86'/1'/0'" },
916
+ * { xpub: 'tpub...', fingerprint: '22334455', originPath: "86'/1'/0'" },
917
+ * ],
918
+ * network: 'testnet'
919
+ * });
920
+ *
921
+ * console.log(multisig.address); // tb1p...
922
+ * ```
923
+ */
924
+ declare function taprootMultisig<K extends Key>(params: TaprootMultisigParams<K>): TaprootMultisig;
925
+
926
+ /**
927
+ * NUMS (Nothing Up My Sleeve) point for script-only Taproot.
928
+ *
929
+ * This is the BIP-341 recommended NUMS point. It has no known discrete log,
930
+ * meaning no one can spend via the key path - only script paths are valid.
931
+ *
932
+ * Public key: lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)
933
+ * This is SHA256("TapTweak")[:32] interpreted as an x-coordinate.
934
+ */
935
+ declare const NUMS: {
936
+ /** Compressed public key (33 bytes as hex) */
937
+ readonly pubkey: "0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0";
938
+ /** X-only public key (32 bytes as hex) - for taproot internal key */
939
+ readonly xonly: "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0";
940
+ /** X-only as Buffer */
941
+ readonly xonlyBuffer: Buffer;
942
+ /** Compressed as Buffer */
943
+ readonly pubkeyBuffer: Buffer;
944
+ /**
945
+ * Get NUMS xpub for a specific network.
946
+ * Constructed with:
947
+ * - Public key: NUMS point
948
+ * - Chain code: 32 zero bytes
949
+ * - Depth/parent/index: all zeros (acts like master key)
950
+ */
951
+ readonly xpub: (network: NetworkName) => string;
952
+ };
953
+
954
+ /**
955
+ * Create a SegWit (P2WSH) HTLC with SHA256 hashlock.
956
+ *
957
+ * Miniscript policy: or_d(and_v(v:sha256(H), pk(@0)), and_v(v:pk(@1), after(N)))
958
+ *
959
+ * Compiles to:
960
+ * ```
961
+ * SIZE <32> EQUALVERIFY SHA256 <H> EQUALVERIFY <payeePubkey> CHECKSIG
962
+ * IFDUP NOTIF
963
+ * <payerPubkey> CHECKSIGVERIFY <timelock> CHECKLOCKTIMEVERIFY
964
+ * ENDIF
965
+ * ```
966
+ *
967
+ * - Payee: reveals preimage, signature satisfies first branch (returns true, skips NOTIF)
968
+ * - Payer: provides signature + timelock satisfied (first branch fails, enters NOTIF)
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * const htlc = segwitHtlc({
973
+ * payee: { pubkey: '02abc...' },
974
+ * payer: { pubkey: '03def...' },
975
+ * secretHash: 'deadbeef...', // sha256(preimage)
976
+ * timelock: 800000,
977
+ * network: 'testnet'
978
+ * });
979
+ *
980
+ * console.log(htlc.address); // bc1q...
981
+ * ```
982
+ */
983
+ declare function segwitHtlc<K extends Key>(params: SegwitHtlcParams<K>): SegwitHtlc;
984
+ /**
985
+ * Extract the preimage from a spent SegWit HTLC witness.
986
+ * @param witness The witness stack from a transaction input
987
+ * @param secretHash Optional sha256 hash to validate the preimage against
988
+ * @returns The preimage hex string, or null if not found/invalid
989
+ */
990
+ declare function extractSecret(witness: Buffer[], secretHash?: string): string | null;
991
+
992
+ /**
993
+ * Create a SegWit (P2WSH) multisig output.
994
+ *
995
+ * Script structure (for sorted=true, which is default):
996
+ * ```
997
+ * OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG
998
+ * ```
999
+ *
1000
+ * Keys are sorted lexicographically when sorted=true (recommended for
1001
+ * deterministic addresses regardless of key order in params).
1002
+ *
1003
+ * @example
1004
+ * ```ts
1005
+ * const multisig = segwitMultisig({
1006
+ * threshold: 2,
1007
+ * keys: [
1008
+ * { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: "48'/1'/0'/2'" },
1009
+ * { xpub: 'tpub...', fingerprint: 'eeff0011', originPath: "48'/1'/0'/2'" },
1010
+ * { xpub: 'tpub...', fingerprint: '22334455', originPath: "48'/1'/0'/2'" },
1011
+ * ],
1012
+ * network: 'testnet'
1013
+ * });
1014
+ *
1015
+ * console.log(multisig.address); // tb1q...
1016
+ * ```
1017
+ */
1018
+ declare function segwitMultisig<K extends Key>(params: MultisigParams<K>): SegwitMultisig;
1019
+
1020
+ export { type AfterFragment, type AndVFragment, type Fragment, type Hash160Fragment, type Hash256Fragment, type HashType$1 as HashType, type HtlcWitness, type Key, type KeyInfo, type MultiAFragment, type MultiFragment, type MultisigParams, type MultisigWitness, NUMS, type NetworkName, type OlderFragment, type OrDFragment, type OrIFragment, type PkFragment, type PkhFragment, type PolicyOptions, type RawKey, type Ripemd160Fragment, type SegwitHtlc, type SegwitHtlcParams, type SegwitHtlcPolicyParams, type SegwitMultisig, type SegwitMultisigPolicyParams, type SegwitOutput, type Sha256Fragment, type SortedMultiAFragment, type SortedMultiFragment, type TapLeaf, type TapTree, type TaprootHtlc, type TaprootHtlcParams, type TaprootHtlcPolicyParams, type TaprootMultisig, type TaprootMultisigParams, type TaprootMultisigPolicyParams, type TaprootOutput, type VerifyWrapper, type WalletPolicy, type XpubKey, after, and_v, bareKey, bareMultiScript, buildSegwitHtlcPolicy, buildSegwitMultisigPolicy, buildSegwitPolicy, buildTaprootHtlcPolicy, buildTaprootMultisigPolicy, buildTaprootPolicy, cltvScript, csvScript, deriveFromXpub, encodeScriptInt, encodeScriptNumber, extractKeyInfos, extractSecret as extractSegwitSecret, extractSecret$1 as extractTaprootSecret, formatKeyInfo, getNetwork, hash160, hash256, hashlockScript, isRawKey, isValidPoint, isXpubKey, keyPlaceholder, multi, multiScript, multi_a, older, or_d, or_i, parsePublicKey, pk, pkScript, pkh, pkhScript, pkhScriptFromHash, resolveCompressedPubkey, resolveXOnlyPubkey, ripemd160, segwitHtlc, segwitMultisig, sha256, simpleCltvScript, simpleHashlockScript, sortedBareMultiScript, sortedMultiScript, sortedmulti, sortedmulti_a, taprootHtlc, taprootMultisig, toKeyInfo, toXOnly, trDescriptor, v, wpkhDescriptor, wshDescriptor };