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 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/miniscript.ts","../src/bip388.ts","../src/patterns/htlc.ts","../src/patterns/multisig.ts","../src/scripts/pk.ts","../src/scripts/pkh.ts","../src/scripts/multi.ts","../src/scripts/hashlock.ts","../src/scripts/timelock.ts","../src/keys.ts","../src/types.ts","../src/patterns/taproot/htlc.ts","../src/patterns/taproot/nums.ts","../src/patterns/taproot/script.ts","../src/patterns/taproot/multisig.ts","../src/patterns/segwit/htlc.ts","../src/patterns/segwit/multisig.ts"],"sourcesContent":["/**\n * bip388 - BIP-388 wallet policy utilities for TypeScript\n */\n\n// ============================================================================\n// BIP-379 Miniscript Fragments\n// ============================================================================\n\nexport {\n // Fragment builders\n pk,\n pkh,\n sha256,\n hash256,\n hash160,\n ripemd160,\n older,\n after,\n and_v,\n or_d,\n or_i,\n v,\n // Multisig fragment builders\n multi,\n sortedmulti,\n multi_a,\n sortedmulti_a,\n} from \"./miniscript.js\";\n\n// ============================================================================\n// BIP-388 Wallet Policies\n// ============================================================================\n\nexport {\n // Descriptor builders\n trDescriptor,\n wshDescriptor,\n wpkhDescriptor,\n // Generic policy builders\n buildTaprootPolicy,\n buildSegwitPolicy,\n // Key helpers\n keyPlaceholder,\n formatKeyInfo,\n bareKey,\n} from \"./bip388.js\";\n\n// ============================================================================\n// Pattern-Specific Policy Builders\n// ============================================================================\n\nexport {\n buildTaprootHtlcPolicy,\n buildSegwitHtlcPolicy,\n buildTaprootMultisigPolicy,\n buildSegwitMultisigPolicy,\n} from \"./patterns/index.js\";\n\n// ============================================================================\n// Script Builders (low-level)\n// ============================================================================\n\nexport {\n // pk() / pkh() scripts\n pkScript,\n pkhScript,\n pkhScriptFromHash,\n // Multisig scripts\n multiScript,\n sortedMultiScript,\n bareMultiScript,\n sortedBareMultiScript,\n encodeScriptInt,\n // Hashlock scripts\n hashlockScript,\n simpleHashlockScript,\n // Timelock scripts\n cltvScript,\n csvScript,\n simpleCltvScript,\n encodeScriptNumber,\n} from \"./scripts/index.js\";\n\nexport type { HashType } from \"./scripts/index.js\";\n\n// ============================================================================\n// Utilities (for power users)\n// ============================================================================\n\nexport {\n // Network\n getNetwork,\n // Key derivation\n deriveFromXpub,\n resolveCompressedPubkey,\n resolveXOnlyPubkey,\n toXOnly,\n parsePublicKey,\n isValidPoint,\n // BIP-388 key formatting\n toKeyInfo,\n extractKeyInfos,\n} from \"./keys.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type {\n // Network\n NetworkName,\n\n // Keys\n XpubKey,\n RawKey,\n Key,\n KeyInfo,\n\n // Outputs\n TapLeaf,\n TaprootOutput,\n SegwitOutput,\n} from \"./types.js\";\n\nexport type {\n // Wallet Policy\n WalletPolicy,\n PolicyOptions,\n TapTree,\n} from \"./bip388.js\";\n\nexport type {\n // Pattern params\n TaprootHtlcPolicyParams,\n SegwitHtlcPolicyParams,\n SegwitMultisigPolicyParams,\n TaprootMultisigPolicyParams,\n} from \"./patterns/index.js\";\n\nexport type {\n // Miniscript fragments\n Fragment,\n PkFragment,\n PkhFragment,\n Sha256Fragment,\n Hash256Fragment,\n Hash160Fragment,\n Ripemd160Fragment,\n OlderFragment,\n AfterFragment,\n AndVFragment,\n OrDFragment,\n OrIFragment,\n VerifyWrapper,\n MultiFragment,\n SortedMultiFragment,\n MultiAFragment,\n SortedMultiAFragment,\n} from \"./miniscript.js\";\n\n// ============================================================================\n// HTLC Builders\n// ============================================================================\n\nexport { taprootHtlc, NUMS } from \"./patterns/taproot/index.js\";\nexport { segwitHtlc } from \"./patterns/segwit/index.js\";\n\n// ============================================================================\n// Multisig Builders\n// ============================================================================\n\nexport { taprootMultisig } from \"./patterns/taproot/index.js\";\nexport { segwitMultisig } from \"./patterns/segwit/index.js\";\n\n// ============================================================================\n// Secret Extraction\n// ============================================================================\n\nexport { extractSecret as extractTaprootSecret } from \"./patterns/taproot/htlc.js\";\nexport { extractSecret as extractSegwitSecret } from \"./patterns/segwit/htlc.js\";\n\nexport { isXpubKey, isRawKey } from \"./types.js\";\n\nexport {\n // HTLC\n TaprootHtlcParams,\n SegwitHtlcParams,\n TaprootHtlc,\n SegwitHtlc,\n HtlcWitness,\n\n // Multisig\n MultisigParams,\n TaprootMultisigParams,\n TaprootMultisig,\n SegwitMultisig,\n MultisigWitness,\n} from \"./patterns/types.js\";\n","/**\n * BIP-379 Miniscript Fragment Builders\n *\n * Provides typesafe construction of miniscript fragments for use in\n * Bitcoin Script descriptors (wsh, tr).\n *\n * @see https://github.com/bitcoin/bips/blob/master/bip-0379.mediawiki\n */\n\n// ============================================================================\n// Fragment Types\n// ============================================================================\n\n/**\n * Base interface for all miniscript fragments.\n * Each fragment knows how to serialize itself to a string.\n */\ninterface MiniscriptFragment {\n readonly type: string;\n toString(): string;\n}\n\n/**\n * pk(@N/**) - Public key check\n */\nexport interface PkFragment extends MiniscriptFragment {\n readonly type: \"pk\";\n readonly key: string;\n}\n\n/**\n * pkh(@N/**) - Public key hash check\n */\nexport interface PkhFragment extends MiniscriptFragment {\n readonly type: \"pkh\";\n readonly key: string;\n}\n\n/**\n * sha256(H) - SHA256 preimage check\n */\nexport interface Sha256Fragment extends MiniscriptFragment {\n readonly type: \"sha256\";\n readonly hash: string;\n}\n\n/**\n * hash256(H) - Double SHA256 preimage check\n */\nexport interface Hash256Fragment extends MiniscriptFragment {\n readonly type: \"hash256\";\n readonly hash: string;\n}\n\n/**\n * hash160(H) - HASH160 preimage check\n */\nexport interface Hash160Fragment extends MiniscriptFragment {\n readonly type: \"hash160\";\n readonly hash: string;\n}\n\n/**\n * ripemd160(H) - RIPEMD160 preimage check\n */\nexport interface Ripemd160Fragment extends MiniscriptFragment {\n readonly type: \"ripemd160\";\n readonly hash: string;\n}\n\n/**\n * older(N) - Relative timelock (CSV)\n */\nexport interface OlderFragment extends MiniscriptFragment {\n readonly type: \"older\";\n readonly blocks: number;\n}\n\n/**\n * after(N) - Absolute timelock (CLTV)\n */\nexport interface AfterFragment extends MiniscriptFragment {\n readonly type: \"after\";\n readonly time: number;\n}\n\n/**\n * and_v(X, Y) - Verify AND\n */\nexport interface AndVFragment extends MiniscriptFragment {\n readonly type: \"and_v\";\n readonly left: Fragment;\n readonly right: Fragment;\n}\n\n/**\n * or_d(X, Y) - Dissatisfiable OR\n */\nexport interface OrDFragment extends MiniscriptFragment {\n readonly type: \"or_d\";\n readonly left: Fragment;\n readonly right: Fragment;\n}\n\n/**\n * or_i(X, Z) - IF/ELSE OR\n */\nexport interface OrIFragment extends MiniscriptFragment {\n readonly type: \"or_i\";\n readonly left: Fragment;\n readonly right: Fragment;\n}\n\n/**\n * v:X - Verify wrapper\n */\nexport interface VerifyWrapper extends MiniscriptFragment {\n readonly type: \"v\";\n readonly inner: Fragment;\n}\n\n/**\n * multi(k, key1, key2, ...) - k-of-n multisig (SegWit)\n */\nexport interface MultiFragment extends MiniscriptFragment {\n readonly type: \"multi\";\n readonly threshold: number;\n readonly keys: string[];\n}\n\n/**\n * sortedmulti(k, key1, key2, ...) - k-of-n multisig with sorted keys (SegWit)\n */\nexport interface SortedMultiFragment extends MiniscriptFragment {\n readonly type: \"sortedmulti\";\n readonly threshold: number;\n readonly keys: string[];\n}\n\n/**\n * multi_a(k, key1, key2, ...) - k-of-n multisig (Taproot)\n */\nexport interface MultiAFragment extends MiniscriptFragment {\n readonly type: \"multi_a\";\n readonly threshold: number;\n readonly keys: string[];\n}\n\n/**\n * sortedmulti_a(k, key1, key2, ...) - k-of-n multisig with sorted keys (Taproot)\n */\nexport interface SortedMultiAFragment extends MiniscriptFragment {\n readonly type: \"sortedmulti_a\";\n readonly threshold: number;\n readonly keys: string[];\n}\n\n/**\n * Union of all fragment types\n */\nexport type Fragment =\n | PkFragment\n | PkhFragment\n | Sha256Fragment\n | Hash256Fragment\n | Hash160Fragment\n | Ripemd160Fragment\n | OlderFragment\n | AfterFragment\n | AndVFragment\n | OrDFragment\n | OrIFragment\n | VerifyWrapper\n | MultiFragment\n | SortedMultiFragment\n | MultiAFragment\n | SortedMultiAFragment;\n\n// ============================================================================\n// Fragment Builders\n// ============================================================================\n\n/**\n * Create a pk() fragment for a key placeholder.\n * @param key Key placeholder string (e.g., \"@0/**\")\n */\nexport function pk(key: string): PkFragment {\n return {\n type: \"pk\",\n key,\n toString() {\n return `pk(${this.key})`;\n },\n };\n}\n\n/**\n * Create a pkh() fragment for a key placeholder.\n * @param key Key placeholder string (e.g., \"@0/**\")\n */\nexport function pkh(key: string): PkhFragment {\n return {\n type: \"pkh\",\n key,\n toString() {\n return `pkh(${this.key})`;\n },\n };\n}\n\n/**\n * Create a sha256() fragment with a preimage hash.\n * @param hash 32-byte hash as 64 hex characters\n */\nexport function sha256(hash: string): Sha256Fragment {\n validateHash(hash, 64, \"sha256\");\n return {\n type: \"sha256\",\n hash,\n toString() {\n return `sha256(${this.hash})`;\n },\n };\n}\n\n/**\n * Create a hash256() fragment (double SHA256).\n * @param hash 32-byte hash as 64 hex characters\n */\nexport function hash256(hash: string): Hash256Fragment {\n validateHash(hash, 64, \"hash256\");\n return {\n type: \"hash256\",\n hash,\n toString() {\n return `hash256(${this.hash})`;\n },\n };\n}\n\n/**\n * Create a hash160() fragment (SHA256 + RIPEMD160).\n * @param hash 20-byte hash as 40 hex characters\n */\nexport function hash160(hash: string): Hash160Fragment {\n validateHash(hash, 40, \"hash160\");\n return {\n type: \"hash160\",\n hash,\n toString() {\n return `hash160(${this.hash})`;\n },\n };\n}\n\n/**\n * Create a ripemd160() fragment.\n * @param hash 20-byte hash as 40 hex characters\n */\nexport function ripemd160(hash: string): Ripemd160Fragment {\n validateHash(hash, 40, \"ripemd160\");\n return {\n type: \"ripemd160\",\n hash,\n toString() {\n return `ripemd160(${this.hash})`;\n },\n };\n}\n\n/**\n * Create an older() fragment for relative timelocks.\n * @param blocks Number of blocks (must be positive, max 2^31-1)\n */\nexport function older(blocks: number): OlderFragment {\n validateTimelock(blocks, \"older\");\n return {\n type: \"older\",\n blocks,\n toString() {\n return `older(${this.blocks})`;\n },\n };\n}\n\n/**\n * Create an after() fragment for absolute timelocks.\n * @param time Block height or timestamp\n */\nexport function after(time: number): AfterFragment {\n validateTimelock(time, \"after\");\n return {\n type: \"after\",\n time,\n toString() {\n return `after(${this.time})`;\n },\n };\n}\n\n/**\n * Create an and_v() fragment combining two conditions.\n */\nexport function and_v(left: Fragment, right: Fragment): AndVFragment {\n return {\n type: \"and_v\",\n left,\n right,\n toString() {\n return `and_v(${this.left.toString()},${this.right.toString()})`;\n },\n };\n}\n\n/**\n * Create an or_d() fragment for alternative conditions.\n * Requires X to be Bdu (dissatisfiable).\n */\nexport function or_d(left: Fragment, right: Fragment): OrDFragment {\n return {\n type: \"or_d\",\n left,\n right,\n toString() {\n return `or_d(${this.left.toString()},${this.right.toString()})`;\n },\n };\n}\n\n/**\n * Create an or_i() fragment for IF/ELSE alternatives.\n * Compiles to: IF [X] ELSE [Z] ENDIF\n * Satisfaction: sat(X) 1; sat(Z) 0\n */\nexport function or_i(left: Fragment, right: Fragment): OrIFragment {\n return {\n type: \"or_i\",\n left,\n right,\n toString() {\n return `or_i(${this.left.toString()},${this.right.toString()})`;\n },\n };\n}\n\n/**\n * Wrap a fragment with v: (verify).\n */\nexport function v(inner: Fragment): VerifyWrapper {\n return {\n type: \"v\",\n inner,\n toString() {\n return `v:${this.inner.toString()}`;\n },\n };\n}\n\n/**\n * Create a multi() fragment for k-of-n multisig (SegWit).\n * @param threshold Number of required signatures\n * @param keys Key placeholder strings\n */\nexport function multi(threshold: number, keys: string[]): MultiFragment {\n validateMultisig(threshold, keys.length, \"multi\");\n return {\n type: \"multi\",\n threshold,\n keys,\n toString() {\n return `multi(${this.threshold},${this.keys.join(\",\")})`;\n },\n };\n}\n\n/**\n * Create a sortedmulti() fragment for k-of-n multisig with sorted keys (SegWit).\n * Keys are sorted lexicographically in the resulting script.\n * @param threshold Number of required signatures\n * @param keys Key placeholder strings\n */\nexport function sortedmulti(\n threshold: number,\n keys: string[],\n): SortedMultiFragment {\n validateMultisig(threshold, keys.length, \"sortedmulti\");\n return {\n type: \"sortedmulti\",\n threshold,\n keys,\n toString() {\n return `sortedmulti(${this.threshold},${this.keys.join(\",\")})`;\n },\n };\n}\n\n/**\n * Create a multi_a() fragment for k-of-n multisig (Taproot).\n * Uses OP_CHECKSIGADD for efficient Taproot multisig.\n * @param threshold Number of required signatures\n * @param keys Key placeholder strings\n */\nexport function multi_a(threshold: number, keys: string[]): MultiAFragment {\n validateMultisig(threshold, keys.length, \"multi_a\");\n return {\n type: \"multi_a\",\n threshold,\n keys,\n toString() {\n return `multi_a(${this.threshold},${this.keys.join(\",\")})`;\n },\n };\n}\n\n/**\n * Create a sortedmulti_a() fragment for k-of-n multisig with sorted keys (Taproot).\n * Keys are sorted lexicographically in the resulting script.\n * @param threshold Number of required signatures\n * @param keys Key placeholder strings\n */\nexport function sortedmulti_a(\n threshold: number,\n keys: string[],\n): SortedMultiAFragment {\n validateMultisig(threshold, keys.length, \"sortedmulti_a\");\n return {\n type: \"sortedmulti_a\",\n threshold,\n keys,\n toString() {\n return `sortedmulti_a(${this.threshold},${this.keys.join(\",\")})`;\n },\n };\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nfunction validateHash(\n hash: string,\n expectedLength: number,\n name: string,\n): void {\n if (!hash || typeof hash !== \"string\") {\n throw new Error(`${name} must be a hex string`);\n }\n if (hash.length !== expectedLength) {\n throw new Error(\n `${name} must be ${expectedLength / 2} bytes (${expectedLength} hex chars), got ${hash.length}`,\n );\n }\n if (!/^[0-9a-fA-F]+$/.test(hash)) {\n throw new Error(`${name} must be a valid hex string`);\n }\n}\n\nfunction validateTimelock(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${name} must be a positive integer`);\n }\n if (value > 0x7fffffff) {\n throw new Error(`${name} exceeds maximum value (2^31-1)`);\n }\n}\n\nfunction validateMultisig(\n threshold: number,\n numKeys: number,\n name: string,\n): void {\n if (!Number.isInteger(threshold) || threshold <= 0) {\n throw new Error(`${name} threshold must be a positive integer`);\n }\n if (numKeys < 1) {\n throw new Error(`${name} requires at least one key`);\n }\n if (threshold > numKeys) {\n throw new Error(\n `${name} threshold (${threshold}) cannot exceed number of keys (${numKeys})`,\n );\n }\n // BIP-0383: Standard multi() is limited to 20 keys in SegWit\n // Taproot multi_a has no such limit but we set a reasonable max\n if (numKeys > 20 && (name === \"multi\" || name === \"sortedmulti\")) {\n throw new Error(`${name} is limited to 20 keys in SegWit`);\n }\n}\n","/**\n * BIP-388 Wallet Policy Builder\n *\n * Provides typesafe construction of wallet policy templates for Ledger devices.\n * Wallet policies are a compact representation of descriptor templates with\n * a separate key information vector.\n *\n * @see https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki\n */\n\nimport type { KeyInfo } from \"./types.js\";\nimport type { Fragment } from \"./miniscript.js\";\n\n// Re-export miniscript fragments for convenience\nexport {\n pk,\n pkh,\n sha256,\n hash256,\n hash160,\n ripemd160,\n older,\n after,\n and_v,\n or_d,\n or_i,\n v,\n multi,\n sortedmulti,\n multi_a,\n sortedmulti_a,\n} from \"./miniscript.js\";\n\nexport type {\n Fragment,\n PkFragment,\n PkhFragment,\n Sha256Fragment,\n Hash256Fragment,\n Hash160Fragment,\n Ripemd160Fragment,\n OlderFragment,\n AfterFragment,\n AndVFragment,\n OrDFragment,\n OrIFragment,\n VerifyWrapper,\n MultiFragment,\n SortedMultiFragment,\n MultiAFragment,\n SortedMultiAFragment,\n} from \"./miniscript.js\";\n\n// ============================================================================\n// Key Placeholder Types\n// ============================================================================\n\n/**\n * A key placeholder in a policy template.\n * Format: @N/** where N is the index into the keys array.\n */\nexport type KeyPlaceholder = `@${number}/**`;\n\n/**\n * Create a key placeholder for a given index.\n */\nexport function keyPlaceholder(index: number): KeyPlaceholder {\n if (!Number.isInteger(index) || index < 0) {\n throw new Error(`Key index must be a non-negative integer, got: ${index}`);\n }\n return `@${index}/**` as KeyPlaceholder;\n}\n\n// ============================================================================\n// Descriptor Wrappers\n// ============================================================================\n\n/**\n * A tap tree node - either a leaf or a branch with two children.\n */\nexport type TapTree = Fragment | [TapTree, TapTree];\n\n/**\n * Build a tr() descriptor template string.\n * @param internalKeyIndex Index of the internal key in the keys array\n * @param tree Optional tap tree of script leaves\n */\nexport function trDescriptor(internalKeyIndex: number, tree?: TapTree): string {\n const internalKey = keyPlaceholder(internalKeyIndex);\n if (!tree) {\n return `tr(${internalKey})`;\n }\n const treeStr = serializeTapTree(tree);\n return `tr(${internalKey},${treeStr})`;\n}\n\n/**\n * Build a wsh() descriptor template string.\n * @param script The miniscript fragment inside wsh()\n */\nexport function wshDescriptor(script: Fragment): string {\n return `wsh(${script.toString()})`;\n}\n\n/**\n * Build a wpkh() descriptor template string.\n * @param keyIndex Index of the key in the keys array\n */\nexport function wpkhDescriptor(keyIndex: number): string {\n return `wpkh(${keyPlaceholder(keyIndex)})`;\n}\n\n// ============================================================================\n// Wallet Policy Construction\n// ============================================================================\n\n/**\n * BIP-388 Wallet Policy\n */\nexport interface WalletPolicy {\n /** Human-readable name for the policy */\n name: string;\n /** Descriptor template with @N/** placeholders */\n template: string;\n /** Ordered list of key origins */\n keys: KeyInfo[];\n}\n\n/**\n * Options for building a wallet policy.\n */\nexport interface PolicyOptions {\n /** Human-readable name (max 64 chars recommended) */\n name: string;\n /** Keys in the order they're referenced (@0, @1, ...) */\n keys: KeyInfo[];\n}\n\n/**\n * Build a complete wallet policy for a Taproot output.\n */\nexport function buildTaprootPolicy(\n internalKeyIndex: number,\n tree: TapTree | undefined,\n options: PolicyOptions,\n): WalletPolicy {\n validatePolicyOptions(options);\n return {\n name: options.name,\n template: trDescriptor(internalKeyIndex, tree),\n keys: options.keys,\n };\n}\n\n/**\n * Build a complete wallet policy for a SegWit (P2WSH) output.\n */\nexport function buildSegwitPolicy(\n script: Fragment,\n options: PolicyOptions,\n): WalletPolicy {\n validatePolicyOptions(options);\n return {\n name: options.name,\n template: wshDescriptor(script),\n keys: options.keys,\n };\n}\n\n// ============================================================================\n// Key Info Formatting\n// ============================================================================\n\n/**\n * Format KeyInfo as a string for BIP-388 key vector.\n * e.g., \"[d34db33f/48'/0'/0'/2']xpub6ERApfZ...\"\n */\nexport function formatKeyInfo(info: KeyInfo): string {\n let result = \"\";\n if (info.fingerprint || info.originPath) {\n result += \"[\";\n if (info.fingerprint) {\n result += info.fingerprint;\n }\n if (info.originPath) {\n result += \"/\" + info.originPath;\n }\n result += \"]\";\n }\n result += info.xpub;\n return result;\n}\n\n/**\n * Create a KeyInfo for a bare xpub (no origin info).\n * Used for external keys like NUMS.\n */\nexport function bareKey(xpub: string): KeyInfo {\n return { xpub };\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nfunction validatePolicyOptions(options: PolicyOptions): void {\n if (!options.name || typeof options.name !== \"string\") {\n throw new Error(\"Policy name is required\");\n }\n if (options.name.length > 64) {\n throw new Error(\"Policy name should not exceed 64 characters\");\n }\n if (!Array.isArray(options.keys) || options.keys.length === 0) {\n throw new Error(\"At least one key is required\");\n }\n}\n\nfunction serializeTapTree(tree: TapTree): string {\n if (Array.isArray(tree)) {\n // It's a branch: {left, right}\n const [left, right] = tree;\n return `{${serializeTapTree(left)},${serializeTapTree(right)}}`;\n }\n // It's a leaf (fragment)\n return tree.toString();\n}\n","/**\n * HTLC (Hash Time-Locked Contract) Policy Builders\n *\n * Constructs BIP-388 wallet policies for HTLC patterns in both\n * Taproot and SegWit variants.\n */\n\nimport type { KeyInfo } from \"../types.js\";\nimport type { WalletPolicy, TapTree } from \"../bip388.js\";\nimport { pk, sha256, after, and_v, or_i, v } from \"../miniscript.js\";\nimport { keyPlaceholder, trDescriptor, wshDescriptor } from \"../bip388.js\";\n\n// ============================================================================\n// Taproot HTLC Policy\n// ============================================================================\n\n/**\n * Parameters for building a Taproot HTLC policy.\n */\nexport interface TaprootHtlcPolicyParams {\n /** Name for the policy */\n name: string;\n /** SHA256 hash of the secret (64 hex chars) */\n secretHash: string;\n /** Timelock value for the refund path */\n timelock: number;\n /** Key info for NUMS (internal key) */\n numsKey: KeyInfo;\n /** Key info for the payee */\n payeeKey: KeyInfo;\n /** Key info for the payer */\n payerKey: KeyInfo;\n}\n\n/**\n * Build a Taproot HTLC wallet policy.\n *\n * Creates a policy with:\n * - Internal key: NUMS (index 0) - no key path spend\n * - Secret leaf: and_v(v:sha256(H), pk(@1))\n * - Timeout leaf: and_v(v:older(N), pk(@2))\n */\nexport function buildTaprootHtlcPolicy(\n params: TaprootHtlcPolicyParams,\n): WalletPolicy {\n const { name, secretHash, timelock, numsKey, payeeKey, payerKey } = params;\n\n // Validate inputs\n validateHash(secretHash, 64, \"secretHash\");\n validateTimelock(timelock, \"timelock\");\n\n // Build the tap tree: {secret_leaf, timeout_leaf}\n // Note: using after() for absolute timelock (CLTV), not older() which is relative (CSV)\n const secretLeaf = and_v(v(sha256(secretHash)), pk(keyPlaceholder(1)));\n const timeoutLeaf = and_v(v(after(timelock)), pk(keyPlaceholder(2)));\n const tree: TapTree = [secretLeaf, timeoutLeaf];\n\n return {\n name,\n template: trDescriptor(0, tree),\n keys: [numsKey, payeeKey, payerKey],\n };\n}\n\n// ============================================================================\n// SegWit HTLC Policy\n// ============================================================================\n\n/**\n * Parameters for building a SegWit HTLC policy.\n */\nexport interface SegwitHtlcPolicyParams {\n /** Name for the policy */\n name: string;\n /** SHA256 hash of the secret (64 hex chars) */\n secretHash: string;\n /** Timelock value for the refund path */\n timelock: number;\n /** Key info for the payee */\n payeeKey: KeyInfo;\n /** Key info for the payer */\n payerKey: KeyInfo;\n}\n\n/**\n * Build a SegWit HTLC wallet policy.\n *\n * Creates a policy with:\n * - Secret path (IF): and_v(v:sha256(H), pk(@0))\n * - Timeout path (ELSE): and_v(v:pk(@1), after(N))\n *\n * Uses or_i which compiles to IF [X] ELSE [Z] ENDIF\n */\nexport function buildSegwitHtlcPolicy(\n params: SegwitHtlcPolicyParams,\n): WalletPolicy {\n const { name, secretHash, timelock, payeeKey, payerKey } = params;\n\n // Validate inputs\n validateHash(secretHash, 64, \"secretHash\");\n validateTimelock(timelock, \"timelock\");\n\n // Build the script: or_i(secret_path, timeout_path)\n // or_i compiles to: IF [secret_path] ELSE [timeout_path] ENDIF\n // Satisfaction: sat(secret_path) 1; sat(timeout_path) 0\n //\n // and_v(X,Y) requires X to be V type, Y to be B/K/V\n // v:sha256(H) is V type, pk(@0) is B type -> and_v works\n // v:pk(@1) is V type, after(N) is B type -> and_v works\n const secretPath = and_v(v(sha256(secretHash)), pk(keyPlaceholder(0)));\n const timeoutPath = and_v(v(pk(keyPlaceholder(1))), after(timelock));\n const script = or_i(secretPath, timeoutPath);\n\n return {\n name,\n template: wshDescriptor(script),\n keys: [payeeKey, payerKey],\n };\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nfunction validateHash(\n hash: string,\n expectedLength: number,\n name: string,\n): void {\n if (!hash || typeof hash !== \"string\") {\n throw new Error(`${name} must be a hex string`);\n }\n if (hash.length !== expectedLength) {\n throw new Error(\n `${name} must be ${expectedLength / 2} bytes (${expectedLength} hex chars), got ${hash.length}`,\n );\n }\n if (!/^[0-9a-fA-F]+$/.test(hash)) {\n throw new Error(`${name} must be a valid hex string`);\n }\n}\n\nfunction validateTimelock(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${name} must be a positive integer`);\n }\n if (value > 0x7fffffff) {\n throw new Error(`${name} exceeds maximum value (2^31-1)`);\n }\n}\n","/**\n * Multisig Policy Builders\n *\n * Constructs BIP-388 wallet policies for multisig patterns in both\n * Taproot (multi_a/sortedmulti_a) and SegWit (multi/sortedmulti) variants.\n */\n\nimport type { KeyInfo } from \"../types.js\";\nimport type { WalletPolicy } from \"../bip388.js\";\nimport { multi, sortedmulti, multi_a, sortedmulti_a } from \"../miniscript.js\";\nimport { keyPlaceholder, trDescriptor, wshDescriptor } from \"../bip388.js\";\n\n// ============================================================================\n// SegWit Multisig Policy\n// ============================================================================\n\n/**\n * Parameters for building a SegWit multisig policy.\n */\nexport interface SegwitMultisigPolicyParams {\n /** Name for the policy */\n name: string;\n /** Number of required signatures */\n threshold: number;\n /** Keys (order matters for non-sorted multisig) */\n keys: KeyInfo[];\n /** Sort keys lexicographically (default: true) */\n sorted?: boolean;\n}\n\n/**\n * Build a SegWit multisig wallet policy.\n *\n * Creates a policy with:\n * - wsh(sortedmulti(k, @0/**, @1/**, ...)) for sorted (default)\n * - wsh(multi(k, @0/**, @1/**, ...)) for non-sorted\n */\nexport function buildSegwitMultisigPolicy(\n params: SegwitMultisigPolicyParams,\n): WalletPolicy {\n const { name, threshold, keys, sorted = true } = params;\n\n if (keys.length === 0) {\n throw new Error(\"At least one key is required\");\n }\n\n const keyPlaceholders = keys.map((_, i) => keyPlaceholder(i));\n const script = sorted\n ? sortedmulti(threshold, keyPlaceholders)\n : multi(threshold, keyPlaceholders);\n\n return {\n name,\n template: wshDescriptor(script),\n keys,\n };\n}\n\n// ============================================================================\n// Taproot Multisig Policy\n// ============================================================================\n\n/**\n * Parameters for building a Taproot multisig policy.\n */\nexport interface TaprootMultisigPolicyParams {\n /** Name for the policy */\n name: string;\n /** Number of required signatures */\n threshold: number;\n /** Keys (order matters for non-sorted multisig) */\n keys: KeyInfo[];\n /** Sort keys lexicographically (default: true) */\n sorted?: boolean;\n}\n\n/**\n * Build a Taproot multisig wallet policy (script path spend).\n *\n * Creates a policy with:\n * - tr(@0/**, sortedmulti_a(k, @1/**, @2/**, ...)) for sorted (default)\n * - tr(@0/**, multi_a(k, @1/**, @2/**, ...)) for non-sorted\n *\n * Note: First key is used as internal key. For script-only spend,\n * use a NUMS key as the first key.\n */\nexport function buildTaprootMultisigPolicy(\n params: TaprootMultisigPolicyParams,\n): WalletPolicy {\n const { name, threshold, keys, sorted = true } = params;\n\n if (keys.length < 2) {\n throw new Error(\n \"Taproot multisig requires at least 2 keys (internal key + script key)\",\n );\n }\n\n // Keys[0] is internal key, keys[1..n] are in the script\n const scriptKeyPlaceholders = keys\n .slice(1)\n .map((_, i) => keyPlaceholder(i + 1));\n const script = sorted\n ? sortedmulti_a(threshold, scriptKeyPlaceholders)\n : multi_a(threshold, scriptKeyPlaceholders);\n\n return {\n name,\n template: trDescriptor(0, script),\n keys,\n };\n}\n","/**\n * pk() Script Builder\n *\n * Compiles to: <pubkey> OP_CHECKSIG\n *\n * Used in:\n * - wsh(pk(...)) for P2WSH single-key outputs\n * - Taproot script leaves\n */\n\nimport { script as bscript, opcodes } from \"bitcoinjs-lib\";\n\n/**\n * Build a pk() script.\n *\n * @param pubkey - Compressed public key (33 bytes) or x-only pubkey (32 bytes for Taproot)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * const script = pkScript(pubkey);\n * // <pubkey> OP_CHECKSIG\n * ```\n */\nexport function pkScript(pubkey: Buffer): Buffer {\n if (pubkey.length !== 33 && pubkey.length !== 32) {\n throw new Error(\n `Invalid pubkey length: ${pubkey.length} (expected 32 or 33 bytes)`,\n );\n }\n\n return Buffer.from(bscript.compile([pubkey, opcodes.OP_CHECKSIG])) as Buffer;\n}\n","/**\n * pkh() Script Builder\n *\n * Compiles to: OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG\n *\n * Used in:\n * - wsh(pkh(...)) for P2WSH with pubkey hash\n * - Legacy P2PKH (though typically handled by bitcoinjs-lib payments)\n */\n\nimport { script as bscript, opcodes, crypto } from \"bitcoinjs-lib\";\n\n/**\n * Build a pkh() script from a public key.\n *\n * @param pubkey - Compressed public key (33 bytes)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * const script = pkhScript(pubkey);\n * // OP_DUP OP_HASH160 <hash160(pubkey)> OP_EQUALVERIFY OP_CHECKSIG\n * ```\n */\nexport function pkhScript(pubkey: Buffer): Buffer {\n if (pubkey.length !== 33) {\n throw new Error(\n `Invalid pubkey length: ${pubkey.length} (expected 33 bytes for compressed pubkey)`,\n );\n }\n\n const pubkeyHash = crypto.hash160(pubkey);\n\n return Buffer.from(\n bscript.compile([\n opcodes.OP_DUP,\n opcodes.OP_HASH160,\n pubkeyHash,\n opcodes.OP_EQUALVERIFY,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a pkh() script from a pubkey hash directly.\n *\n * @param pubkeyHash - 20-byte HASH160 of the public key\n * @returns Compiled script buffer\n */\nexport function pkhScriptFromHash(pubkeyHash: Buffer): Buffer {\n if (pubkeyHash.length !== 20) {\n throw new Error(\n `Invalid pubkey hash length: ${pubkeyHash.length} (expected 20 bytes)`,\n );\n }\n\n return Buffer.from(\n bscript.compile([\n opcodes.OP_DUP,\n opcodes.OP_HASH160,\n pubkeyHash,\n opcodes.OP_EQUALVERIFY,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n","/**\n * multi() / sortedmulti() Script Builder\n *\n * Compiles to: OP_M <pubkey1> <pubkey2> ... <pubkeyN> OP_N OP_CHECKMULTISIG\n *\n * Used in:\n * - wsh(multi(...)) for P2WSH multisig\n * - wsh(sortedmulti(...)) with lexicographically sorted keys\n * - Bare multisig (top-level, limited to 3 keys)\n * - sh(multi(...)) for P2SH multisig (limited to 15 keys)\n */\n\nimport { script as bscript, opcodes } from \"bitcoinjs-lib\";\n\n/**\n * Encode a number for use in Bitcoin Script.\n * For values 0, uses OP_0.\n * For values 1-16, uses OP_1 through OP_16.\n * For values > 16, uses minimal push encoding per BIP-383.\n *\n * @param n - Number to encode\n * @returns Opcode number or Buffer for values > 16\n */\nexport function encodeScriptInt(n: number): number | Buffer {\n if (n === 0) return opcodes.OP_0;\n if (n >= 1 && n <= 16) return opcodes.OP_1 - 1 + n;\n return Buffer.from(bscript.number.encode(n));\n}\n\n/**\n * Build a multi() script (k-of-n multisig) for SegWit.\n *\n * @param threshold - Number of required signatures (k), max 20\n * @param pubkeys - Array of compressed public keys (33 bytes each)\n * @param sorted - If true, sort keys lexicographically (sortedmulti behavior)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * const script = multiScript(2, [pubkey1, pubkey2, pubkey3]);\n * // OP_2 <pk1> <pk2> <pk3> OP_3 OP_CHECKMULTISIG\n * ```\n */\nexport function multiScript(\n threshold: number,\n pubkeys: Buffer[],\n sorted: boolean = false,\n): Buffer {\n if (threshold <= 0 || !Number.isInteger(threshold)) {\n throw new Error(\"threshold must be a positive integer\");\n }\n if (pubkeys.length === 0) {\n throw new Error(\"At least one pubkey is required\");\n }\n if (threshold > pubkeys.length) {\n throw new Error(\n `threshold (${threshold}) cannot exceed number of pubkeys (${pubkeys.length})`,\n );\n }\n if (pubkeys.length > 20) {\n throw new Error(\"SegWit multisig is limited to 20 keys\");\n }\n\n // Validate all pubkeys are 33 bytes (compressed) for SegWit\n for (const pk of pubkeys) {\n if (pk.length !== 33) {\n throw new Error(\n `Invalid pubkey length: ${pk.length} (expected 33 bytes for SegWit)`,\n );\n }\n }\n\n // Sort lexicographically if requested\n const keys = sorted ? [...pubkeys].sort(Buffer.compare) : pubkeys;\n\n return Buffer.from(\n bscript.compile([\n encodeScriptInt(threshold),\n ...keys,\n encodeScriptInt(keys.length),\n opcodes.OP_CHECKMULTISIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a sortedmulti() script (k-of-n multisig with sorted keys).\n *\n * Keys are sorted lexicographically for deterministic script generation.\n *\n * @param threshold - Number of required signatures (k)\n * @param pubkeys - Array of compressed public keys (33 bytes each)\n * @returns Compiled script buffer\n */\nexport function sortedMultiScript(\n threshold: number,\n pubkeys: Buffer[],\n): Buffer {\n return multiScript(threshold, pubkeys, true);\n}\n\n/**\n * Build a bare multi() script that supports both compressed and uncompressed keys.\n *\n * This is used for:\n * - Top-level bare multisig (limited to 3 keys per BIP-383)\n * - Legacy P2SH multisig (limited to 15 keys)\n *\n * Unlike multiScript(), this function accepts uncompressed pubkeys (65 bytes).\n *\n * @param threshold - Number of required signatures (k)\n * @param pubkeys - Array of public keys (33 or 65 bytes each)\n * @param sorted - If true, sort keys lexicographically (sortedmulti behavior)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * const script = bareMultiScript(1, [compressedKey, uncompressedKey]);\n * // OP_1 <pk1> <pk2> OP_2 OP_CHECKMULTISIG\n * ```\n */\nexport function bareMultiScript(\n threshold: number,\n pubkeys: Buffer[],\n sorted: boolean = false,\n): Buffer {\n if (threshold <= 0 || !Number.isInteger(threshold)) {\n throw new Error(\"threshold must be a positive integer\");\n }\n if (pubkeys.length === 0) {\n throw new Error(\"At least one pubkey is required\");\n }\n if (threshold > pubkeys.length) {\n throw new Error(\n `threshold (${threshold}) cannot exceed number of pubkeys (${pubkeys.length})`,\n );\n }\n\n // Validate all pubkeys are either 33 bytes (compressed) or 65 bytes (uncompressed)\n for (const pk of pubkeys) {\n if (pk.length !== 33 && pk.length !== 65) {\n throw new Error(\n `Invalid pubkey length: ${pk.length} (expected 33 or 65 bytes)`,\n );\n }\n }\n\n // Sort lexicographically if requested\n const keys = sorted ? [...pubkeys].sort(Buffer.compare) : pubkeys;\n\n return Buffer.from(\n bscript.compile([\n encodeScriptInt(threshold),\n ...keys,\n encodeScriptInt(keys.length),\n opcodes.OP_CHECKMULTISIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a sortedmulti() script for bare/legacy multisig with sorted keys.\n *\n * Supports both compressed and uncompressed keys.\n *\n * @param threshold - Number of required signatures (k)\n * @param pubkeys - Array of public keys (33 or 65 bytes each)\n * @returns Compiled script buffer\n */\nexport function sortedBareMultiScript(\n threshold: number,\n pubkeys: Buffer[],\n): Buffer {\n return bareMultiScript(threshold, pubkeys, true);\n}\n","/**\n * Hashlock Script Builders\n *\n * Scripts that require revealing a preimage to spend.\n *\n * Used in HTLCs and other hash-locked contracts.\n */\n\nimport { script as bscript, opcodes } from \"bitcoinjs-lib\";\n\n/**\n * Hash types supported for hashlock scripts.\n */\nexport type HashType = \"sha256\" | \"hash256\" | \"hash160\" | \"ripemd160\";\n\n/**\n * Get the opcode for a hash type.\n */\nfunction getHashOpcode(hashType: HashType): number {\n switch (hashType) {\n case \"sha256\":\n return opcodes.OP_SHA256;\n case \"hash256\":\n return opcodes.OP_HASH256;\n case \"hash160\":\n return opcodes.OP_HASH160;\n case \"ripemd160\":\n return opcodes.OP_RIPEMD160;\n }\n}\n\n/**\n * Get the expected hash length for a hash type.\n */\nfunction getHashLength(hashType: HashType): number {\n switch (hashType) {\n case \"sha256\":\n case \"hash256\":\n return 32;\n case \"hash160\":\n case \"ripemd160\":\n return 20;\n }\n}\n\n/**\n * Build a hashlock script with pubkey check.\n *\n * Miniscript: and_v(v:sha256(H), pk(K))\n * Compiles to: SIZE <32> EQUALVERIFY <HASHOP> <hash> EQUALVERIFY <pubkey> CHECKSIG\n *\n * The SIZE check ensures the preimage is exactly the expected length.\n *\n * @param hash - The hash that the preimage must match\n * @param pubkey - Public key that must sign (32 or 33 bytes)\n * @param hashType - Hash function to use (default: sha256)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * const script = hashlockScript(secretHash, payeePubkey);\n * // SIZE 32 EQUALVERIFY SHA256 <hash> EQUALVERIFY <pubkey> CHECKSIG\n * ```\n */\nexport function hashlockScript(\n hash: Buffer,\n pubkey: Buffer,\n hashType: HashType = \"sha256\",\n): Buffer {\n const expectedLen = getHashLength(hashType);\n if (hash.length !== expectedLen) {\n throw new Error(\n `Invalid hash length for ${hashType}: ${hash.length} (expected ${expectedLen} bytes)`,\n );\n }\n\n if (pubkey.length !== 32 && pubkey.length !== 33) {\n throw new Error(\n `Invalid pubkey length: ${pubkey.length} (expected 32 or 33 bytes)`,\n );\n }\n\n return Buffer.from(\n bscript.compile([\n // v:sha256(H) - verify wrapper with SIZE check for preimage length\n opcodes.OP_SIZE,\n bscript.number.encode(expectedLen),\n opcodes.OP_EQUALVERIFY,\n // Hash check\n getHashOpcode(hashType),\n hash,\n opcodes.OP_EQUALVERIFY,\n // pk(K)\n pubkey,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a simple hashlock script without pubkey (just hash verification).\n *\n * Compiles to: SIZE <len> EQUALVERIFY <HASHOP> <hash> EQUAL\n *\n * @param hash - The hash that the preimage must match\n * @param hashType - Hash function to use (default: sha256)\n * @returns Compiled script buffer\n */\nexport function simpleHashlockScript(\n hash: Buffer,\n hashType: HashType = \"sha256\",\n): Buffer {\n const expectedLen = getHashLength(hashType);\n if (hash.length !== expectedLen) {\n throw new Error(\n `Invalid hash length for ${hashType}: ${hash.length} (expected ${expectedLen} bytes)`,\n );\n }\n\n return Buffer.from(\n bscript.compile([\n opcodes.OP_SIZE,\n bscript.number.encode(expectedLen),\n opcodes.OP_EQUALVERIFY,\n getHashOpcode(hashType),\n hash,\n opcodes.OP_EQUAL,\n ]),\n ) as Buffer;\n}\n","/**\n * Timelock Script Builders\n *\n * Scripts that can only be spent after a certain time/block.\n *\n * - CLTV (OP_CHECKLOCKTIMEVERIFY): Absolute timelock\n * - CSV (OP_CHECKSEQUENCEVERIFY): Relative timelock\n */\n\nimport { script as bscript, opcodes } from \"bitcoinjs-lib\";\n\n/**\n * Encode a number for use in Bitcoin Script.\n *\n * Numbers in Script use a minimal encoding:\n * - 0 is OP_0\n * - 1-16 are OP_1 through OP_16\n * - Larger numbers use little-endian encoding with sign bit\n */\nexport function encodeScriptNumber(n: number): Buffer | number {\n if (n === 0) {\n return opcodes.OP_0;\n }\n if (n >= 1 && n <= 16) {\n return opcodes.OP_1 - 1 + n;\n }\n return Buffer.from(bscript.number.encode(n));\n}\n\n/**\n * Build an absolute timelock script with pubkey check.\n *\n * Miniscript: and_v(v:after(N), pk(K))\n * Compiles to: <N> CHECKLOCKTIMEVERIFY VERIFY <pubkey> CHECKSIG\n *\n * @param locktime - Block height or Unix timestamp\n * @param pubkey - Public key that must sign (32 or 33 bytes)\n * @param useDrop - Use OP_DROP instead of OP_VERIFY after CLTV\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * // Spend only after block 800000\n * const script = cltvScript(800000, payerPubkey);\n * ```\n */\nexport function cltvScript(\n locktime: number,\n pubkey: Buffer,\n useDrop: boolean = false,\n): Buffer {\n if (locktime <= 0) {\n throw new Error(\"locktime must be a positive number\");\n }\n if (locktime > 0x7fffffff) {\n throw new Error(\"locktime exceeds maximum value (2^31-1)\");\n }\n\n if (pubkey.length !== 32 && pubkey.length !== 33) {\n throw new Error(\n `Invalid pubkey length: ${pubkey.length} (expected 32 or 33 bytes)`,\n );\n }\n\n return Buffer.from(\n bscript.compile([\n encodeScriptNumber(locktime),\n opcodes.OP_CHECKLOCKTIMEVERIFY,\n useDrop ? opcodes.OP_DROP : opcodes.OP_VERIFY,\n pubkey,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a relative timelock script with pubkey check.\n *\n * Miniscript: and_v(v:older(N), pk(K))\n * Compiles to: <N> CHECKSEQUENCEVERIFY VERIFY <pubkey> CHECKSIG\n *\n * @param sequence - Relative locktime in blocks or time units\n * @param pubkey - Public key that must sign (32 or 33 bytes)\n * @param useDrop - Use DROP instead of VERIFY (for Taproot compatibility)\n * @returns Compiled script buffer\n *\n * @example\n * ```ts\n * // Spend only after 144 blocks (~1 day)\n * const script = csvScript(144, recoveryPubkey);\n * ```\n */\nexport function csvScript(\n sequence: number,\n pubkey: Buffer,\n useDrop: boolean = false,\n): Buffer {\n if (sequence <= 0) {\n throw new Error(\"sequence must be a positive number\");\n }\n if (sequence > 0x7fffffff) {\n throw new Error(\"sequence exceeds maximum value (2^31-1)\");\n }\n\n if (pubkey.length !== 32 && pubkey.length !== 33) {\n throw new Error(\n `Invalid pubkey length: ${pubkey.length} (expected 32 or 33 bytes)`,\n );\n }\n\n return Buffer.from(\n bscript.compile([\n encodeScriptNumber(sequence),\n opcodes.OP_CHECKSEQUENCEVERIFY,\n useDrop ? opcodes.OP_DROP : opcodes.OP_VERIFY,\n pubkey,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build a simple absolute timelock script (no pubkey).\n *\n * Compiles to: <N> CHECKLOCKTIMEVERIFY DROP OP_TRUE\n *\n * @param locktime - Block height or Unix timestamp\n * @returns Compiled script buffer\n */\nexport function simpleCltvScript(locktime: number): Buffer {\n if (locktime <= 0) {\n throw new Error(\"locktime must be a positive number\");\n }\n if (locktime > 0x7fffffff) {\n throw new Error(\"locktime exceeds maximum value (2^31-1)\");\n }\n\n return Buffer.from(\n bscript.compile([\n encodeScriptNumber(locktime),\n opcodes.OP_CHECKLOCKTIMEVERIFY,\n opcodes.OP_DROP,\n opcodes.OP_TRUE,\n ]),\n ) as Buffer;\n}\n","import * as ecc from \"@bitcoinerlab/secp256k1\";\nimport BIP32Factory, { type BIP32Interface } from \"bip32\";\nimport { networks, type Network } from \"bitcoinjs-lib\";\n\nimport type { Key, KeyInfo, NetworkName, RawKey, XpubKey } from \"./types.js\";\nimport { isXpubKey } from \"./types.js\";\n\nconst bip32 = BIP32Factory(ecc);\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\nexport function getNetwork(name: NetworkName): Network {\n switch (name) {\n case \"mainnet\":\n return networks.bitcoin;\n case \"testnet\":\n return networks.testnet;\n case \"regtest\":\n return networks.regtest;\n }\n}\n\n// ============================================================================\n// Key Derivation\n// ============================================================================\n\n/**\n * Derive a child public key from an xpub at the given path.\n * @param xpub Extended public key\n * @param change 0 for receive, 1 for change\n * @param index Child index\n * @param network Network for xpub parsing\n * @returns BIP32 node at the derived path\n */\nexport function deriveFromXpub(\n xpub: string,\n change: number,\n index: number,\n network: Network,\n): BIP32Interface {\n const node = bip32.fromBase58(xpub, network);\n return node.derive(change).derive(index);\n}\n\n/**\n * Resolve a Key to its compressed public key (33 bytes).\n * For XpubKey, derives the child key. For RawKey, validates and returns the pubkey.\n */\nexport function resolveCompressedPubkey(\n key: Key,\n network: NetworkName,\n): Buffer {\n if (isXpubKey(key)) {\n const net = getNetwork(network);\n const child = deriveFromXpub(\n key.xpub,\n key.change ?? 0,\n key.index ?? 0,\n net,\n );\n return Buffer.from(child.publicKey);\n } else {\n return parsePublicKey(key.pubkey);\n }\n}\n\n/**\n * Resolve a Key to its x-only public key (32 bytes) for Taproot.\n */\nexport function resolveXOnlyPubkey(key: Key, network: NetworkName): Buffer {\n const compressed = resolveCompressedPubkey(key, network);\n return toXOnly(compressed);\n}\n\n// ============================================================================\n// Public Key Utilities\n// ============================================================================\n\n/**\n * Convert compressed (33 byte) or uncompressed (65 byte) pubkey to x-only (32 byte).\n */\nexport function toXOnly(pubkey: Buffer): Buffer {\n if (pubkey.length === 32) {\n return pubkey; // Already x-only\n }\n if (pubkey.length === 33) {\n return pubkey.subarray(1, 33); // Drop the prefix byte\n }\n if (pubkey.length === 65) {\n return pubkey.subarray(1, 33); // Drop prefix, take x-coordinate\n }\n throw new Error(`Invalid public key length: ${pubkey.length}`);\n}\n\n/**\n * Parse a hex public key string to Buffer, validating format.\n * Accepts compressed (66 hex), x-only (64 hex), or uncompressed (130 hex).\n */\nexport function parsePublicKey(pubkeyHex: string): Buffer {\n const buf = Buffer.from(pubkeyHex, \"hex\");\n\n if (buf.length === 33) {\n // Compressed\n if (buf[0] !== 0x02 && buf[0] !== 0x03) {\n throw new Error(\"Compressed public key must start with 02 or 03\");\n }\n if (!isValidPoint(buf)) {\n throw new Error(\"Invalid public key: not a valid curve point\");\n }\n return buf;\n }\n\n if (buf.length === 32) {\n // X-only - convert to compressed for validation\n const compressed = Buffer.concat([Buffer.from([0x02]), buf]) as Buffer;\n if (!isValidPoint(compressed)) {\n throw new Error(\"Invalid x-only public key: not a valid curve point\");\n }\n return compressed; // Return as compressed\n }\n\n if (buf.length === 65) {\n // Uncompressed\n if (buf[0] !== 0x04) {\n throw new Error(\"Uncompressed public key must start with 04\");\n }\n // Convert to compressed\n const prefix = (buf[64] & 1) === 0 ? 0x02 : 0x03;\n const compressed = Buffer.concat([\n Buffer.from([prefix]),\n buf.subarray(1, 33),\n ]);\n if (!isValidPoint(compressed)) {\n throw new Error(\"Invalid public key: not a valid curve point\");\n }\n return compressed;\n }\n\n throw new Error(\n `Invalid public key length: ${buf.length} bytes (expected 32, 33, or 65)`,\n );\n}\n\n/**\n * Check if a compressed public key is a valid secp256k1 point.\n */\nexport function isValidPoint(pubkey: Buffer): boolean {\n try {\n return ecc.isPoint(pubkey);\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// BIP-388 Key Info\n// ============================================================================\n\n/**\n * Convert an XpubKey to KeyInfo for BIP-388 policy.\n */\nexport function toKeyInfo(key: XpubKey): KeyInfo {\n return {\n fingerprint: key.fingerprint,\n originPath: key.originPath,\n xpub: key.xpub,\n };\n}\n\n/**\n * Try to extract KeyInfo from an array of Keys.\n * Returns null if any key is a RawKey (no xpub info available).\n */\nexport function extractKeyInfos(keys: Key[]): KeyInfo[] | null {\n const infos: KeyInfo[] = [];\n for (const key of keys) {\n if (!isXpubKey(key)) {\n return null; // Can't build policy without xpubs\n }\n infos.push(toKeyInfo(key));\n }\n return infos;\n}\n","import type { Network } from \"bitcoinjs-lib\";\nimport type { WalletPolicy } from \"./bip388.js\";\n\n// ============================================================================\n// Network\n// ============================================================================\n\nexport type NetworkName = \"mainnet\" | \"testnet\" | \"regtest\";\n\n// ============================================================================\n// Key Types\n// ============================================================================\n\n/** Key with xpub - enables BIP-388 policy generation and child derivation */\nexport interface XpubKey {\n /** Master fingerprint (8 hex chars) */\n fingerprint?: string;\n /** Origin path e.g. \"48'/1'/0'/2'\" */\n originPath?: string;\n /** Extended public key (xpub/tpub) */\n xpub: string;\n /** Child index for derivation (default: 0) */\n index?: number;\n /** Change path: 0 = receive, 1 = change (default: 0) */\n change?: 0 | 1;\n}\n\n/** Raw public key - no policy generation, just script building */\nexport interface RawKey {\n /** Compressed (33 bytes / 66 hex) or x-only (32 bytes / 64 hex) */\n pubkey: string;\n}\n\n/** Either xpub-based or raw pubkey */\nexport type Key = XpubKey | RawKey;\n\n/** Type guard for XpubKey */\nexport function isXpubKey(key: Key): key is XpubKey {\n return \"xpub\" in key;\n}\n\n/** Type guard for RawKey */\nexport function isRawKey(key: Key): key is RawKey {\n return \"pubkey\" in key;\n}\n\n// ============================================================================\n// BIP-388 Key Types\n// ============================================================================\n\nexport interface KeyInfo {\n fingerprint?: string;\n originPath?: string;\n xpub: string;\n}\n\n// ============================================================================\n// Script Output Types\n// ============================================================================\n\nexport interface TapLeaf {\n script: Buffer;\n hash: Buffer;\n}\n\nexport interface TaprootOutput {\n /** The P2TR address */\n address: string;\n /** The scriptPubkey for this output */\n scriptPubkey: Buffer;\n /** Internal public key (x-only, 32 bytes) */\n internalPubkey: Buffer;\n /** Merkle root of the tap tree (32 bytes) */\n merkleRoot: Buffer;\n /** Tweak applied to internal key */\n tweak: Buffer;\n /** Tweaked output key (x-only, 32 bytes) */\n outputKey: Buffer;\n}\n\nexport interface SegwitOutput {\n /** The P2WSH address */\n address: string;\n /** The scriptPubkey for this output */\n scriptPubkey: Buffer;\n /** The witness script (redeemScript) */\n witnessScript: Buffer;\n /** SHA256 hash of witness script */\n scriptHash: Buffer;\n}\n","import * as ecc from \"@bitcoinerlab/secp256k1\";\nimport {\n initEccLib,\n payments,\n opcodes,\n script as bscript,\n} from \"bitcoinjs-lib\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nimport type { Key } from \"../../types.js\";\nimport type { TaprootHtlc, TaprootHtlcParams } from \"../types.js\";\nimport type { WalletPolicy } from \"../../bip388.js\";\nimport { isXpubKey } from \"../../types.js\";\nimport {\n getNetwork,\n resolveXOnlyPubkey,\n toKeyInfo,\n deriveFromXpub,\n toXOnly,\n} from \"../../keys.js\";\nimport { bareKey } from \"../../bip388.js\";\nimport { buildTaprootHtlcPolicy } from \"../htlc.js\";\nimport { NUMS } from \"./nums.js\";\nimport {\n tapLeafHash,\n tapBranchHash,\n tapTweak,\n buildControlBlock,\n encodeScriptNumber,\n buildP2TROutput,\n} from \"./script.js\";\n\n// Initialize ecc library for bitcoinjs-lib\ninitEccLib(ecc);\n\n/**\n * Create a Taproot HTLC with two script paths:\n * - Secret path: payee can spend by revealing the preimage\n * - Timeout path: payer can refund after the timelock expires\n *\n * Secret leaf script:\n * ```\n * OP_SHA256 <secretHash> OP_EQUALVERIFY <payeePubkey> OP_CHECKSIG\n * ```\n *\n * Timeout leaf script:\n * ```\n * <timelock> OP_CHECKLOCKTIMEVERIFY OP_DROP <payerPubkey> OP_CHECKSIG\n * ```\n *\n * Uses NUMS as internal key (script-only spend, no key path).\n *\n * @example\n * ```ts\n * const htlc = taprootHtlc({\n * payee: { pubkey: '02abc...' },\n * payer: { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: \"86'/1'/0'\" },\n * secretHash: 'deadbeef...',\n * timelock: 800000,\n * network: 'testnet'\n * });\n *\n * // Fund it\n * console.log(htlc.address);\n *\n * // Spend with preimage\n * const witness = htlc.witnessSecret(signature, preimage);\n * ```\n */\nexport function taprootHtlc<K extends Key>(\n params: TaprootHtlcParams<K>,\n): TaprootHtlc {\n const { payee, payer, secretHash, timelock, network, name } = params;\n\n // Validate secretHash\n if (!secretHash || secretHash.length !== 64) {\n throw new Error(\"secretHash must be 32 bytes (64 hex chars)\");\n }\n if (timelock <= 0) {\n throw new Error(\"timelock must be a positive number\");\n }\n\n // Resolve pubkeys\n const payeeXOnly = resolveXOnlyPubkey(payee, network);\n const payerXOnly = resolveXOnlyPubkey(payer, network);\n const hashBuffer = Buffer.from(secretHash, \"hex\");\n\n // Build leaf scripts\n const secretScript = buildHashLockScript(hashBuffer, payeeXOnly);\n const timeoutScript = buildTimelockScript(timelock, payerXOnly);\n\n // Compute leaf hashes\n const secretLeafHash = tapLeafHash(secretScript);\n const timeoutLeafHash = tapLeafHash(timeoutScript);\n\n // Compute merkle root (2 leaves)\n const merkleRoot = tapBranchHash(secretLeafHash, timeoutLeafHash);\n\n // Use NUMS-derived key as internal key (script-only)\n // We derive /0/0 from NUMS xpub to match what Ledger does with @0/**\n // The derived key is still unspendable (no known private key)\n const net = getNetwork(network);\n const numsXpub = NUMS.xpub(network);\n const derivedNums = deriveFromXpub(numsXpub, 0, 0, net);\n const internalPubkey = toXOnly(Buffer.from(derivedNums.publicKey));\n\n // Compute tweak and output key\n const tweak = tapTweak(internalPubkey, merkleRoot);\n\n // Tweak the internal key\n const tweakedKey = ecc.xOnlyPointAddTweak(internalPubkey, tweak);\n if (!tweakedKey) {\n throw new Error(\"Failed to tweak internal key\");\n }\n const outputKey = Buffer.from(tweakedKey.xOnlyPubkey);\n\n // Build P2TR output\n const scriptPubkey = buildP2TROutput(outputKey);\n\n const address = payments.p2tr({\n pubkey: outputKey,\n network: net,\n }).address!;\n\n // Build control blocks (for 2-leaf tree, each leaf's path is the other leaf's hash)\n const secretControlBlock = buildControlBlock(\n internalPubkey,\n 0xc0 | (tweakedKey.parity ? 1 : 0),\n [timeoutLeafHash], // path to sibling\n );\n\n const timeoutControlBlock = buildControlBlock(\n internalPubkey,\n 0xc0 | (tweakedKey.parity ? 1 : 0),\n [secretLeafHash], // path to sibling\n );\n\n // Build BIP-388 policy if both keys have xpub info\n let policy: WalletPolicy | null = null;\n if (isXpubKey(payee) && isXpubKey(payer)) {\n policy = buildTaprootHtlcPolicy({\n name: name || \"HTLC\",\n secretHash,\n timelock,\n numsKey: bareKey(NUMS.xpub(network)),\n payeeKey: toKeyInfo(payee),\n payerKey: toKeyInfo(payer),\n });\n }\n\n return {\n address,\n scriptPubkey,\n internalPubkey,\n merkleRoot,\n tweak,\n outputKey,\n timelock,\n\n secretLeaf: {\n script: secretScript,\n hash: secretLeafHash,\n },\n\n timeoutLeaf: {\n script: timeoutScript,\n hash: timeoutLeafHash,\n },\n\n controlBlock(leaf: \"secret\" | \"timeout\"): Buffer {\n return leaf === \"secret\" ? secretControlBlock : timeoutControlBlock;\n },\n\n witness: {\n secret(signature: Buffer, preimage: Buffer): Buffer[] {\n // Witness: <signature> <preimage> <script> <control_block>\n return [signature, preimage, secretScript, secretControlBlock];\n },\n timeout(signature: Buffer): Buffer[] {\n // Witness: <signature> <script> <control_block>\n return [signature, timeoutScript, timeoutControlBlock];\n },\n },\n\n policy,\n };\n}\n\n/**\n * Extract the preimage from a spent HTLC witness.\n * @param witness The witness stack from a transaction input\n * @param secretHash Optional hash to validate the preimage against\n * @returns The preimage hex string, or null if not found/invalid\n */\nexport function extractSecret(\n witness: Buffer[],\n secretHash?: string,\n): string | null {\n // Taproot HTLC witness: [signature, preimage, script, control_block]\n if (!witness || witness.length < 4) {\n return null;\n }\n\n const preimage = witness[1];\n if (preimage.length !== 32) {\n return null;\n }\n\n if (secretHash) {\n const computed = Buffer.from(sha256(preimage)).toString(\"hex\");\n if (computed !== secretHash) {\n return null;\n }\n }\n\n return preimage.toString(\"hex\");\n}\n\n/**\n * Build miniscript: and_v(v:sha256(H), pk(K))\n * Compiles to: SIZE <32> EQUALVERIFY SHA256 <H> EQUALVERIFY <K> CHECKSIG\n *\n * The v:sha256(H) wrapper adds SIZE 32 EQUALVERIFY to validate preimage length.\n * This matches the BIP-388 policy template exactly.\n */\nexport function buildHashLockScript(\n hash: Buffer,\n pubkey: Buffer,\n hashOp: number = opcodes.OP_SHA256,\n): Buffer {\n return Buffer.from(\n bscript.compile([\n // v:sha256(H) - verify wrapper adds SIZE check for 32-byte preimage\n opcodes.OP_SIZE,\n bscript.number.encode(32), // Push number 32\n opcodes.OP_EQUALVERIFY,\n // sha256(H)\n hashOp,\n hash,\n opcodes.OP_EQUALVERIFY,\n // pk(K)\n pubkey,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n\n/**\n * Build miniscript: and_v(v:after(N), pk(K))\n * Compiles to: <N> CHECKLOCKTIMEVERIFY VERIFY <K> CHECKSIG\n *\n * The v: wrapper on after(N) adds VERIFY (since CLTV doesn't have a VERIFY variant).\n * This matches the BIP-388 policy template exactly.\n */\nexport function buildTimelockScript(timelock: number, pubkey: Buffer): Buffer {\n return Buffer.from(\n bscript.compile([\n encodeScriptNumber(timelock),\n opcodes.OP_CHECKLOCKTIMEVERIFY,\n opcodes.OP_VERIFY,\n pubkey,\n opcodes.OP_CHECKSIG,\n ]),\n ) as Buffer;\n}\n","import type { NetworkName } from \"../../types.js\";\n\n/**\n * NUMS (Nothing Up My Sleeve) point for script-only Taproot.\n *\n * This is the BIP-341 recommended NUMS point. It has no known discrete log,\n * meaning no one can spend via the key path - only script paths are valid.\n *\n * Public key: lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)\n * This is SHA256(\"TapTweak\")[:32] interpreted as an x-coordinate.\n */\nexport const NUMS = {\n /** Compressed public key (33 bytes as hex) */\n pubkey: \"0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0\",\n\n /** X-only public key (32 bytes as hex) - for taproot internal key */\n xonly: \"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0\",\n\n /** X-only as Buffer */\n get xonlyBuffer(): Buffer {\n return Buffer.from(this.xonly, \"hex\");\n },\n\n /** Compressed as Buffer */\n get pubkeyBuffer(): Buffer {\n return Buffer.from(this.pubkey, \"hex\");\n },\n\n /**\n * Get NUMS xpub for a specific network.\n * Constructed with:\n * - Public key: NUMS point\n * - Chain code: 32 zero bytes\n * - Depth/parent/index: all zeros (acts like master key)\n */\n xpub(network: NetworkName): string {\n switch (network) {\n case \"mainnet\":\n return \"xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6QgnecKFpJFPpdzxKrwoaZoV44qAJewsc4kX9vGaCaBExuvJH57\";\n case \"testnet\":\n case \"regtest\":\n return \"tpubD6NzVbkrYhZ4WLczPJWReQycCJdd6YVWXubbVUFnJ5KgU5MDQrD998ZJLSmaB7GVcCnJSDWprxmrGkJ6SvgQC6QAffVpqSvonXmeizXcrkN\";\n }\n },\n} as const;\n","import * as ecc from \"@bitcoinerlab/secp256k1\";\nimport { crypto, script as bscript, opcodes } from \"bitcoinjs-lib\";\n\n// ============================================================================\n// Taproot Script Hashing\n// ============================================================================\n\nconst LEAF_VERSION = 0xc0;\n\n/**\n * Compute TapLeaf hash for a Tapscript.\n */\nexport function tapLeafHash(script: Buffer): Buffer {\n return Buffer.from(\n crypto.taggedHash(\n \"TapLeaf\",\n Buffer.concat([Buffer.from([LEAF_VERSION]), serializeScript(script)]),\n ),\n );\n}\n\n/**\n * Compute TapBranch hash from two child hashes.\n * Sorts lexicographically as per BIP-341.\n */\nexport function tapBranchHash(left: Buffer, right: Buffer): Buffer {\n const [first, second] =\n Buffer.compare(left, right) <= 0 ? [left, right] : [right, left];\n return Buffer.from(\n crypto.taggedHash(\"TapBranch\", Buffer.concat([first, second])),\n );\n}\n\n/**\n * Compute the taproot tweak for a given internal key and merkle root.\n */\nexport function tapTweak(internalPubkey: Buffer, merkleRoot: Buffer): Buffer {\n return Buffer.from(\n crypto.taggedHash(\"TapTweak\", Buffer.concat([internalPubkey, merkleRoot])),\n );\n}\n\n/**\n * Serialize script with compact size prefix.\n */\nexport function serializeScript(script: Buffer): Buffer {\n const len = varintEncode(script.length);\n return Buffer.concat([len, script]);\n}\n\n// ============================================================================\n// Control Block Construction\n// ============================================================================\n\n/**\n * Build a control block for spending a tapscript leaf.\n * @param internalPubkey X-only internal public key (32 bytes)\n * @param leafVersion Leaf version (usually 0xc0)\n * @param merklePath Array of 32-byte hashes forming the merkle proof\n */\nexport function buildControlBlock(\n internalPubkey: Buffer,\n leafVersion: number,\n merklePath: Buffer[],\n): Buffer {\n const parityByte = leafVersion; // TODO: add parity bit from output key if needed\n return Buffer.concat([\n Buffer.from([parityByte]),\n internalPubkey,\n ...merklePath,\n ]);\n}\n\n// ============================================================================\n// Witness Stack Utilities\n// ============================================================================\n\n/**\n * Convert a witness stack to serialized script witness format.\n */\nexport function witnessStackToScriptWitness(witness: Buffer[]): Buffer {\n const parts: Buffer[] = [varintEncode(witness.length)];\n for (const item of witness) {\n parts.push(varintEncode(item.length));\n parts.push(item);\n }\n return Buffer.concat(parts);\n}\n\n// ============================================================================\n// Varint Encoding\n// ============================================================================\n\nexport function varintEncodingLength(n: number): number {\n return n < 0xfd ? 1 : n <= 0xffff ? 3 : n <= 0xffffffff ? 5 : 9;\n}\n\nexport function varintEncode(n: number): Buffer {\n if (n < 0xfd) {\n const buf = Buffer.allocUnsafe(1);\n buf.writeUInt8(n, 0);\n return buf;\n } else if (n <= 0xffff) {\n const buf = Buffer.allocUnsafe(3);\n buf.writeUInt8(0xfd, 0);\n buf.writeUInt16LE(n, 1);\n return buf;\n } else if (n <= 0xffffffff) {\n const buf = Buffer.allocUnsafe(5);\n buf.writeUInt8(0xfe, 0);\n buf.writeUInt32LE(n, 1);\n return buf;\n } else {\n const buf = Buffer.allocUnsafe(9);\n buf.writeUInt8(0xff, 0);\n buf.writeUInt32LE(n >>> 0, 1);\n buf.writeUInt32LE((n / 0x100000000) | 0, 5);\n return buf;\n }\n}\n\n// ============================================================================\n// Script Number Encoding\n// ============================================================================\n\n/**\n * Encode a number for use in Bitcoin script (minimal encoding).\n */\nexport function encodeScriptNumber(n: number): Buffer {\n return Buffer.from(bscript.number.encode(n)) as Buffer;\n}\n\n// ============================================================================\n// Taproot Output Key Computation\n// ============================================================================\n\n/**\n * Compute tweaked output key for key-only spend (no script tree).\n * Q = P + int(hash_TapTweak(P)) * G\n *\n * @param internalPubkey X-only internal public key (32 bytes)\n * @returns X-only tweaked output key (32 bytes)\n */\nexport function computeKeyOnlyOutputKey(internalPubkey: Buffer): Buffer {\n const tweak = crypto.taggedHash(\"TapTweak\", internalPubkey);\n const result = ecc.xOnlyPointAddTweak(internalPubkey, tweak);\n if (!result) throw new Error(\"Failed to tweak key\");\n return Buffer.from(result.xOnlyPubkey);\n}\n\n/**\n * Compute tweaked output key with script tree.\n * Q = P + int(hash_TapTweak(P || merkle_root)) * G\n *\n * @param internalPubkey X-only internal public key (32 bytes)\n * @param merkleRoot Merkle root of the script tree (32 bytes)\n * @returns X-only tweaked output key (32 bytes)\n */\nexport function computeScriptTreeOutputKey(\n internalPubkey: Buffer,\n merkleRoot: Buffer,\n): Buffer {\n const tweak = crypto.taggedHash(\n \"TapTweak\",\n Buffer.concat([internalPubkey, merkleRoot]),\n );\n const result = ecc.xOnlyPointAddTweak(internalPubkey, tweak);\n if (!result) throw new Error(\"Failed to tweak key\");\n return Buffer.from(result.xOnlyPubkey);\n}\n\n/**\n * Build P2TR scriptPubKey: OP_1 <32-byte-output-key>\n *\n * @param outputKey X-only tweaked output key (32 bytes)\n * @returns scriptPubKey buffer (34 bytes)\n */\nexport function buildP2TROutput(outputKey: Buffer): Buffer {\n return Buffer.concat([\n Buffer.from([0x51, 0x20]), // OP_1, push 32 bytes\n outputKey,\n ]);\n}\n\n/**\n * Build a Tapscript pk() leaf: <x-only-pubkey> OP_CHECKSIG\n *\n * @param xOnlyPubkey X-only public key (32 bytes)\n * @returns Tapscript buffer (34 bytes)\n */\nexport function buildTapscriptPk(xOnlyPubkey: Buffer): Buffer {\n return Buffer.concat([\n Buffer.from([0x20]), // push 32 bytes\n xOnlyPubkey,\n Buffer.from([0xac]), // OP_CHECKSIG\n ]);\n}\n","import * as ecc from \"@bitcoinerlab/secp256k1\";\nimport {\n initEccLib,\n payments,\n opcodes,\n script as bscript,\n} from \"bitcoinjs-lib\";\n\nimport type { Key } from \"../../types.js\";\nimport type { TaprootMultisig, TaprootMultisigParams } from \"../types.js\";\nimport type { WalletPolicy } from \"../../bip388.js\";\nimport { getNetwork, resolveXOnlyPubkey, extractKeyInfos } from \"../../keys.js\";\nimport { bareKey } from \"../../bip388.js\";\nimport { buildTaprootMultisigPolicy } from \"../multisig.js\";\nimport { NUMS } from \"./nums.js\";\nimport {\n tapLeafHash,\n tapTweak,\n buildControlBlock,\n buildP2TROutput,\n} from \"./script.js\";\nimport { encodeScriptNumber } from \"../../scripts/index.js\";\n\n// Initialize ecc library for bitcoinjs-lib\ninitEccLib(ecc);\n\n/**\n * Create a Taproot multisig output using script path spend.\n *\n * Uses multi_a / sortedmulti_a which leverages OP_CHECKSIGADD for\n * efficient k-of-n multisig in Tapscript.\n *\n * Script structure (for 2-of-3):\n * ```\n * <pubkey1> OP_CHECKSIG\n * <pubkey2> OP_CHECKSIGADD\n * <pubkey3> OP_CHECKSIGADD\n * OP_2 OP_NUMEQUAL\n * ```\n *\n * Uses NUMS as internal key (script-only spend, no key path).\n *\n * @example\n * ```ts\n * const multisig = taprootMultisig({\n * threshold: 2,\n * keys: [\n * { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: \"86'/1'/0'\" },\n * { xpub: 'tpub...', fingerprint: 'eeff0011', originPath: \"86'/1'/0'\" },\n * { xpub: 'tpub...', fingerprint: '22334455', originPath: \"86'/1'/0'\" },\n * ],\n * network: 'testnet'\n * });\n *\n * console.log(multisig.address); // tb1p...\n * ```\n */\nexport function taprootMultisig<K extends Key>(\n params: TaprootMultisigParams<K>,\n): TaprootMultisig {\n const { threshold, keys, sorted = true, network, name } = params;\n\n // Validation\n if (threshold <= 0 || !Number.isInteger(threshold)) {\n throw new Error(\"threshold must be a positive integer\");\n }\n if (keys.length === 0) {\n throw new Error(\"At least one key is required\");\n }\n if (threshold > keys.length) {\n throw new Error(\n `threshold (${threshold}) cannot exceed number of keys (${keys.length})`,\n );\n }\n\n // Resolve all pubkeys to x-only (32 bytes)\n const net = getNetwork(network);\n let pubkeys = keys.map((key: Key) => resolveXOnlyPubkey(key, network));\n\n // Keep track of original order for signature matching\n let sortedIndexes: number[] = pubkeys.map((_: Buffer, i: number) => i);\n\n // Sort lexicographically if requested (default)\n if (sorted) {\n // Create array of [pubkey, originalIndex] pairs, sort by pubkey, extract new order\n const indexed = pubkeys.map((pk: Buffer, i: number) => ({ pk, i }));\n indexed.sort((a: { pk: Buffer; i: number }, b: { pk: Buffer; i: number }) =>\n Buffer.compare(a.pk, b.pk),\n );\n pubkeys = indexed.map((x: { pk: Buffer; i: number }) => x.pk);\n sortedIndexes = indexed.map((x: { pk: Buffer; i: number }) => x.i);\n }\n\n // Build the multi_a script using OP_CHECKSIGADD\n // <pk1> OP_CHECKSIG <pk2> OP_CHECKSIGADD ... <pkN> OP_CHECKSIGADD <M> OP_NUMEQUAL\n const scriptParts: (Buffer | number)[] = [];\n\n // First key uses OP_CHECKSIG\n scriptParts.push(pubkeys[0]);\n scriptParts.push(opcodes.OP_CHECKSIG);\n\n // Remaining keys use OP_CHECKSIGADD\n for (let i = 1; i < pubkeys.length; i++) {\n scriptParts.push(pubkeys[i]);\n scriptParts.push(opcodes.OP_CHECKSIGADD);\n }\n\n // Final threshold check\n scriptParts.push(encodeScriptNumber(threshold));\n scriptParts.push(opcodes.OP_NUMEQUAL);\n\n const multisigScript = Buffer.from(bscript.compile(scriptParts)) as Buffer;\n\n // Compute leaf hash (single leaf tree)\n const leafHash = tapLeafHash(multisigScript);\n\n // Use NUMS as internal key (script-only, no key path spend)\n const internalPubkey = NUMS.xonlyBuffer;\n\n // Merkle root is just the leaf hash for a single-leaf tree\n const merkleRoot = leafHash;\n\n // Compute tweak and output key\n const tweak = tapTweak(internalPubkey, merkleRoot);\n\n // Tweak the internal key\n const tweakedKey = ecc.xOnlyPointAddTweak(internalPubkey, tweak);\n if (!tweakedKey) {\n throw new Error(\"Failed to tweak internal key\");\n }\n const outputKey = Buffer.from(tweakedKey.xOnlyPubkey);\n\n // Build P2TR output\n const scriptPubkey = buildP2TROutput(outputKey);\n\n const address = payments.p2tr({\n pubkey: outputKey,\n network: net,\n }).address!;\n\n // Build control block (single leaf, empty merkle path)\n const controlBlock = buildControlBlock(\n internalPubkey,\n 0xc0 | (tweakedKey.parity ? 1 : 0),\n [], // No sibling for single-leaf tree\n );\n\n // Build BIP-388 policy if all keys have xpub info\n let policy: WalletPolicy | null = null;\n const keyInfos = extractKeyInfos(keys);\n if (keyInfos) {\n // For BIP-388, we need NUMS as @0 (internal key) and actual keys as @1, @2, ...\n policy = buildTaprootMultisigPolicy({\n name: name || `${threshold}-of-${keys.length} Taproot Multisig`,\n threshold,\n keys: [bareKey(NUMS.xpub(network)), ...keyInfos],\n sorted,\n });\n }\n\n return {\n address,\n scriptPubkey,\n internalPubkey,\n merkleRoot,\n tweak,\n outputKey,\n\n scriptLeaf: {\n script: multisigScript,\n hash: leafHash,\n },\n\n controlBlock,\n\n policy,\n\n /**\n * Build witness stack for script path spend.\n *\n * For multi_a, signatures must be provided in the same order as keys appear\n * in the script. Use empty Buffer for keys that don't sign.\n *\n * @param signatures Array of signatures (length must equal number of keys)\n * Use Buffer.alloc(0) for non-signing keys\n * @returns Witness stack: [sig1, sig2, ..., sigN, script, control_block]\n */\n witness(signatures: Buffer[]): Buffer[] {\n if (signatures.length !== keys.length) {\n throw new Error(\n `Expected ${keys.length} signature slots (use empty Buffer for non-signers), got ${signatures.length}`,\n );\n }\n\n // Count actual signatures\n const sigCount = signatures.filter((s) => s.length > 0).length;\n if (sigCount !== threshold) {\n throw new Error(`Expected ${threshold} signatures, got ${sigCount}`);\n }\n\n // Reorder signatures to match sorted key order\n const orderedSigs = sorted\n ? sortedIndexes.map((origIdx) => signatures[origIdx])\n : signatures;\n\n // Taproot witness: signatures in reverse order, then script, then control block\n // (signatures are popped from stack, so last sig in witness is checked first)\n return [...orderedSigs.reverse(), multisigScript, controlBlock];\n },\n };\n}\n","import { crypto, script as bscript, opcodes, payments } from \"bitcoinjs-lib\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nimport type { Key } from \"../../types.js\";\nimport type { SegwitHtlc, SegwitHtlcParams } from \"../types.js\";\n\nimport type { WalletPolicy } from \"../../bip388.js\";\nimport { isXpubKey } from \"../../types.js\";\nimport { getNetwork, resolveCompressedPubkey, toKeyInfo } from \"../../keys.js\";\nimport { buildSegwitHtlcPolicy } from \"../htlc.js\";\n\n/**\n * Create a SegWit (P2WSH) HTLC with SHA256 hashlock.\n *\n * Miniscript policy: or_d(and_v(v:sha256(H), pk(@0)), and_v(v:pk(@1), after(N)))\n *\n * Compiles to:\n * ```\n * SIZE <32> EQUALVERIFY SHA256 <H> EQUALVERIFY <payeePubkey> CHECKSIG\n * IFDUP NOTIF\n * <payerPubkey> CHECKSIGVERIFY <timelock> CHECKLOCKTIMEVERIFY\n * ENDIF\n * ```\n *\n * - Payee: reveals preimage, signature satisfies first branch (returns true, skips NOTIF)\n * - Payer: provides signature + timelock satisfied (first branch fails, enters NOTIF)\n *\n * @example\n * ```ts\n * const htlc = segwitHtlc({\n * payee: { pubkey: '02abc...' },\n * payer: { pubkey: '03def...' },\n * secretHash: 'deadbeef...', // sha256(preimage)\n * timelock: 800000,\n * network: 'testnet'\n * });\n *\n * console.log(htlc.address); // bc1q...\n * ```\n */\nexport function segwitHtlc<K extends Key>(\n params: SegwitHtlcParams<K>,\n): SegwitHtlc {\n const { payee, payer, secretHash, timelock, network, name } = params;\n\n // Validate secretHash (sha256, 32 bytes)\n if (!secretHash || secretHash.length !== 64) {\n throw new Error(\"secretHash must be 32 bytes (64 hex chars)\");\n }\n if (timelock <= 0) {\n throw new Error(\"timelock must be a positive number\");\n }\n\n // Resolve compressed pubkeys (SegWit requires compressed)\n const payeePubkey = resolveCompressedPubkey(payee, network);\n const payerPubkey = resolveCompressedPubkey(payer, network);\n const secretHashBuffer = Buffer.from(secretHash, \"hex\");\n\n // Build the HTLC script matching miniscript:\n // or_i(and_v(v:sha256(H), pk(@0)), and_v(v:pk(@1), after(N)))\n //\n // or_i compiles to: IF [X] ELSE [Z] ENDIF\n // and_v(X,Y) compiles to: [X] [Y] (concatenation)\n // v:sha256(H) = SIZE <0x20> EQUALVERIFY SHA256 <h> EQUALVERIFY (EQUAL becomes EQUALVERIFY)\n // pk(@0) = <K0> CHECKSIG\n // v:pk(@1) = <K1> CHECKSIGVERIFY\n // after(N) = <N> CHECKLOCKTIMEVERIFY\n //\n // Full script:\n // IF SIZE 32 EQUALVERIFY SHA256 <h> EQUALVERIFY <K0> CHECKSIG\n // ELSE <K1> CHECKSIGVERIFY <N> CHECKLOCKTIMEVERIFY ENDIF\n const witnessScript = Buffer.from(\n bscript.compile([\n opcodes.OP_IF,\n // and_v(v:sha256(H), pk(@0)) - secret path\n opcodes.OP_SIZE,\n bscript.number.encode(32),\n opcodes.OP_EQUALVERIFY,\n opcodes.OP_SHA256,\n secretHashBuffer,\n opcodes.OP_EQUALVERIFY,\n payeePubkey,\n opcodes.OP_CHECKSIG,\n opcodes.OP_ELSE,\n // and_v(v:pk(@1), after(N)) - timeout path\n payerPubkey,\n opcodes.OP_CHECKSIGVERIFY,\n bscript.number.encode(timelock),\n opcodes.OP_CHECKLOCKTIMEVERIFY,\n opcodes.OP_ENDIF,\n ]),\n ) as Buffer;\n\n // Create P2WSH output\n const net = getNetwork(network);\n const scriptHash = sha256(witnessScript);\n\n const p2wsh = payments.p2wsh({\n redeem: { output: witnessScript, network: net },\n network: net,\n });\n\n if (!p2wsh.address || !p2wsh.output) {\n throw new Error(\"Failed to create P2WSH output\");\n }\n\n // Build BIP-388 policy if both keys have xpub info\n let policy: WalletPolicy | null = null;\n if (isXpubKey(payee) && isXpubKey(payer)) {\n policy = buildSegwitHtlcPolicy({\n name: name || \"HTLC\",\n secretHash,\n timelock,\n payeeKey: toKeyInfo(payee),\n payerKey: toKeyInfo(payer),\n });\n }\n\n return {\n address: p2wsh.address,\n scriptPubkey: Buffer.from(p2wsh.output),\n witnessScript,\n scriptHash: Buffer.from(scriptHash),\n timelock,\n\n witness: {\n secret(signature: Buffer, preimage: Buffer): Buffer[] {\n // or_i satisfaction for first branch: sat(X) 1\n // Witness stack (bottom to top): <sig> <preimage> <1> <witnessScript>\n // The 1 causes IF to take the first (secret) branch\n return [signature, preimage, Buffer.from([0x01]), witnessScript];\n },\n timeout(signature: Buffer): Buffer[] {\n // or_i satisfaction for second branch: sat(Z) 0\n // Witness stack (bottom to top): <sig> <0/empty> <witnessScript>\n // The 0/empty causes IF to take the ELSE (timeout) branch\n return [signature, Buffer.alloc(0), witnessScript];\n },\n },\n\n policy,\n };\n}\n\n/**\n * Extract the preimage from a spent SegWit HTLC witness.\n * @param witness The witness stack from a transaction input\n * @param secretHash Optional sha256 hash to validate the preimage against\n * @returns The preimage hex string, or null if not found/invalid\n */\nexport function extractSecret(\n witness: Buffer[],\n secretHash?: string,\n): string | null {\n // SegWit HTLC witness for secret path: [signature, preimage, OP_TRUE, witnessScript]\n if (!witness || witness.length < 4) {\n return null;\n }\n\n const preimage = witness[1];\n\n // Preimage should be 32 bytes\n if (preimage.length !== 32) {\n return null;\n }\n\n if (secretHash) {\n const computed = Buffer.from(sha256(preimage)).toString(\"hex\");\n if (computed !== secretHash) {\n return null;\n }\n }\n\n return preimage.toString(\"hex\");\n}\n","import { payments } from \"bitcoinjs-lib\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nimport type { Key } from \"../../types.js\";\nimport type { MultisigParams, SegwitMultisig } from \"../types.js\";\nimport type { WalletPolicy } from \"../../bip388.js\";\nimport {\n getNetwork,\n resolveCompressedPubkey,\n extractKeyInfos,\n} from \"../../keys.js\";\nimport { buildSegwitMultisigPolicy } from \"../multisig.js\";\nimport { multiScript } from \"../../scripts/index.js\";\n\n/**\n * Create a SegWit (P2WSH) multisig output.\n *\n * Script structure (for sorted=true, which is default):\n * ```\n * OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG\n * ```\n *\n * Keys are sorted lexicographically when sorted=true (recommended for\n * deterministic addresses regardless of key order in params).\n *\n * @example\n * ```ts\n * const multisig = segwitMultisig({\n * threshold: 2,\n * keys: [\n * { xpub: 'tpub...', fingerprint: 'aabbccdd', originPath: \"48'/1'/0'/2'\" },\n * { xpub: 'tpub...', fingerprint: 'eeff0011', originPath: \"48'/1'/0'/2'\" },\n * { xpub: 'tpub...', fingerprint: '22334455', originPath: \"48'/1'/0'/2'\" },\n * ],\n * network: 'testnet'\n * });\n *\n * console.log(multisig.address); // tb1q...\n * ```\n */\nexport function segwitMultisig<K extends Key>(\n params: MultisigParams<K>,\n): SegwitMultisig {\n const { threshold, keys, sorted = true, network, name } = params;\n\n // Validation\n if (threshold <= 0 || !Number.isInteger(threshold)) {\n throw new Error(\"threshold must be a positive integer\");\n }\n if (keys.length === 0) {\n throw new Error(\"At least one key is required\");\n }\n if (threshold > keys.length) {\n throw new Error(\n `threshold (${threshold}) cannot exceed number of keys (${keys.length})`,\n );\n }\n if (keys.length > 20) {\n throw new Error(\"SegWit multisig is limited to 20 keys\");\n }\n\n // Resolve all pubkeys\n const net = getNetwork(network);\n const pubkeys = keys.map((key: Key) => resolveCompressedPubkey(key, network));\n\n // Build the multisig script using the script builder\n // multiScript handles sorting internally when sorted=true\n const witnessScript = multiScript(threshold, pubkeys, sorted);\n\n // Create P2WSH output\n const scriptHash = sha256(witnessScript);\n\n const p2wsh = payments.p2wsh({\n redeem: { output: witnessScript, network: net },\n network: net,\n });\n\n if (!p2wsh.address || !p2wsh.output) {\n throw new Error(\"Failed to create P2WSH output\");\n }\n\n // Build BIP-388 policy if all keys have xpub info\n let policy: WalletPolicy | null = null;\n const keyInfos = extractKeyInfos(keys);\n if (keyInfos) {\n policy = buildSegwitMultisigPolicy({\n name: name || `${threshold}-of-${keys.length} Multisig`,\n threshold,\n keys: keyInfos,\n sorted,\n });\n }\n\n return {\n address: p2wsh.address,\n scriptPubkey: Buffer.from(p2wsh.output),\n witnessScript,\n scriptHash: Buffer.from(scriptHash),\n policy,\n\n /**\n * Build witness stack for spending.\n * @param signatures Array of signatures (must have exactly `threshold` signatures)\n * @returns Witness stack: [OP_0, sig1, sig2, ..., witnessScript]\n */\n witness(signatures: Buffer[]): Buffer[] {\n if (signatures.length !== threshold) {\n throw new Error(\n `Expected ${threshold} signatures, got ${signatures.length}`,\n );\n }\n // OP_CHECKMULTISIG has an off-by-one bug requiring an extra OP_0\n return [Buffer.alloc(0), ...signatures, witnessScript];\n },\n };\n}\n"],"mappings":"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","names":["extractSecret","validateHash","validateTimelock","bscript","import_bitcoinjs_lib","bscript","import_bitcoinjs_lib","bscript","pk","import_bitcoinjs_lib","bscript","import_bitcoinjs_lib","bscript","import_bitcoinjs_lib","BIP32Factory","ecc","import_bitcoinjs_lib","ecc","import_bitcoinjs_lib","encodeScriptNumber","bscript","ecc","bscript","encodeScriptNumber","ecc","import_bitcoinjs_lib","ecc","pk","bscript","import_bitcoinjs_lib","import_sha2","bscript","extractSecret","import_bitcoinjs_lib","import_sha2"]}