@babylonlabs-io/ts-sdk 0.51.1 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ApplicationRegistry.abi-CLaa6E99.cjs +2 -0
- package/dist/ApplicationRegistry.abi-CLaa6E99.cjs.map +1 -0
- package/dist/{ApplicationRegistry.abi-Dn2qk6JG.js → ApplicationRegistry.abi-w5prf7Ig.js} +14 -1
- package/dist/ApplicationRegistry.abi-w5prf7Ig.js.map +1 -0
- package/dist/PayoutManager-1GWmbvI9.cjs +2 -0
- package/dist/PayoutManager-1GWmbvI9.cjs.map +1 -0
- package/dist/{PayoutManager-D26nGR-e.js → PayoutManager-Ddo9_Ozc.js} +34 -32
- package/dist/PayoutManager-Ddo9_Ozc.js.map +1 -0
- package/dist/{PeginManager-COxRVrxa.js → PeginManager-CTU0wgkJ.js} +37 -34
- package/dist/PeginManager-CTU0wgkJ.js.map +1 -0
- package/dist/PeginManager-De-eHl3v.cjs +2 -0
- package/dist/PeginManager-De-eHl3v.cjs.map +1 -0
- package/dist/buildAndBroadcastRefund-BnD2qUDW.cjs +2 -0
- package/dist/buildAndBroadcastRefund-BnD2qUDW.cjs.map +1 -0
- package/dist/{buildAndBroadcastRefund-Bmz9WJuN.js → buildAndBroadcastRefund-DjS9nf87.js} +221 -209
- package/dist/buildAndBroadcastRefund-DjS9nf87.js.map +1 -0
- package/dist/{challengeAssert-HNbugpqL.cjs → challengeAssert-DLQfNcfU.cjs} +2 -2
- package/dist/{challengeAssert-HNbugpqL.cjs.map → challengeAssert-DLQfNcfU.cjs.map} +1 -1
- package/dist/{challengeAssert-csvYXBJB.js → challengeAssert-DvdbpEDY.js} +2 -2
- package/dist/{challengeAssert-csvYXBJB.js.map → challengeAssert-DvdbpEDY.js.map} +1 -1
- package/dist/constants-BhclpREj.js +19 -0
- package/dist/constants-BhclpREj.js.map +1 -0
- package/dist/constants-CvbARMl-.cjs +2 -0
- package/dist/constants-CvbARMl-.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +193 -190
- package/dist/index.js.map +1 -1
- package/dist/{mempoolApi-Dc1KSVNI.js → mempoolApi-CB7bHuwi.js} +106 -101
- package/dist/mempoolApi-CB7bHuwi.js.map +1 -0
- package/dist/mempoolApi-DqJByvqR.cjs +2 -0
- package/dist/mempoolApi-DqJByvqR.cjs.map +1 -0
- package/dist/noPayout-8dDKwi6n.cjs +2 -0
- package/dist/noPayout-8dDKwi6n.cjs.map +1 -0
- package/dist/{noPayout-C1WCsqfd.js → noPayout-tZFoNun3.js} +12 -10
- package/dist/noPayout-tZFoNun3.js.map +1 -0
- package/dist/{peginInput-BPRB9tUi.js → peginInput-BKD_b3gq.js} +8 -7
- package/dist/peginInput-BKD_b3gq.js.map +1 -0
- package/dist/peginInput-CAiiDZeO.cjs +2 -0
- package/dist/peginInput-CAiiDZeO.cjs.map +1 -0
- package/dist/primeVpAuth-CF4cH5_e.cjs +2 -0
- package/dist/primeVpAuth-CF4cH5_e.cjs.map +1 -0
- package/dist/{primeVpAuth-DxMuWQCi.js → primeVpAuth-l-5x_2UV.js} +91 -85
- package/dist/{primeVpAuth-yTddDmGy.cjs.map → primeVpAuth-l-5x_2UV.js.map} +1 -1
- package/dist/tbv/core/clients/eth/protocol-params-reader.d.ts.map +1 -1
- package/dist/tbv/core/clients/eth/protocol-params-validation.d.ts.map +1 -1
- package/dist/tbv/core/clients/eth/types.d.ts +8 -0
- package/dist/tbv/core/clients/eth/types.d.ts.map +1 -1
- package/dist/tbv/core/clients/index.cjs +1 -1
- package/dist/tbv/core/clients/index.js +2 -2
- package/dist/tbv/core/contracts/abis/ProtocolParams.abi.d.ts +10 -0
- package/dist/tbv/core/contracts/abis/ProtocolParams.abi.d.ts.map +1 -1
- package/dist/tbv/core/contracts/index.cjs +1 -1
- package/dist/tbv/core/contracts/index.js +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +191 -188
- package/dist/tbv/core/index.js.map +1 -1
- package/dist/tbv/core/managers/PayoutManager.d.ts +6 -0
- package/dist/tbv/core/managers/PayoutManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/PeginManager.d.ts +7 -0
- package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/index.cjs +1 -1
- package/dist/tbv/core/managers/index.js +2 -2
- package/dist/tbv/core/primitives/__tests__/vaultCoreVersion.test.d.ts +8 -0
- package/dist/tbv/core/primitives/__tests__/vaultCoreVersion.test.d.ts.map +1 -0
- package/dist/tbv/core/primitives/index.cjs +1 -1
- package/dist/tbv/core/primitives/index.d.ts +2 -1
- package/dist/tbv/core/primitives/index.d.ts.map +1 -1
- package/dist/tbv/core/primitives/index.js +39 -36
- package/dist/tbv/core/primitives/index.js.map +1 -1
- package/dist/tbv/core/primitives/psbt/assertWasmPeginSizing.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/payout.d.ts +6 -0
- package/dist/tbv/core/primitives/psbt/payout.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/pegin.d.ts +7 -0
- package/dist/tbv/core/primitives/psbt/pegin.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/peginInput.d.ts +6 -0
- package/dist/tbv/core/primitives/psbt/peginInput.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/refund.d.ts.map +1 -1
- package/dist/tbv/core/primitives/scripts/payout.d.ts +6 -0
- package/dist/tbv/core/primitives/scripts/payout.d.ts.map +1 -1
- package/dist/tbv/core/primitives/vaultCoreVersion.d.ts +26 -0
- package/dist/tbv/core/primitives/vaultCoreVersion.d.ts.map +1 -0
- package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts +7 -0
- package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/signDepositorGraph.d.ts +6 -0
- package/dist/tbv/core/services/deposit/signDepositorGraph.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/verifyRegisteredVaultVersions.d.ts +8 -0
- package/dist/tbv/core/services/deposit/verifyRegisteredVaultVersions.d.ts.map +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +2 -2
- package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts +6 -0
- package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts.map +1 -1
- package/dist/tbv/core/vault-secrets/__tests__/expand.test.d.ts +5 -2
- package/dist/tbv/core/vault-secrets/__tests__/expand.test.d.ts.map +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +191 -188
- package/dist/tbv/index.js.map +1 -1
- package/dist/{verifyScriptPathSchnorrSignature-CeZp6tMw.js → verifyScriptPathSchnorrSignature-DpWZx5J0.js} +67 -61
- package/dist/verifyScriptPathSchnorrSignature-DpWZx5J0.js.map +1 -0
- package/dist/verifyScriptPathSchnorrSignature-a4Us7D3e.cjs +2 -0
- package/dist/verifyScriptPathSchnorrSignature-a4Us7D3e.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/ApplicationRegistry.abi-BAPhJch3.cjs +0 -2
- package/dist/ApplicationRegistry.abi-BAPhJch3.cjs.map +0 -1
- package/dist/ApplicationRegistry.abi-Dn2qk6JG.js.map +0 -1
- package/dist/PayoutManager-BZVEyi10.cjs +0 -2
- package/dist/PayoutManager-BZVEyi10.cjs.map +0 -1
- package/dist/PayoutManager-D26nGR-e.js.map +0 -1
- package/dist/PeginManager-BvxfSwsr.cjs +0 -2
- package/dist/PeginManager-BvxfSwsr.cjs.map +0 -1
- package/dist/PeginManager-COxRVrxa.js.map +0 -1
- package/dist/buildAndBroadcastRefund-Bmz9WJuN.js.map +0 -1
- package/dist/buildAndBroadcastRefund-ob1n2iB3.cjs +0 -2
- package/dist/buildAndBroadcastRefund-ob1n2iB3.cjs.map +0 -1
- package/dist/constants-CSG2XeD8.cjs +0 -2
- package/dist/constants-CSG2XeD8.cjs.map +0 -1
- package/dist/constants-Cd_fN8VT.js +0 -12
- package/dist/constants-Cd_fN8VT.js.map +0 -1
- package/dist/mempoolApi-Dc1KSVNI.js.map +0 -1
- package/dist/mempoolApi-NMiYQAXI.cjs +0 -2
- package/dist/mempoolApi-NMiYQAXI.cjs.map +0 -1
- package/dist/noPayout-C1WCsqfd.js.map +0 -1
- package/dist/noPayout-lyIRiUyG.cjs +0 -2
- package/dist/noPayout-lyIRiUyG.cjs.map +0 -1
- package/dist/peginInput-BPRB9tUi.js.map +0 -1
- package/dist/peginInput-DH6X4ITS.cjs +0 -2
- package/dist/peginInput-DH6X4ITS.cjs.map +0 -1
- package/dist/primeVpAuth-DxMuWQCi.js.map +0 -1
- package/dist/primeVpAuth-yTddDmGy.cjs +0 -2
- package/dist/verifyScriptPathSchnorrSignature-CeZp6tMw.js.map +0 -1
- package/dist/verifyScriptPathSchnorrSignature-Cl7tu77P.cjs +0 -2
- package/dist/verifyScriptPathSchnorrSignature-Cl7tu77P.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyScriptPathSchnorrSignature-a4Us7D3e.cjs","sources":["../src/tbv/core/primitives/psbt/assertWasmPeginSizing.ts","../src/tbv/core/primitives/psbt/pegin.ts","../src/tbv/core/primitives/scripts/payout.ts","../src/tbv/core/primitives/psbt/payout.ts","../src/tbv/core/primitives/psbt/assertPsbtUnsignedTxMatches.ts","../src/tbv/core/primitives/psbt/verifyScriptPathSchnorrSignature.ts"],"sourcesContent":["/**\n * Cross-check the values WASM returns from `createPrePeginTransaction`\n * against independently-known expectations before they feed a signed\n * Bitcoin transaction or the on-chain PegIn registration.\n *\n * CLAUDE.md critical path #1: the Rust/WASM layer computes\n * `htlcValue = peginAmount + depositorClaimValue + minPeginFee` internally\n * and JS receives the outputs with no runtime validation. A doctored or\n * buggy binary that returns a different `peginAmount`, an out-of-formula\n * `htlcValue`, or a wrong `depositorClaimValue` would otherwise be committed\n * verbatim — taxing the depositor or starving the downstream tx graph of fees.\n *\n * @module primitives/psbt/assertWasmPeginSizing\n */\n\nimport {\n computeMinClaimValue,\n type PrePeginResult,\n} from \"@babylonlabs-io/babylon-tbv-rust-wasm\";\n\nimport { MAX_REASONABLE_PEGIN_VBYTES } from \"../../utils/fee/constants\";\nimport type { ParsedOutput } from \"../../utils/transaction/fundPeginTransaction\";\n\nimport type { PrePeginParams } from \"./pegin\";\n\n/**\n * Assert the WASM Pre-PegIn sizing result is internally consistent and\n * matches what the caller requested.\n *\n * The strong checks are pure-JS and fully independent of the WASM binary:\n * the per-HTLC `peginAmount` must equal the requested amount, array lengths\n * must match, and every value must be positive. The implied PegIn fee\n * (`htlcValue - peginAmount - depositorClaimValue`) is bounded by\n * plausibility rather than recomputed exactly, because JS↔Rust vbyte parity\n * is not a cross-stack guarantee (see {@link MAX_REASONABLE_PEGIN_VBYTES}).\n * The `depositorClaimValue` cross-check against `computeMinClaimValue` is a\n * WASM-vs-WASM consistency check (a different entry point), not an\n * independent one.\n *\n * @param result - The result returned by `createPrePeginTransaction`.\n * @param params - The parameters that were passed to build it.\n * @throws If any value is missing, non-positive, mismatched against the\n * request, or outside the protocol formula / plausibility bounds.\n */\nexport async function assertWasmPeginSizing(\n result: PrePeginResult,\n params: PrePeginParams,\n): Promise<void> {\n const expectedCount = params.pegInAmounts.length;\n\n // Count: every parallel array must carry exactly one entry per requested\n // deposit, otherwise the per-HTLC indexing downstream is meaningless.\n if (result.htlcValues.length !== expectedCount) {\n throw new Error(\n `WASM Pre-PegIn returned ${result.htlcValues.length} HTLC value(s), ` +\n `expected ${expectedCount} (one per requested deposit).`,\n );\n }\n if (\n result.peginAmounts.length !== expectedCount ||\n result.htlcScriptPubKeys.length !== expectedCount ||\n result.htlcAddresses.length !== expectedCount\n ) {\n throw new Error(\n `WASM Pre-PegIn returned mismatched array lengths ` +\n `(htlcValues=${result.htlcValues.length}, ` +\n `peginAmounts=${result.peginAmounts.length}, ` +\n `htlcScriptPubKeys=${result.htlcScriptPubKeys.length}, ` +\n `htlcAddresses=${result.htlcAddresses.length}); ` +\n `expected ${expectedCount} each.`,\n );\n }\n\n // depositorClaimValue: positivity + WASM-vs-WASM consistency. Sized by the\n // tx-graph `feeRate` (see PrePeginParams.feeRate), so the standalone\n // `computeMinClaimValue` must reproduce the constructor's internal value.\n if (result.depositorClaimValue <= 0n) {\n throw new Error(\n `WASM Pre-PegIn returned non-positive depositorClaimValue ` +\n `${result.depositorClaimValue}; expected > 0.`,\n );\n }\n const expectedClaimValue = await computeMinClaimValue(\n // Must price the same graph version the builder constructed.\n params.vaultCoreVersion,\n params.numLocalChallengers,\n params.universalChallengerPubkeys.length,\n params.councilQuorum,\n params.councilSize,\n params.feeRate,\n );\n if (result.depositorClaimValue !== expectedClaimValue) {\n throw new Error(\n `WASM Pre-PegIn depositorClaimValue ${result.depositorClaimValue} does ` +\n `not match the independently computed minimum claim value ` +\n `${expectedClaimValue} (vaultCoreVersion=${params.vaultCoreVersion}, ` +\n `numLocalChallengers=${params.numLocalChallengers}, ` +\n `numUniversalChallengers=${params.universalChallengerPubkeys.length}, ` +\n `councilQuorum=${params.councilQuorum}, councilSize=${params.councilSize}, ` +\n `feeRate=${params.feeRate}).`,\n );\n }\n\n const maxImpliedFee = params.minPeginFeeRate * MAX_REASONABLE_PEGIN_VBYTES;\n\n for (let i = 0; i < expectedCount; i++) {\n const requested = params.pegInAmounts[i];\n const peginAmount = result.peginAmounts[i];\n const htlcValue = result.htlcValues[i];\n\n // Amount echo (strongest, fully independent): the recorded pegin amount\n // must equal exactly what the caller requested. A mismatch is the\n // WASM-tax attack — the contract would record a doctored amount while the\n // depositor's wallet funds the original, and the difference is a\n // WASM-controlled tax.\n if (peginAmount !== requested) {\n throw new Error(\n `WASM Pre-PegIn peginAmount[${i}] ${peginAmount} does not match the ` +\n `requested amount ${requested}; refusing to build a tx whose ` +\n `recorded amount differs from the depositor's request.`,\n );\n }\n if (peginAmount <= 0n) {\n throw new Error(\n `WASM Pre-PegIn peginAmount[${i}] is non-positive (${peginAmount}); ` +\n `expected > 0.`,\n );\n }\n if (htlcValue <= 0n) {\n throw new Error(\n `WASM Pre-PegIn htlcValue[${i}] is non-positive (${htlcValue}); ` +\n `expected > 0.`,\n );\n }\n\n // Formula: htlcValue = peginAmount + depositorClaimValue + minPeginFee.\n // The implied fee must be strictly positive (the HTLC must reserve a real\n // PegIn fee) and within the plausibility bound.\n const impliedFee = htlcValue - peginAmount - result.depositorClaimValue;\n if (impliedFee <= 0n) {\n throw new Error(\n `WASM Pre-PegIn htlcValue[${i}] ${htlcValue} does not strictly cover ` +\n `peginAmount ${peginAmount} + depositorClaimValue ` +\n `${result.depositorClaimValue} + a PegIn fee (implied fee ` +\n `${impliedFee}).`,\n );\n }\n if (impliedFee > maxImpliedFee) {\n throw new Error(\n `WASM Pre-PegIn implied PegIn fee for HTLC[${i}] (${impliedFee} sat) ` +\n `exceeds the plausibility cap ${maxImpliedFee} sat ` +\n `(minPeginFeeRate=${params.minPeginFeeRate} × ` +\n `${MAX_REASONABLE_PEGIN_VBYTES} vbytes); htlcValue ${htlcValue} ` +\n `appears grossly inflated.`,\n );\n }\n }\n}\n\n/**\n * Bind the validated metadata to the bytes that actually get funded and\n * signed.\n *\n * `assertWasmPeginSizing` proves the WASM *metadata* (`htlcValues`,\n * `htlcScriptPubKeys`) matches the request and the protocol formula — but the\n * transaction the depositor funds and signs is `result.txHex`. If the encoded\n * tx carried a different HTLC output value or script than the metadata, the\n * depositor would fund a transaction whose real outputs differ from the values\n * that were cross-checked. This closes that final link: the encoded HTLC\n * outputs must equal the validated metadata.\n *\n * The WASM lays out HTLC outputs first (vouts `0..N-1`), then the optional\n * auth-anchor OP_RETURN, then the CPFP anchor — so we only compare the first\n * `htlcValues.length` outputs.\n *\n * @param outputs - Outputs parsed from the unfunded Pre-PegIn tx hex.\n * @param htlcValues - The (already value-validated) per-HTLC values.\n * @param htlcScriptPubKeys - The per-HTLC scriptPubKeys (hex).\n * @throws If the encoded outputs are too few, or any HTLC output's value or\n * scriptPubKey disagrees with the validated metadata.\n */\nexport function assertEncodedHtlcOutputsMatch(\n outputs: readonly ParsedOutput[],\n htlcValues: readonly bigint[],\n htlcScriptPubKeys: readonly string[],\n): void {\n if (outputs.length < htlcValues.length) {\n throw new Error(\n `Encoded Pre-PegIn tx has ${outputs.length} output(s), fewer than the ` +\n `${htlcValues.length} HTLC output(s) the cross-check validated.`,\n );\n }\n\n for (let i = 0; i < htlcValues.length; i++) {\n const encodedValue = BigInt(outputs[i].value);\n if (encodedValue !== htlcValues[i]) {\n throw new Error(\n `Encoded Pre-PegIn HTLC output[${i}] value ${encodedValue} does not ` +\n `match the cross-checked htlcValue ${htlcValues[i]}; the funded/signed ` +\n `tx would not pay the validated amount.`,\n );\n }\n\n const encodedScript = outputs[i].script.toString(\"hex\").toLowerCase();\n const expectedScript = htlcScriptPubKeys[i].toLowerCase();\n if (encodedScript !== expectedScript) {\n throw new Error(\n `Encoded Pre-PegIn HTLC output[${i}] scriptPubKey ${encodedScript} does ` +\n `not match the cross-checked htlcScriptPubKey ${expectedScript}.`,\n );\n }\n }\n}\n","/**\n * Pre-PegIn PSBT Builder Primitive\n *\n * This module provides pure functions for building unfunded Pre-PegIn transactions\n * and deriving PegIn transactions from them, using the WASM implementation from\n * @babylonlabs-io/babylon-tbv-rust-wasm.\n *\n * Pre-PegIn Flow:\n * 1. buildPrePeginPsbt() — creates unfunded Pre-PegIn tx (HTLC output)\n * 2. [caller funds Pre-PegIn tx and computes txid]\n * 3. buildPeginTxFromFundedPrePegin() — derives PegIn tx spending the HTLC\n * 4. buildPeginInputPsbt() — PSBT for depositor to sign PegIn HTLC leaf 0 input\n *\n * @module primitives/psbt/pegin\n */\n\nimport {\n buildPeginTxFromPrePegin,\n createPrePeginTransaction,\n type Network,\n} from \"@babylonlabs-io/babylon-tbv-rust-wasm\";\n\nimport { parseUnfundedWasmTransaction } from \"../../utils/transaction/fundPeginTransaction\";\n\nimport {\n assertEncodedHtlcOutputsMatch,\n assertWasmPeginSizing,\n} from \"./assertWasmPeginSizing\";\n\n/**\n * Parameters for building an unfunded Pre-PegIn PSBT\n */\nexport interface PrePeginParams {\n /**\n * Vault core (tx-graph) version to build. Fresh deposits use the contract's\n * `ProtocolParams.activeVaultCoreVersion()`; resumed vaults use their\n * stamped on-chain `vaultCoreVersion`. The WASM facade fails closed on\n * versions it wasn't compiled with.\n */\n vaultCoreVersion: number;\n /** Depositor's BTC public key (x-only, 64-char hex without 0x prefix) */\n depositorPubkey: string;\n /** Vault provider's BTC public key (x-only, 64-char hex) */\n vaultProviderPubkey: string;\n /** Array of vault keeper BTC public keys (x-only, 64-char hex) */\n vaultKeeperPubkeys: string[];\n /** Array of universal challenger BTC public keys (x-only, 64-char hex) */\n universalChallengerPubkeys: string[];\n /** SHA256 hash commitment(s) (64 hex chars = 32 bytes each) */\n hashlocks: readonly string[];\n /** CSV timelock in blocks for the HTLC refund path */\n timelockRefund: number;\n /** Amounts to peg in (satoshis), one per deposit */\n pegInAmounts: readonly bigint[];\n /** TX-graph fee rate in sat/vB from contract offchain params; sizes the depositor claim value */\n feeRate: bigint;\n /** Minimum PegIn fee rate in sat/vB from contract offchain params; sizes the PegIn tx fee */\n minPeginFeeRate: bigint;\n /** Number of local challengers (from contract params) */\n numLocalChallengers: number;\n /** M in M-of-N council multisig (from contract params) */\n councilQuorum: number;\n /** N in M-of-N council multisig (from contract params) */\n councilSize: number;\n /** Bitcoin network */\n network: Network;\n /**\n * Optional 32-byte `SHA256(auth_anchor)` commitment (64-char hex, no\n * `0x` prefix). If provided, the Pre-PegIn tx will include an\n * `OP_RETURN <PUSH32 authAnchorHash>` output at vout =\n * `hashlocks.length`, binding the depositor's bearer-token\n * `auth_anchor` preimage to this Pre-PegIn.\n */\n authAnchorHash?: string;\n}\n\n/**\n * Byte length of an `auth_anchor_hash` commitment when encoded as a\n * lowercase hex string (32 bytes → 64 hex chars).\n */\nconst AUTH_ANCHOR_HASH_HEX_LEN = 64;\n\nconst HEX_PATTERN = /^[0-9a-fA-F]+$/;\n\n/**\n * Result of building an unfunded Pre-PegIn transaction\n */\nexport interface PrePeginPsbtResult {\n /**\n * Unfunded transaction hex (no inputs, HTLC outputs + optional\n * auth-anchor OP_RETURN + CPFP anchor).\n *\n * The caller is responsible for:\n * - Selecting UTXOs covering totalOutputValue + network fees\n * - Funding the transaction (add inputs and change output)\n * - Calling buildPeginTxFromFundedPrePegin() with the funded tx hex\n */\n psbtHex: string;\n /** Sum of all unfunded outputs — use this for UTXO selection */\n totalOutputValue: bigint;\n /** HTLC output values in satoshis, one per deposit (each includes peginAmount + depositorClaimValue + minPeginFee) */\n htlcValues: readonly bigint[];\n /** HTLC output scriptPubKeys (hex encoded), one per deposit */\n htlcScriptPubKeys: readonly string[];\n /** HTLC Taproot addresses, one per deposit */\n htlcAddresses: readonly string[];\n /** Pegin amounts in satoshis, one per deposit */\n peginAmounts: readonly bigint[];\n /** Depositor claim value computed by WASM from contract parameters */\n depositorClaimValue: bigint;\n /**\n * Vout index of the auth-anchor `OP_RETURN` output if one was\n * included (i.e. `authAnchorHash` was provided), or `null` if not.\n * Always equals `htlcValues.length` when present.\n */\n authAnchorVout: number | null;\n}\n\n/**\n * Parameters for building the PegIn transaction from a funded Pre-PegIn tx\n */\nexport interface BuildPeginTxParams {\n /** Same PrePeginParams used to create the Pre-PegIn transaction */\n prePeginParams: PrePeginParams;\n /** CSV timelock in blocks for the PegIn vault output */\n timelockPegin: number;\n /** Hex-encoded funded Pre-PegIn transaction */\n fundedPrePeginTxHex: string;\n /** Index of the HTLC output to spend */\n htlcVout: number;\n}\n\n/**\n * Result of building the PegIn transaction\n */\nexport interface PeginTxResult {\n /** PegIn transaction hex (1 input spending HTLC, 1 vault output) */\n txHex: string;\n /** PegIn transaction ID */\n txid: string;\n /** Vault output scriptPubKey (hex encoded) */\n vaultScriptPubKey: string;\n /** Vault output value in satoshis */\n vaultValue: bigint;\n}\n\n/**\n * Build unfunded Pre-PegIn transaction using WASM.\n *\n * Creates a Bitcoin transaction template with no inputs, an HTLC output, and a\n * CPFP anchor output. The HTLC value is computed internally from the contract\n * parameters — the caller does not need to compute depositorClaimValue separately.\n *\n * @param params - Pre-PegIn parameters\n * @returns Unfunded Pre-PegIn transaction details with HTLC output information\n * @throws If WASM initialization fails or parameters are invalid\n */\nexport async function buildPrePeginPsbt(\n params: PrePeginParams,\n): Promise<PrePeginPsbtResult> {\n const authAnchorHash = normalizeAuthAnchorHash(params.authAnchorHash);\n\n const result = await createPrePeginTransaction({\n txGraphVersion: params.vaultCoreVersion,\n depositorPubkey: params.depositorPubkey,\n vaultProviderPubkey: params.vaultProviderPubkey,\n vaultKeeperPubkeys: params.vaultKeeperPubkeys,\n universalChallengerPubkeys: params.universalChallengerPubkeys,\n hashlocks: [...params.hashlocks],\n timelockRefund: params.timelockRefund,\n pegInAmounts: [...params.pegInAmounts],\n feeRate: params.feeRate,\n minPeginFeeRate: params.minPeginFeeRate,\n numLocalChallengers: params.numLocalChallengers,\n councilQuorum: params.councilQuorum,\n councilSize: params.councilSize,\n network: params.network,\n authAnchorHash,\n });\n\n // CLAUDE.md critical path #1: the WASM outputs reach JS with no runtime\n // validation. Cross-check every value-bearing field against the request\n // and the protocol formula before it can feed a signed tx or the on-chain\n // PegIn registration. Both the sizing and commit passes route through here.\n await assertWasmPeginSizing(result, params);\n\n // Parse the unfunded tx to sum all output values\n // (HTLCs + optional OP_RETURN + CPFP anchor). This is the amount\n // UTXOs must cover before adding network fees.\n const parsed = parseUnfundedWasmTransaction(result.txHex);\n\n // Bind the validated metadata to the bytes that get funded and signed:\n // the encoded HTLC outputs must carry exactly the values/scripts the\n // cross-check above validated. Otherwise a tx whose real outputs differ\n // from the checked metadata could still be funded and signed.\n assertEncodedHtlcOutputsMatch(\n parsed.outputs,\n result.htlcValues,\n result.htlcScriptPubKeys,\n );\n\n const totalOutputValue = parsed.outputs.reduce(\n (sum, o) => sum + BigInt(o.value),\n 0n,\n );\n\n // The WASM places the OP_RETURN commitment immediately after the\n // HTLC outputs when authAnchorHash is provided.\n const authAnchorVout =\n authAnchorHash !== undefined ? result.htlcValues.length : null;\n\n return {\n psbtHex: result.txHex,\n totalOutputValue,\n htlcValues: result.htlcValues,\n htlcScriptPubKeys: result.htlcScriptPubKeys,\n htlcAddresses: result.htlcAddresses,\n peginAmounts: result.peginAmounts,\n depositorClaimValue: result.depositorClaimValue,\n authAnchorVout,\n };\n}\n\n/**\n * Validate and normalize an `authAnchorHash` hex string before passing\n * it to the WASM boundary. WASM expects exactly 64 lowercase hex chars.\n */\nexport function normalizeAuthAnchorHash(\n value: string | undefined,\n): string | undefined {\n if (value === undefined) return undefined;\n const cleaned =\n value.startsWith(\"0x\") || value.startsWith(\"0X\") ? value.slice(2) : value;\n if (\n cleaned.length !== AUTH_ANCHOR_HASH_HEX_LEN ||\n !HEX_PATTERN.test(cleaned)\n ) {\n throw new Error(\n `authAnchorHash must be 32-byte hex (${AUTH_ANCHOR_HASH_HEX_LEN} chars, no 0x prefix); got length ${cleaned.length}`,\n );\n }\n return cleaned.toLowerCase();\n}\n\n/**\n * Build the PegIn transaction from a funded Pre-PegIn transaction.\n *\n * The PegIn transaction spends the Pre-PegIn HTLC output at htlcVout via the\n * hashlock + all-party script (leaf 0).\n *\n * @param params - Build parameters including Pre-PegIn params and funded tx hex\n * @returns PegIn transaction details\n * @throws If WASM initialization fails or parameters are invalid\n */\nexport async function buildPeginTxFromFundedPrePegin(\n params: BuildPeginTxParams,\n): Promise<PeginTxResult> {\n // WASM reconstructs the Pre-PegIn template from these params to\n // decode the funded tx. Must pass `authAnchorHash` (normalized\n // identically to buildPrePeginPsbt) so the reconstruction matches\n // the original outputs, including the OP_RETURN at vout =\n // hashlocks.length.\n const result = await buildPeginTxFromPrePegin(\n {\n txGraphVersion: params.prePeginParams.vaultCoreVersion,\n depositorPubkey: params.prePeginParams.depositorPubkey,\n vaultProviderPubkey: params.prePeginParams.vaultProviderPubkey,\n vaultKeeperPubkeys: params.prePeginParams.vaultKeeperPubkeys,\n universalChallengerPubkeys:\n params.prePeginParams.universalChallengerPubkeys,\n hashlocks: [...params.prePeginParams.hashlocks],\n timelockRefund: params.prePeginParams.timelockRefund,\n pegInAmounts: [...params.prePeginParams.pegInAmounts],\n feeRate: params.prePeginParams.feeRate,\n minPeginFeeRate: params.prePeginParams.minPeginFeeRate,\n numLocalChallengers: params.prePeginParams.numLocalChallengers,\n councilQuorum: params.prePeginParams.councilQuorum,\n councilSize: params.prePeginParams.councilSize,\n network: params.prePeginParams.network,\n authAnchorHash: normalizeAuthAnchorHash(\n params.prePeginParams.authAnchorHash,\n ),\n },\n params.timelockPegin,\n params.fundedPrePeginTxHex,\n params.htlcVout,\n );\n\n return {\n txHex: result.txHex,\n txid: result.txid,\n vaultScriptPubKey: result.vaultScriptPubKey,\n vaultValue: result.vaultValue,\n };\n}\n","/**\n * Payout Script Generator Primitive\n *\n * This module provides pure functions for generating payout scripts and taproot information\n * by wrapping the WASM implementation from @babylonlabs-io/babylon-tbv-rust-wasm.\n *\n * The payout script is used for signing payout transactions in the vault system.\n * It defines the spending conditions for the vault output, enabling the depositor\n * to authorize payouts during the peg-in flow (Step 3).\n *\n * @remarks\n * This is a low-level primitive. For most use cases, prefer using {@link buildPayoutPsbt}\n * which handles script creation internally. For high-level wallet orchestration, use\n * PayoutManager from the managers module.\n *\n * @see {@link buildPayoutPsbt} - Higher-level function that uses this internally\n *\n * @module primitives/scripts/payout\n */\n\nimport {\n createPayoutConnector,\n type Network,\n} from \"@babylonlabs-io/babylon-tbv-rust-wasm\";\n\n/**\n * Parameters for creating a payout script.\n *\n * These parameters define the participants in a vault and are used to generate\n * the taproot script that controls how funds can be spent from the vault.\n */\nexport interface PayoutScriptParams {\n /**\n * Vault core (tx-graph) version the vault was registered under — the\n * vault's stamped on-chain `vaultCoreVersion`. Selects which graph's\n * payout connector the WASM derives.\n */\n vaultCoreVersion: number;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex without 0x prefix).\n *\n * This is the user depositing BTC into the vault. The depositor must sign\n * payout transactions to authorize fund distribution.\n */\n depositor: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex without 0x prefix).\n *\n * The service provider managing vault operations. Also referred to as\n * \"claimer\" in the WASM layer.\n */\n vaultProvider: string;\n\n /**\n * Array of vault keeper BTC public keys (x-only, 64-char hex without 0x prefix).\n *\n * Vault keepers participate in vault operations and script spending conditions.\n */\n vaultKeepers: string[];\n\n /**\n * Array of universal challenger BTC public keys (x-only, 64-char hex without 0x prefix).\n *\n * These parties can challenge the vault under certain conditions.\n */\n universalChallengers: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n\n /**\n * Bitcoin network for script generation.\n *\n * Must match the network used for all other vault operations to ensure\n * address encoding compatibility.\n */\n network: Network;\n}\n\n/**\n * Result of creating a payout script.\n *\n * Contains all the taproot-related data needed for constructing and signing\n * payout transactions from the vault.\n */\nexport interface PayoutScriptResult {\n /**\n * The payout script hex used in taproot script path spending.\n *\n * This is the raw script bytes that define the spending conditions,\n * encoded as a hexadecimal string. Used when constructing the\n * tapLeafScript for PSBT signing.\n */\n payoutScript: string;\n\n /**\n * The taproot script hash (leaf hash) for the payout script.\n *\n * This is the tagged hash of the script used in taproot tree construction.\n * Required for computing the control block during script path spending.\n */\n taprootScriptHash: string;\n\n /**\n * The full scriptPubKey for the vault output address.\n *\n * This is the complete output script (OP_1 <32-byte-key>) that should be\n * used when creating the vault output in a peg-in transaction.\n */\n scriptPubKey: string;\n\n /**\n * The vault Bitcoin address derived from the script.\n *\n * A human-readable bech32m address (bc1p... for mainnet, tb1p... for testnet/signet)\n * that can be used to receive funds into the vault.\n */\n address: string;\n\n /**\n * Serialized control block for Taproot script path spend (hex encoded).\n *\n * Computed by the Rust WASM PeginPayoutConnector. Used directly in\n * tapLeafScript when building payout PSBTs.\n */\n payoutControlBlock: string;\n}\n\n/**\n * Create payout script and taproot information using WASM.\n *\n * This is a pure function that wraps the Rust WASM implementation.\n * The payout connector generates the necessary taproot scripts and information\n * required for signing payout transactions.\n *\n * @remarks\n * The generated script encodes spending conditions that require signatures from\n * the depositor and vault provider (or liquidators in challenge scenarios).\n * This script is used internally by {@link buildPayoutPsbt}.\n *\n * @param params - Payout script parameters defining vault participants and network\n * @returns Payout script and taproot information for PSBT construction\n *\n * @see {@link buildPayoutPsbt} - Use this for building complete payout PSBTs\n */\nexport async function createPayoutScript(\n params: PayoutScriptParams,\n): Promise<PayoutScriptResult> {\n // Call the WASM wrapper with the correct parameter structure\n const connector = await createPayoutConnector(\n {\n txGraphVersion: params.vaultCoreVersion,\n depositor: params.depositor,\n vaultProvider: params.vaultProvider,\n vaultKeepers: params.vaultKeepers,\n universalChallengers: params.universalChallengers,\n timelockPegin: params.timelockPegin,\n },\n params.network,\n );\n\n return {\n payoutScript: connector.payoutScript,\n taprootScriptHash: connector.taprootScriptHash,\n scriptPubKey: connector.scriptPubKey,\n address: connector.address,\n payoutControlBlock: connector.payoutControlBlock,\n };\n}\n","/**\n * Payout PSBT Builder Primitives\n *\n * This module provides pure functions for building unsigned payout PSBTs and extracting\n * Schnorr signatures from signed PSBTs. It uses WASM-generated scripts from the payout\n * connector and bitcoinjs-lib for PSBT construction.\n *\n * The Payout transaction references the Assert transaction (input 1).\n *\n * @module primitives/psbt/payout\n */\n\nimport {\n type Network,\n tapInternalPubkey,\n} from \"@babylonlabs-io/babylon-tbv-rust-wasm\";\nimport { Buffer } from \"buffer\";\nimport { Psbt, Transaction } from \"bitcoinjs-lib\";\nimport { createPayoutScript } from \"../scripts/payout\";\nimport {\n TAPSCRIPT_LEAF_VERSION,\n deriveBip86ScriptPubKeyHex,\n hexToUint8Array,\n isValidHex,\n stripHexPrefix,\n uint8ArrayToHex,\n} from \"../utils/bitcoin\";\nimport {\n ASSERT_PAYOUT_OUTPUT_INDEX,\n MAX_VP_COMMISSION_BPS_EXCLUSIVE,\n NON_VP_CLAIMER_PAYOUT_OUTPUT_COUNT,\n PAYOUT_ANCHOR_DUST_SATS,\n PEGIN_VAULT_OUTPUT_INDEX,\n VP_CLAIMER_PAYOUT_OUTPUT_COUNT,\n} from \"./constants\";\n\n/**\n * Number of items in a Taproot script-path spend witness stack for a\n * single-signature script: [signature, script, controlBlock].\n *\n * The current payout script requires exactly one depositor signature. If the\n * protocol evolves to require multiple signatures in the payout script, this\n * invariant and the finalized-PSBT extraction path must be revisited because\n * the first witness item would no longer necessarily be the depositor's.\n */\nconst TAPROOT_SINGLE_SIG_WITNESS_STACK_SIZE = 3;\n\n/**\n * Coarse cap on a payout tx's implicit fee (inputs − outputs), as a fraction\n * of input value — blocks a VP deflating outputs and burning the remainder\n * as miner fee. A backstop only; the per-role structural checks in\n * {@link assertPayoutOutputLayout} are the primary value-diversion guard.\n */\nconst MAX_PAYOUT_FEE_FRACTION_NUMERATOR = 10;\nconst MAX_PAYOUT_FEE_FRACTION_DENOMINATOR = 100;\n\n/**\n * Parameters for building an unsigned Payout PSBT\n *\n * Payout is used in the challenge path after Assert, when the claimer proves validity.\n * Input 1 references the Assert transaction.\n */\nexport interface PayoutParams {\n /**\n * Vault core (tx-graph) version the vault was registered under — the\n * vault's stamped on-chain `vaultCoreVersion`. Selects which graph's\n * payout connector scripts are derived.\n */\n vaultCoreVersion: number;\n\n /**\n * Payout transaction hex (unsigned)\n * This is the transaction that needs to be signed by the depositor\n */\n payoutTxHex: string;\n\n /**\n * Assert transaction hex\n * Payout input 1 references Assert output 0\n */\n assertTxHex: string;\n\n /**\n * Peg-in transaction hex\n * This transaction created the vault output that we're spending\n */\n peginTxHex: string;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex without 0x prefix)\n */\n depositorBtcPubkey: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex)\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex)\n */\n vaultKeeperBtcPubkeys: string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex)\n */\n universalChallengerBtcPubkeys: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n\n /**\n * Bitcoin network\n */\n network: Network;\n\n /**\n * Claimer's x-only BTC public key (64-char hex, no prefix). Drives role\n * inference (VP / depositor-as-claimer / VK-claimer) inside `buildPayoutPsbt`.\n */\n claimerBtcPubkey: string;\n\n /**\n * On-chain registered depositor payout scriptPubKey (hex, 0x optional).\n * Expected outs[0].script for VP- and depositor-claimer roles; unused for\n * VK-claimer (its outs[0].script is derived from `claimerBtcPubkey`).\n */\n registeredPayoutScriptPubKey: string;\n\n /**\n * VP commission in basis points (`BTCVaultRegistry.vaultProviderCommissionBps`).\n * Caps the VP-claimer outs[1].value. The protocol minimum is enforced\n * upstream; here only `0 <= bps < 10_000` is checked, for safe cap math.\n */\n commissionBps: number;\n}\n\n/**\n * Result of building an unsigned payout PSBT\n */\nexport interface PayoutPsbtResult {\n /**\n * Unsigned PSBT hex ready for signing\n */\n psbtHex: string;\n}\n\n/**\n * Build unsigned Payout PSBT for depositor to sign.\n *\n * Payout is used in the **challenge path** when the claimer proves validity:\n * 1. Vault provider submits Claim transaction\n * 2. Challenge is raised during challenge period\n * 3. Claimer submits Assert transaction to prove validity\n * 4. Payout can be executed (references Assert tx)\n *\n * Payout transactions have the following structure:\n * - Input 0: from PeginTx output0 (signed by depositor)\n * - Input 1: from Assert output0 (NOT signed by depositor)\n *\n * @param params - Payout parameters\n * @returns Unsigned PSBT ready for depositor to sign\n *\n * @throws If payout transaction does not have exactly 2 inputs\n * @throws If input 0 does not spend PegIn:0 (vault UTXO)\n * @throws If input 1 does not spend Assert:0 (proof output)\n * @throws If previous output is not found for either input\n * @throws If sum of output values exceeds sum of input values (invalid tx)\n * @throws If implicit fee (inputs − outputs) exceeds the configured fraction\n * of total input value — see {@link MAX_PAYOUT_FEE_FRACTION_NUMERATOR}\n * @throws If `claimerBtcPubkey` is not VP, depositor, or a registered VK\n * @throws If payout output count, outs[0] script, outs[last] anchor value, or\n * (VP-claimer) outs[1] commission cap do not match the protocol layout\n * @throws If `commissionBps` is not a non-negative integer below 10_000\n */\nexport async function buildPayoutPsbt(\n params: PayoutParams,\n): Promise<PayoutPsbtResult> {\n // Normalize hex inputs (strip 0x prefix if present)\n const payoutTxHex = stripHexPrefix(params.payoutTxHex);\n const peginTxHex = stripHexPrefix(params.peginTxHex);\n const assertTxHex = stripHexPrefix(params.assertTxHex);\n\n // Get payout script from WASM\n const payoutConnector = await createPayoutScript({\n vaultCoreVersion: params.vaultCoreVersion,\n depositor: params.depositorBtcPubkey,\n vaultProvider: params.vaultProviderBtcPubkey,\n vaultKeepers: params.vaultKeeperBtcPubkeys,\n universalChallengers: params.universalChallengerBtcPubkeys,\n timelockPegin: params.timelockPegin,\n network: params.network,\n });\n\n const payoutScriptBytes = hexToUint8Array(payoutConnector.payoutScript);\n const controlBlock = hexToUint8Array(payoutConnector.payoutControlBlock);\n\n // Parse transactions\n const payoutTx = Transaction.fromHex(payoutTxHex);\n const peginTx = Transaction.fromHex(peginTxHex);\n const assertTx = Transaction.fromHex(assertTxHex);\n\n // Create PSBT\n const psbt = new Psbt();\n psbt.setVersion(payoutTx.version);\n psbt.setLocktime(payoutTx.locktime);\n\n // PayoutTx has exactly 2 inputs:\n // - Input 0: from PeginTx output0 (signed by depositor using taproot script path)\n // - Input 1: from Assert output0 (signed by claimer/challengers, not depositor)\n //\n // IMPORTANT: For Taproot SIGHASH_DEFAULT (0x00), the sighash commits to ALL inputs'\n // prevouts, not just the one being signed. Therefore, we must include BOTH inputs\n // in the PSBT so the wallet computes the correct sighash that the VP expects.\n\n // Verify payout transaction has expected structure\n if (payoutTx.ins.length !== 2) {\n throw new Error(\n `Payout transaction must have exactly 2 inputs, got ${payoutTx.ins.length}`,\n );\n }\n\n const input0 = payoutTx.ins[0];\n const input1 = payoutTx.ins[1];\n\n // Verify input 0 spends PegIn:0 (the vault UTXO).\n // Both txid AND vout must match the protocol contract — the vout is the\n // input-side anchor that prevents a malicious VP from binding the\n // depositor's signature to a different output of the same parent.\n const input0Txid = uint8ArrayToHex(\n new Uint8Array(input0.hash).slice().reverse(),\n );\n const peginTxid = peginTx.getId();\n\n if (input0Txid !== peginTxid || input0.index !== PEGIN_VAULT_OUTPUT_INDEX) {\n throw new Error(\n `Input 0 must spend PegIn:${PEGIN_VAULT_OUTPUT_INDEX}. ` +\n `Expected ${peginTxid}:${PEGIN_VAULT_OUTPUT_INDEX}, got ${input0Txid}:${input0.index}`,\n );\n }\n\n // Verify input 1 spends Assert:0 (the proof output).\n const input1Txid = uint8ArrayToHex(\n new Uint8Array(input1.hash).slice().reverse(),\n );\n const assertTxid = assertTx.getId();\n\n if (input1Txid !== assertTxid || input1.index !== ASSERT_PAYOUT_OUTPUT_INDEX) {\n throw new Error(\n `Input 1 must spend Assert:${ASSERT_PAYOUT_OUTPUT_INDEX}. ` +\n `Expected ${assertTxid}:${ASSERT_PAYOUT_OUTPUT_INDEX}, got ${input1Txid}:${input1.index}`,\n );\n }\n\n const peginPrevOut = peginTx.outs[input0.index];\n if (!peginPrevOut) {\n throw new Error(\n `Previous output not found for input 0 (txid: ${input0Txid}, index: ${input0.index})`,\n );\n }\n\n const input1PrevOut = assertTx.outs[input1.index];\n if (!input1PrevOut) {\n throw new Error(\n `Previous output not found for input 1 (txid: ${input1Txid}, index: ${input1.index})`,\n );\n }\n\n // Per-role output validation — blocks an extra attacker output or value\n // routed into a non-payout slot.\n assertPayoutOutputLayout({\n payoutTx,\n peginValueSats: peginPrevOut.value,\n claimerBtcPubkey: params.claimerBtcPubkey,\n vaultProviderBtcPubkey: params.vaultProviderBtcPubkey,\n depositorBtcPubkey: params.depositorBtcPubkey,\n vaultKeeperBtcPubkeys: params.vaultKeeperBtcPubkeys,\n registeredPayoutScriptPubKey: params.registeredPayoutScriptPubKey,\n commissionBps: params.commissionBps,\n });\n\n // Bound the implicit fee — blocks a VP deflating output values and burning\n // the difference as miner fee.\n const inputValueSats = peginPrevOut.value + input1PrevOut.value;\n let outputValueSats = 0;\n for (const out of payoutTx.outs) outputValueSats += out.value;\n if (outputValueSats > inputValueSats) {\n throw new Error(\n `Payout outputs (${outputValueSats} sats) exceed inputs ` +\n `(${inputValueSats} sats); invalid transaction.`,\n );\n }\n const implicitFeeSats = inputValueSats - outputValueSats;\n const maxFeeSats = Math.floor(\n (inputValueSats * MAX_PAYOUT_FEE_FRACTION_NUMERATOR) /\n MAX_PAYOUT_FEE_FRACTION_DENOMINATOR,\n );\n if (implicitFeeSats > maxFeeSats) {\n throw new Error(\n `Payout implicit fee ${implicitFeeSats} sats exceeds the safety cap ` +\n `of ${maxFeeSats} sats ` +\n `(${MAX_PAYOUT_FEE_FRACTION_NUMERATOR}/${MAX_PAYOUT_FEE_FRACTION_DENOMINATOR} ` +\n `of inputs=${inputValueSats}); refusing to sign payout.`,\n );\n }\n\n // Input 0: Depositor signs using Taproot script path spend\n // This input includes tapLeafScript for signing\n psbt.addInput({\n hash: input0.hash,\n index: input0.index,\n sequence: input0.sequence,\n witnessUtxo: {\n script: peginPrevOut.script,\n value: peginPrevOut.value,\n },\n tapLeafScript: [\n {\n leafVersion: TAPSCRIPT_LEAF_VERSION,\n script: Buffer.from(payoutScriptBytes),\n controlBlock: Buffer.from(controlBlock),\n },\n ],\n tapInternalKey: Buffer.from(tapInternalPubkey),\n // sighashType omitted - defaults to SIGHASH_DEFAULT (0x00) for Taproot\n });\n\n // Input 1: From Assert transaction (NOT signed by depositor)\n // We include this with witnessUtxo so the sighash is computed correctly,\n // but we do NOT include tapLeafScript since the depositor doesn't sign it.\n psbt.addInput({\n hash: input1.hash,\n index: input1.index,\n sequence: input1.sequence,\n witnessUtxo: {\n script: input1PrevOut.script,\n value: input1PrevOut.value,\n },\n // No tapLeafScript - depositor doesn't sign this input\n });\n\n // Add outputs\n for (const output of payoutTx.outs) {\n psbt.addOutput({\n script: output.script,\n value: output.value,\n });\n }\n\n return {\n psbtHex: psbt.toHex(),\n };\n}\n\n/**\n * Validate a payout transaction's output structure for the claimer's role,\n * keyed on `claimerBtcPubkey`. Pins per role: `outs.length`, `outs[0].script`,\n * `outs[last].value` (anchor dust), and (VP-claimer) `outs[1].value` capped at\n * `floor(peginValue × commissionBps / 10_000)`. Canonical layouts: VP-claimer\n * = [payout, commission, anchor]; depositor/VK-claimer = [payout, anchor].\n *\n * `outs[1].script` and `outs[last].script` are intentionally not pinned: the\n * value pins above bound depositor exposure regardless of where those outputs\n * are sent, so the value pins — not script pins — are load-bearing.\n *\n * @internal Helper invoked by {@link buildPayoutPsbt}.\n */\nfunction assertPayoutOutputLayout(args: {\n payoutTx: Transaction;\n peginValueSats: number;\n claimerBtcPubkey: string;\n vaultProviderBtcPubkey: string;\n depositorBtcPubkey: string;\n vaultKeeperBtcPubkeys: string[];\n registeredPayoutScriptPubKey: string;\n commissionBps: number;\n}): void {\n const {\n payoutTx,\n peginValueSats,\n claimerBtcPubkey,\n vaultProviderBtcPubkey,\n depositorBtcPubkey,\n vaultKeeperBtcPubkeys,\n registeredPayoutScriptPubKey,\n commissionBps,\n } = args;\n\n if (!isValidHex(registeredPayoutScriptPubKey)) {\n throw new Error(\"Invalid registeredPayoutScriptPubKey: not valid hex\");\n }\n\n const claimer = stripHexPrefix(claimerBtcPubkey).toLowerCase();\n const vp = stripHexPrefix(vaultProviderBtcPubkey).toLowerCase();\n const dep = stripHexPrefix(depositorBtcPubkey).toLowerCase();\n const keepers = vaultKeeperBtcPubkeys.map((k) =>\n stripHexPrefix(k).toLowerCase(),\n );\n\n type Role = \"vp-claimer\" | \"depositor-as-claimer\" | \"vk-claimer\";\n let role: Role;\n let expectedOutCount: number;\n let expectedOut0ScriptHex: string;\n\n if (claimer === vp) {\n role = \"vp-claimer\";\n expectedOutCount = VP_CLAIMER_PAYOUT_OUTPUT_COUNT;\n expectedOut0ScriptHex = stripHexPrefix(registeredPayoutScriptPubKey);\n } else if (claimer === dep) {\n role = \"depositor-as-claimer\";\n expectedOutCount = NON_VP_CLAIMER_PAYOUT_OUTPUT_COUNT;\n expectedOut0ScriptHex = stripHexPrefix(registeredPayoutScriptPubKey);\n } else if (keepers.includes(claimer)) {\n role = \"vk-claimer\";\n expectedOutCount = NON_VP_CLAIMER_PAYOUT_OUTPUT_COUNT;\n expectedOut0ScriptHex = stripHexPrefix(deriveBip86ScriptPubKeyHex(claimer));\n } else {\n throw new Error(\n `Unknown claimer pubkey ${claimer}: not VP, depositor, or a registered vault keeper`,\n );\n }\n\n if (payoutTx.outs.length !== expectedOutCount) {\n throw new Error(\n `Payout transaction has ${payoutTx.outs.length} output(s), ` +\n `expected exactly ${expectedOutCount} for role ${role}.`,\n );\n }\n\n const expectedOut0Script = Buffer.from(expectedOut0ScriptHex, \"hex\");\n if (!payoutTx.outs[0].script.equals(expectedOut0Script)) {\n throw new Error(\n `Payout transaction output 0 does not pay the expected scriptPubKey for role ${role}`,\n );\n }\n\n const anchorIdx = expectedOutCount - 1;\n if (payoutTx.outs[anchorIdx].value !== PAYOUT_ANCHOR_DUST_SATS) {\n throw new Error(\n `Payout CPFP anchor (out ${anchorIdx}) value ${payoutTx.outs[anchorIdx].value} sats ` +\n `must equal ${PAYOUT_ANCHOR_DUST_SATS} sats`,\n );\n }\n\n if (role === \"vp-claimer\") {\n // Structural guard only — a non-negative integer below the bps\n // denominator, so the cap math `floor(peginValue * bps / 10_000)` is\n // meaningful. The protocol minimum is enforced at the trust boundary\n // (`prepareSigningContext`); a too-low value here is fail-safe.\n if (\n !Number.isInteger(commissionBps) ||\n commissionBps < 0 ||\n commissionBps >= MAX_VP_COMMISSION_BPS_EXCLUSIVE\n ) {\n throw new Error(\n `commissionBps must be an integer in ` +\n `[0, ${MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${commissionBps}`,\n );\n }\n const maxCommissionSats = Math.floor(\n (peginValueSats * commissionBps) / MAX_VP_COMMISSION_BPS_EXCLUSIVE,\n );\n if (payoutTx.outs[1].value > maxCommissionSats) {\n throw new Error(\n `Payout VP commission (out 1) value ${payoutTx.outs[1].value} sats ` +\n `exceeds cap ${maxCommissionSats} sats ` +\n `(${commissionBps} bps of peginValue=${peginValueSats})`,\n );\n }\n }\n}\n\n/**\n * Extract Schnorr signature from signed payout PSBT.\n *\n * This function supports two cases:\n * 1. Non-finalized PSBT: Extracts from tapScriptSig field\n * 2. Finalized PSBT: Extracts from witness data\n *\n * The signature is returned as a 64-byte hex string (128 hex characters).\n * Payout signatures must use implicit Taproot SIGHASH_DEFAULT, which is\n * encoded by omitting the sighash byte.\n *\n * @param signedPsbtHex - Signed PSBT hex\n * @param depositorPubkey - Depositor's public key (x-only, 64-char hex)\n * @param inputIndex - Input index to extract signature from (default: 0)\n * @returns 64-byte Schnorr signature (128 hex characters, no sighash flag)\n *\n * @throws If no signature is found in the PSBT\n * @throws If the signature has an unexpected length\n */\nexport function extractPayoutSignature(\n signedPsbtHex: string,\n depositorPubkey: string,\n inputIndex = 0,\n): string {\n const signedPsbt = Psbt.fromHex(signedPsbtHex);\n\n if (inputIndex >= signedPsbt.data.inputs.length) {\n throw new Error(\n `Input index ${inputIndex} out of range (${signedPsbt.data.inputs.length} inputs)`,\n );\n }\n\n const input = signedPsbt.data.inputs[inputIndex];\n\n // Case 1: Non-finalized PSBT — extract from tapScriptSig\n if (input.tapScriptSig && input.tapScriptSig.length > 0) {\n const depositorPubkeyBytes = hexToUint8Array(depositorPubkey);\n\n for (const sigEntry of input.tapScriptSig) {\n if (sigEntry.pubkey.equals(Buffer.from(depositorPubkeyBytes))) {\n return extractSchnorrSig(sigEntry.signature, inputIndex);\n }\n }\n\n throw new Error(\n `No signature found for depositor pubkey: ${depositorPubkey} at input ${inputIndex}`,\n );\n }\n\n // Case 2: Finalized PSBT — extract from finalScriptWitness\n // Taproot single-signature script-path witness: [signature, script, controlBlock].\n // Enforce the exact stack size so that if a wallet produces an unexpected\n // finalization (e.g. a multi-signature stack, an annex, or malformed data),\n // we fail loudly instead of silently returning witnessStack[0] which may\n // not be the depositor's signature.\n if (input.finalScriptWitness && input.finalScriptWitness.length > 0) {\n const witnessStack = parseWitnessStack(input.finalScriptWitness);\n if (witnessStack.length !== TAPROOT_SINGLE_SIG_WITNESS_STACK_SIZE) {\n throw new Error(\n `Unexpected finalized witness stack size at input ${inputIndex}: ` +\n `expected ${TAPROOT_SINGLE_SIG_WITNESS_STACK_SIZE} items (signature, script, controlBlock), ` +\n `got ${witnessStack.length}`,\n );\n }\n return extractSchnorrSig(witnessStack[0], inputIndex);\n }\n\n throw new Error(\n `No tapScriptSig or finalScriptWitness found in signed PSBT at input ${inputIndex}`,\n );\n}\n\n/**\n * Extract and validate a 64-byte Schnorr signature.\n * Rejects 65-byte signatures because the appended sighash byte changes the\n * Taproot message being signed; stripping it would produce an unverifiable\n * SIGHASH_DEFAULT signature.\n * @internal\n */\nfunction extractSchnorrSig(sig: Uint8Array, inputIndex: number): string {\n if (sig.length === 64) {\n return uint8ArrayToHex(new Uint8Array(sig));\n }\n if (sig.length === 65) {\n throw new Error(\n `Unexpected sighash byte 0x${sig[64].toString(16).padStart(2, \"0\")} at input ${inputIndex}. ` +\n \"Expected implicit SIGHASH_DEFAULT as a 64-byte signature.\",\n );\n }\n throw new Error(\n `Unexpected signature length at input ${inputIndex}: ${sig.length}`,\n );\n}\n\n/**\n * Parse a BIP-141 serialized witness stack into individual stack items.\n * Format: [varint item_count] [varint len, data]...\n *\n * Throws on malformed input (truncated buffer, 8-byte varints, or trailing\n * bytes) so callers never receive silently-corrupted witness items.\n * @internal\n */\nfunction parseWitnessStack(witness: Buffer): Buffer[] {\n const items: Buffer[] = [];\n let offset = 0;\n\n const requireBytes = (n: number): void => {\n if (offset + n > witness.length) {\n throw new Error(\n `Malformed witness data: need ${n} byte(s) at offset ${offset}, only ${witness.length - offset} remaining`,\n );\n }\n };\n\n const readVarInt = (): number => {\n requireBytes(1);\n const first = witness[offset++];\n if (first < 0xfd) return first;\n if (first === 0xfd) {\n requireBytes(2);\n const val = (witness[offset] | (witness[offset + 1] << 8)) >>> 0;\n offset += 2;\n return val;\n }\n if (first === 0xfe) {\n requireBytes(4);\n const val =\n (witness[offset] |\n (witness[offset + 1] << 8) |\n (witness[offset + 2] << 16) |\n (witness[offset + 3] << 24)) >>>\n 0;\n offset += 4;\n return val;\n }\n // 0xff — 8-byte varint. Not used for witness sizes in practice and JS\n // numbers cannot represent all 64-bit values exactly, so reject rather\n // than risk silent truncation.\n throw new Error(\n `Malformed witness data: 8-byte varint (0xff) not supported at offset ${offset - 1}`,\n );\n };\n\n const count = readVarInt();\n for (let i = 0; i < count; i++) {\n const len = readVarInt();\n requireBytes(len);\n items.push(Buffer.from(witness.subarray(offset, offset + len)));\n offset += len;\n }\n\n if (offset !== witness.length) {\n throw new Error(\n `Malformed witness data: ${witness.length - offset} trailing byte(s) after parsing ${count} item(s)`,\n );\n }\n\n return items;\n}\n\n","/**\n * Asserts a wallet-returned PSBT encodes the same unsigned transaction\n * as the locally-built PSBT we asked the wallet to sign. Per-input PSBT\n * metadata (witnessUtxo, tapLeafScript, sighashType) is intentionally NOT\n * compared — those fields are committed to the Schnorr sighash and the\n * vault provider's `verify_depositor_signature` rejects mismatches there.\n * This primitive defends the path where a colluding VP would otherwise\n * accept a wallet-substituted signature.\n */\n\nimport { Buffer } from \"buffer\";\n\nimport { Psbt } from \"bitcoinjs-lib\";\n\n/**\n * Thrown when a wallet-returned PSBT encodes a different unsigned\n * transaction than the one the caller asked the wallet to sign.\n */\nexport class PsbtSubstitutionError extends Error {\n constructor(detail: string) {\n super(\n `Wallet returned a PSBT for a different transaction: ${detail}`,\n );\n this.name = \"PsbtSubstitutionError\";\n }\n}\n\nexport interface AssertPsbtUnsignedTxMatchesParams {\n /** PSBT we built locally and asked the wallet to sign. */\n requestedPsbtHex: string;\n /** PSBT the wallet returned after signing. */\n returnedPsbtHex: string;\n}\n\nfunction parsePsbt(label: \"requested\" | \"returned\", hex: string): Psbt {\n try {\n return Psbt.fromHex(hex);\n } catch (cause) {\n const reason = cause instanceof Error ? cause.message : String(cause);\n throw new Error(`Failed to parse ${label} PSBT: ${reason}`);\n }\n}\n\n/**\n * Length of the hex prefix included in mismatch errors. Short enough that\n * full prevout txids and output scriptPubKeys never reach logs / error\n * trackers, long enough to disambiguate during forensic triage.\n */\nconst REDACTED_HEX_PREFIX_LEN = 8;\n\nfunction redactHex(buf: Buffer): string {\n return `${buf.toString(\"hex\").slice(0, REDACTED_HEX_PREFIX_LEN)}…`;\n}\n\n/**\n * `bitcoinjs-lib` exposes `txInputs[i].hash` in internal little-endian form;\n * a human reading logs expects the big-endian txid an explorer would show.\n * Reverse before truncating so the surfaced prefix matches what an operator\n * can search for.\n */\nfunction redactTxid(internalHash: Buffer): string {\n const reversed = Buffer.from(internalHash).reverse();\n return redactHex(reversed);\n}\n\n/**\n * Compare two PSBTs and throw `PsbtSubstitutionError` unless they encode\n * the same unsigned transaction (version, locktime, inputs, outputs).\n *\n * @throws PsbtSubstitutionError on any mismatch in the unsigned tx\n * @throws Error if either PSBT cannot be parsed\n */\nexport function assertPsbtUnsignedTxMatches(\n params: AssertPsbtUnsignedTxMatchesParams,\n): void {\n const requested = parsePsbt(\"requested\", params.requestedPsbtHex);\n const returned = parsePsbt(\"returned\", params.returnedPsbtHex);\n\n if (requested.version !== returned.version) {\n throw new PsbtSubstitutionError(\n `tx version differs (requested=${requested.version}, returned=${returned.version})`,\n );\n }\n if (requested.locktime !== returned.locktime) {\n throw new PsbtSubstitutionError(\n `tx locktime differs (requested=${requested.locktime}, returned=${returned.locktime})`,\n );\n }\n if (requested.txInputs.length !== returned.txInputs.length) {\n throw new PsbtSubstitutionError(\n `input count differs (requested=${requested.txInputs.length}, returned=${returned.txInputs.length})`,\n );\n }\n if (requested.txOutputs.length !== returned.txOutputs.length) {\n throw new PsbtSubstitutionError(\n `output count differs (requested=${requested.txOutputs.length}, returned=${returned.txOutputs.length})`,\n );\n }\n for (let i = 0; i < requested.txInputs.length; i++) {\n const r = requested.txInputs[i];\n const s = returned.txInputs[i];\n if (!r.hash.equals(s.hash)) {\n throw new PsbtSubstitutionError(\n `input ${i} prevout txid differs (requested=${redactTxid(r.hash)}, returned=${redactTxid(s.hash)})`,\n );\n }\n if (r.index !== s.index) {\n throw new PsbtSubstitutionError(\n `input ${i} prevout vout differs (requested=${r.index}, returned=${s.index})`,\n );\n }\n if (r.sequence !== s.sequence) {\n throw new PsbtSubstitutionError(\n `input ${i} sequence differs (requested=${r.sequence}, returned=${s.sequence})`,\n );\n }\n }\n for (let i = 0; i < requested.txOutputs.length; i++) {\n const r = requested.txOutputs[i];\n const s = returned.txOutputs[i];\n if (!r.script.equals(s.script)) {\n throw new PsbtSubstitutionError(\n `output ${i} scriptPubKey differs (requested=${redactHex(r.script)}, returned=${redactHex(s.script)})`,\n );\n }\n if (r.value !== s.value) {\n throw new PsbtSubstitutionError(\n `output ${i} value differs (requested=${r.value}, returned=${s.value})`,\n );\n }\n }\n}\n","/**\n * Independent BIP-340 verification of a wallet-returned Taproot script-path\n * Schnorr signature against an independently-recomputed sighash.\n *\n * Critical Path #7 (CLAUDE.md): the SDK requests script-path signatures with\n * `useTweakedSigner: false, autoFinalized: false`. Wallet support for the\n * untweaked-key flag is inconsistent — older OKX / mobile bridges silently sign\n * with the *tweaked* key, Keystone ignores the flag — and a compromised\n * extension can stuff a 64-byte stub into `tapScriptSig`. A bad signature that\n * the SDK forwards is only caught on broadcast; in the worst case it passes the\n * VP off-chain but Bitcoin rejects it, leaving the depositor's BTC locked in the\n * HTLC until `timelockRefund` matures. This guard rejects such signatures before\n * they are trusted.\n *\n * Why verify against the *locally-built* PSBT, not the wallet-returned one:\n * `assertPsbtUnsignedTxMatches` pins the unsigned transaction but deliberately\n * skips per-input metadata (`witnessUtxo`, `tapLeafScript`). A malicious wallet\n * could rewrite those consistently in the returned PSBT so a wrong-message\n * signature self-validates. The trusted prevout scripts/values and leaf script\n * therefore come from the PSBT we built ourselves (derived from on-chain / WASM\n * sources); only the 64-byte signature comes from the wallet.\n *\n * Reuses the exact primitives `bip322Verify.ts` already depends on — no new\n * dependency:\n * - `@bitcoin-js/tiny-secp256k1-asmjs` → `verifySchnorr`\n * - `bitcoinjs-lib` → `Transaction.hashForWitnessV1`, `crypto.taggedHash` (TapLeaf hash)\n *\n * @module tbv/core/primitives/psbt/verifyScriptPathSchnorrSignature\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { Psbt, Transaction, crypto as bcrypto } from \"bitcoinjs-lib\";\n\nimport { Buffer } from \"buffer\";\n\nimport {\n SCHNORR_SIG_HEX_LEN,\n TAPSCRIPT_LEAF_VERSION,\n X_ONLY_PUBKEY_HEX_LEN,\n hexToUint8Array,\n stripHexPrefix,\n} from \"../utils/bitcoin\";\n\n// Bitcoin CompactSize (varint) prefix markers — values fixed by the protocol.\n// https://developer.bitcoin.org/reference/transactions.html#compactsize-unsigned-integers\nconst COMPACT_SIZE_UINT16_PREFIX = 0xfd; // value in [0xfd, 0xffff] → 0xfd + uint16 LE\nconst COMPACT_SIZE_UINT32_PREFIX = 0xfe; // value in [0x10000, 0xffffffff] → 0xfe + uint32 LE\nconst COMPACT_SIZE_UINT16_MAX = 0xffff;\nconst COMPACT_SIZE_UINT32_MAX = 0xffffffff;\n\n/**\n * Encode a length as a Bitcoin CompactSize (varint). Tapscript leaf scripts can\n * exceed 252 bytes (WOTS scripts), so the multi-byte forms are required, not\n * just the single-byte fast path.\n */\nfunction encodeCompactSize(n: number): Buffer {\n if (n < COMPACT_SIZE_UINT16_PREFIX) {\n return Buffer.from([n]);\n }\n if (n <= COMPACT_SIZE_UINT16_MAX) {\n const value = Buffer.alloc(2); // uint16, little-endian\n value.writeUInt16LE(n);\n return Buffer.concat([Buffer.from([COMPACT_SIZE_UINT16_PREFIX]), value]);\n }\n if (n <= COMPACT_SIZE_UINT32_MAX) {\n const value = Buffer.alloc(4); // uint32, little-endian\n value.writeUInt32LE(n);\n return Buffer.concat([Buffer.from([COMPACT_SIZE_UINT32_PREFIX]), value]);\n }\n throw new Error(`Script too large to encode as CompactSize: ${n} bytes`);\n}\n\n/** BIP-341 tag for the TapLeaf hash. */\nconst TAPLEAF_TAG = \"TapLeaf\";\n\n/**\n * Compute the BIP-341 TapLeaf hash for a tapscript leaf:\n * `tagged_hash(\"TapLeaf\", leaf_version || compact_size(script) || script)`.\n */\nfunction computeTapLeafHash(leafVersion: number, script: Uint8Array): Buffer {\n const preimage = Buffer.concat([\n Buffer.from([leafVersion]),\n encodeCompactSize(script.length),\n Buffer.from(script),\n ]);\n return bcrypto.taggedHash(TAPLEAF_TAG, preimage);\n}\n\nexport interface VerifyScriptPathSchnorrSignatureParams {\n /**\n * Hex of the PSBT we built locally and sent to the wallet (the trusted\n * source of prevout scripts/values and the leaf script). NOT the\n * wallet-returned PSBT.\n */\n requestedPsbtHex: string;\n /** The 64-byte Schnorr signature extracted from the wallet's response (128 hex chars). */\n signatureHex: string;\n /** X-only public key (64 hex chars) the wallet signed the script-path leaf with. */\n signerXOnlyPubkeyHex: string;\n /** Index of the input the signature is for. */\n inputIndex: number;\n}\n\n/**\n * Assert that `signatureHex` is a valid BIP-340 Schnorr signature by the\n * `signerXOnlyPubkeyHex` key over the Taproot script-path sighash of\n * `requestedPsbtHex` input `inputIndex` (SIGHASH_DEFAULT).\n *\n * @throws If the requested PSBT is malformed, lacks the prevout/leaf data needed\n * to recompute the sighash, or the signature does not verify.\n */\nexport function assertScriptPathSchnorrSignature(\n params: VerifyScriptPathSchnorrSignatureParams,\n): void {\n const { requestedPsbtHex, signatureHex, signerXOnlyPubkeyHex, inputIndex } =\n params;\n\n const signatureRaw = stripHexPrefix(signatureHex);\n if (signatureRaw.length !== SCHNORR_SIG_HEX_LEN) {\n throw new Error(\n `Schnorr signature for input ${inputIndex} must be ${SCHNORR_SIG_HEX_LEN} hex chars ` +\n `(64 bytes), got ${signatureRaw.length}.`,\n );\n }\n\n const signerXOnly = stripHexPrefix(signerXOnlyPubkeyHex);\n if (signerXOnly.length !== X_ONLY_PUBKEY_HEX_LEN) {\n throw new Error(\n `Signer x-only pubkey for input ${inputIndex} must be ${X_ONLY_PUBKEY_HEX_LEN} hex chars ` +\n `(32 bytes), got ${signerXOnly.length}.`,\n );\n }\n\n const psbt = Psbt.fromHex(requestedPsbtHex);\n\n if (inputIndex < 0 || inputIndex >= psbt.data.inputs.length) {\n throw new Error(\n `Input index ${inputIndex} out of range (${psbt.data.inputs.length} inputs).`,\n );\n }\n\n // Taproot's sighash commits to every input's prevout (script + value), so all\n // inputs must carry a witnessUtxo. A missing one is a build error, not a\n // value we can default — fail loudly.\n const prevOutScripts: Buffer[] = [];\n const values: number[] = [];\n for (let i = 0; i < psbt.data.inputs.length; i++) {\n const witnessUtxo = psbt.data.inputs[i].witnessUtxo;\n if (!witnessUtxo) {\n throw new Error(\n `Cannot verify signature: input ${i} of the requested PSBT has no witnessUtxo ` +\n `(required to recompute the Taproot sighash).`,\n );\n }\n prevOutScripts.push(witnessUtxo.script);\n values.push(witnessUtxo.value);\n }\n\n // The signed input must expose exactly one tapLeafScript — the leaf the\n // depositor signs. Zero means we sent the wrong PSBT; more than one means an\n // ambiguous spend path we never construct for a single-signature input.\n const tapLeafScripts = psbt.data.inputs[inputIndex].tapLeafScript;\n if (!tapLeafScripts || tapLeafScripts.length !== 1) {\n throw new Error(\n `Cannot verify signature: input ${inputIndex} of the requested PSBT must have exactly ` +\n `one tapLeafScript, got ${tapLeafScripts?.length ?? 0}.`,\n );\n }\n const leaf = tapLeafScripts[0];\n if (leaf.leafVersion !== TAPSCRIPT_LEAF_VERSION) {\n throw new Error(\n `Cannot verify signature: input ${inputIndex} tapLeafScript has leaf version ` +\n `0x${leaf.leafVersion.toString(16)}, expected 0x${TAPSCRIPT_LEAF_VERSION.toString(16)}.`,\n );\n }\n\n const leafHash = computeTapLeafHash(leaf.leafVersion, leaf.script);\n\n // Reconstruct the unsigned transaction from the requested PSBT using only\n // public bitcoinjs-lib API (same pattern as bip322Verify.ts), then compute the\n // BIP-341 script-path sighash with SIGHASH_DEFAULT.\n const tx = new Transaction();\n tx.version = psbt.version;\n tx.locktime = psbt.locktime;\n for (const input of psbt.txInputs) {\n tx.addInput(input.hash, input.index, input.sequence);\n }\n for (const output of psbt.txOutputs) {\n tx.addOutput(output.script, output.value);\n }\n\n const sighash = tx.hashForWitnessV1(\n inputIndex,\n prevOutScripts,\n values,\n Transaction.SIGHASH_DEFAULT,\n leafHash,\n );\n\n const isValid = ecc.verifySchnorr(\n sighash,\n hexToUint8Array(signerXOnly),\n hexToUint8Array(signatureRaw),\n );\n\n if (!isValid) {\n throw new Error(\n `Schnorr signature for input ${inputIndex} (signer ${signerXOnly}) does not verify ` +\n `against the expected Taproot script-path sighash. The wallet may have signed with ` +\n `the tweaked key, signed a different transaction, or returned an invalid signature.`,\n );\n }\n}\n"],"names":["assertWasmPeginSizing","result","params","expectedCount","expectedClaimValue","computeMinClaimValue","maxImpliedFee","MAX_REASONABLE_PEGIN_VBYTES","requested","peginAmount","htlcValue","impliedFee","assertEncodedHtlcOutputsMatch","outputs","htlcValues","htlcScriptPubKeys","i","encodedValue","encodedScript","expectedScript","AUTH_ANCHOR_HASH_HEX_LEN","HEX_PATTERN","buildPrePeginPsbt","authAnchorHash","normalizeAuthAnchorHash","createPrePeginTransaction","parsed","parseUnfundedWasmTransaction","totalOutputValue","sum","o","authAnchorVout","value","cleaned","buildPeginTxFromFundedPrePegin","buildPeginTxFromPrePegin","createPayoutScript","connector","createPayoutConnector","TAPROOT_SINGLE_SIG_WITNESS_STACK_SIZE","MAX_PAYOUT_FEE_FRACTION_NUMERATOR","MAX_PAYOUT_FEE_FRACTION_DENOMINATOR","buildPayoutPsbt","payoutTxHex","stripHexPrefix","peginTxHex","assertTxHex","payoutConnector","payoutScriptBytes","hexToUint8Array","controlBlock","payoutTx","Transaction","peginTx","assertTx","psbt","Psbt","input0","input1","input0Txid","uint8ArrayToHex","peginTxid","PEGIN_VAULT_OUTPUT_INDEX","input1Txid","assertTxid","ASSERT_PAYOUT_OUTPUT_INDEX","peginPrevOut","input1PrevOut","assertPayoutOutputLayout","inputValueSats","outputValueSats","out","implicitFeeSats","maxFeeSats","TAPSCRIPT_LEAF_VERSION","Buffer","tapInternalPubkey","output","args","peginValueSats","claimerBtcPubkey","vaultProviderBtcPubkey","depositorBtcPubkey","vaultKeeperBtcPubkeys","registeredPayoutScriptPubKey","commissionBps","isValidHex","claimer","vp","dep","keepers","k","role","expectedOutCount","expectedOut0ScriptHex","VP_CLAIMER_PAYOUT_OUTPUT_COUNT","NON_VP_CLAIMER_PAYOUT_OUTPUT_COUNT","deriveBip86ScriptPubKeyHex","expectedOut0Script","anchorIdx","PAYOUT_ANCHOR_DUST_SATS","MAX_VP_COMMISSION_BPS_EXCLUSIVE","maxCommissionSats","extractPayoutSignature","signedPsbtHex","depositorPubkey","inputIndex","signedPsbt","input","depositorPubkeyBytes","sigEntry","extractSchnorrSig","witnessStack","parseWitnessStack","sig","witness","items","offset","requireBytes","n","readVarInt","first","val","count","len","PsbtSubstitutionError","detail","parsePsbt","label","hex","cause","reason","REDACTED_HEX_PREFIX_LEN","redactHex","buf","redactTxid","internalHash","reversed","assertPsbtUnsignedTxMatches","returned","r","s","COMPACT_SIZE_UINT16_PREFIX","COMPACT_SIZE_UINT32_PREFIX","COMPACT_SIZE_UINT16_MAX","COMPACT_SIZE_UINT32_MAX","encodeCompactSize","TAPLEAF_TAG","computeTapLeafHash","leafVersion","script","preimage","bcrypto","assertScriptPathSchnorrSignature","requestedPsbtHex","signatureHex","signerXOnlyPubkeyHex","signatureRaw","SCHNORR_SIG_HEX_LEN","signerXOnly","X_ONLY_PUBKEY_HEX_LEN","prevOutScripts","values","witnessUtxo","tapLeafScripts","leaf","leafHash","tx","sighash","ecc"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const e=[{type:"function",name:"getTBVProtocolParams",inputs:[],outputs:[{name:"",type:"tuple",internalType:"struct IProtocolParams.TBVProtocolParams",components:[{name:"minimumPegInAmount",type:"uint64",internalType:"uint64"},{name:"maxPegInAmount",type:"uint64",internalType:"uint64"},{name:"pegInAckTimeout",type:"uint64",internalType:"uint64"},{name:"pegInActivationTimeout",type:"uint64",internalType:"uint64"},{name:"maxHtlcOutputCount",type:"uint8",internalType:"uint8"},{name:"expiredPegInGraceBlocks",type:"uint64",internalType:"uint64"}]}],stateMutability:"view"},{type:"function",name:"getLatestOffchainParams",inputs:[],outputs:[{name:"",type:"tuple",internalType:"struct IProtocolParams.VersionedOffchainParams",components:[{name:"timelockAssert",type:"uint256",internalType:"uint256"},{name:"timelockChallengeAssert",type:"uint256",internalType:"uint256"},{name:"securityCouncilKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"councilQuorum",type:"uint8",internalType:"uint8"},{name:"feeRate",type:"uint64",internalType:"uint64"},{name:"babeTotalInstances",type:"uint16",internalType:"uint16"},{name:"babeInstancesToFinalize",type:"uint8",internalType:"uint8"},{name:"minVpCommissionBps",type:"uint16",internalType:"uint16"},{name:"tRefund",type:"uint32",internalType:"uint32"},{name:"tStale",type:"uint32",internalType:"uint32"},{name:"minPeginFeeRate",type:"uint64",internalType:"uint64"},{name:"proverCircuitVersion",type:"uint16",internalType:"uint16"},{name:"minPrepeginDepth",type:"uint32",internalType:"uint32"}]}],stateMutability:"view"},{type:"function",name:"getOffchainParamsByVersion",inputs:[{name:"versionNumber",type:"uint16",internalType:"uint16"}],outputs:[{name:"",type:"tuple",internalType:"struct IProtocolParams.VersionedOffchainParams",components:[{name:"timelockAssert",type:"uint256",internalType:"uint256"},{name:"timelockChallengeAssert",type:"uint256",internalType:"uint256"},{name:"securityCouncilKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"councilQuorum",type:"uint8",internalType:"uint8"},{name:"feeRate",type:"uint64",internalType:"uint64"},{name:"babeTotalInstances",type:"uint16",internalType:"uint16"},{name:"babeInstancesToFinalize",type:"uint8",internalType:"uint8"},{name:"minVpCommissionBps",type:"uint16",internalType:"uint16"},{name:"tRefund",type:"uint32",internalType:"uint32"},{name:"tStale",type:"uint32",internalType:"uint32"},{name:"minPeginFeeRate",type:"uint64",internalType:"uint64"},{name:"proverCircuitVersion",type:"uint16",internalType:"uint16"},{name:"minPrepeginDepth",type:"uint32",internalType:"uint32"}]}],stateMutability:"view"},{type:"function",name:"latestOffchainParamsVersion",inputs:[],outputs:[{name:"",type:"uint16",internalType:"uint16"}],stateMutability:"view"},{type:"function",name:"getUniversalChallengersByVersion",inputs:[{name:"versionNumber",type:"uint16",internalType:"uint16"}],outputs:[{name:"",type:"tuple[]",internalType:"struct BTCVaultTypes.AddressBTCKeyPair[]",components:[{name:"ethAddress",type:"address",internalType:"address"},{name:"btcPubKey",type:"bytes32",internalType:"bytes32"}]}],stateMutability:"view"},{type:"function",name:"getCurrentUniversalChallengers",inputs:[],outputs:[{name:"",type:"tuple[]",internalType:"struct BTCVaultTypes.AddressBTCKeyPair[]",components:[{name:"ethAddress",type:"address",internalType:"address"},{name:"btcPubKey",type:"bytes32",internalType:"bytes32"}]}],stateMutability:"view"},{type:"function",name:"latestUniversalChallengersVersion",inputs:[],outputs:[{name:"",type:"uint16",internalType:"uint16"}],stateMutability:"view"}],t=[{type:"function",name:"getVaultKeepersByVersion",inputs:[{name:"appEntryPoint",type:"address",internalType:"address"},{name:"versionNumber",type:"uint16",internalType:"uint16"}],outputs:[{name:"",type:"tuple[]",internalType:"struct BTCVaultTypes.AddressBTCKeyPair[]",components:[{name:"ethAddress",type:"address",internalType:"address"},{name:"btcPubKey",type:"bytes32",internalType:"bytes32"}]}],stateMutability:"view"},{type:"function",name:"getCurrentVaultKeepers",inputs:[{name:"appEntryPoint",type:"address",internalType:"address"}],outputs:[{name:"",type:"tuple[]",internalType:"struct BTCVaultTypes.AddressBTCKeyPair[]",components:[{name:"ethAddress",type:"address",internalType:"address"},{name:"btcPubKey",type:"bytes32",internalType:"bytes32"}]}],stateMutability:"view"},{type:"function",name:"getCurrentVaultKeepersVersion",inputs:[{name:"appEntryPoint",type:"address",internalType:"address"}],outputs:[{name:"",type:"uint16",internalType:"uint16"}],stateMutability:"view"}];exports.ApplicationRegistryABI=t;exports.ProtocolParamsABI=e;
|
|
2
|
-
//# sourceMappingURL=ApplicationRegistry.abi-BAPhJch3.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationRegistry.abi-BAPhJch3.cjs","sources":["../src/tbv/core/contracts/abis/ProtocolParams.abi.ts","../src/tbv/core/contracts/abis/ApplicationRegistry.abi.ts"],"sourcesContent":["/**\n * ProtocolParams Contract ABI\n *\n * Minimal ABI containing only the read functions needed by the SDK.\n * Generated from vault-contracts-aave-v4 IProtocolParams.sol interface.\n *\n * @module contracts/abis/ProtocolParams\n */\n\nexport const ProtocolParamsABI = [\n {\n type: \"function\",\n name: \"getTBVProtocolParams\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.TBVProtocolParams\",\n components: [\n {\n name: \"minimumPegInAmount\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"maxPegInAmount\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"pegInAckTimeout\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"pegInActivationTimeout\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"maxHtlcOutputCount\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"expiredPegInGraceBlocks\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getLatestOffchainParams\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.VersionedOffchainParams\",\n components: [\n {\n name: \"timelockAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"timelockChallengeAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"securityCouncilKeys\",\n type: \"bytes32[]\",\n internalType: \"bytes32[]\",\n },\n {\n name: \"councilQuorum\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"feeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"babeTotalInstances\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"babeInstancesToFinalize\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"minVpCommissionBps\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"tRefund\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"tStale\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"minPeginFeeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"proverCircuitVersion\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"minPrepeginDepth\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getOffchainParamsByVersion\",\n inputs: [\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.VersionedOffchainParams\",\n components: [\n {\n name: \"timelockAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"timelockChallengeAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"securityCouncilKeys\",\n type: \"bytes32[]\",\n internalType: \"bytes32[]\",\n },\n {\n name: \"councilQuorum\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"feeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"babeTotalInstances\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"babeInstancesToFinalize\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"minVpCommissionBps\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"tRefund\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"tStale\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"minPeginFeeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"proverCircuitVersion\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"minPrepeginDepth\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"latestOffchainParamsVersion\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getUniversalChallengersByVersion\",\n inputs: [\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentUniversalChallengers\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"latestUniversalChallengersVersion\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n] as const;\n","/**\n * ApplicationRegistry Contract ABI\n *\n * Minimal ABI containing only the vault keeper read functions needed by the SDK.\n * Generated from vault-contracts-aave-v4 IApplicationRegistry.sol interface.\n *\n * @module contracts/abis/ApplicationRegistry\n */\n\nexport const ApplicationRegistryABI = [\n {\n type: \"function\",\n name: \"getVaultKeepersByVersion\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentVaultKeepers\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentVaultKeepersVersion\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n] as const;\n"],"names":["ProtocolParamsABI","ApplicationRegistryABI"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationRegistry.abi-Dn2qk6JG.js","sources":["../src/tbv/core/contracts/abis/ProtocolParams.abi.ts","../src/tbv/core/contracts/abis/ApplicationRegistry.abi.ts"],"sourcesContent":["/**\n * ProtocolParams Contract ABI\n *\n * Minimal ABI containing only the read functions needed by the SDK.\n * Generated from vault-contracts-aave-v4 IProtocolParams.sol interface.\n *\n * @module contracts/abis/ProtocolParams\n */\n\nexport const ProtocolParamsABI = [\n {\n type: \"function\",\n name: \"getTBVProtocolParams\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.TBVProtocolParams\",\n components: [\n {\n name: \"minimumPegInAmount\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"maxPegInAmount\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"pegInAckTimeout\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"pegInActivationTimeout\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"maxHtlcOutputCount\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"expiredPegInGraceBlocks\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getLatestOffchainParams\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.VersionedOffchainParams\",\n components: [\n {\n name: \"timelockAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"timelockChallengeAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"securityCouncilKeys\",\n type: \"bytes32[]\",\n internalType: \"bytes32[]\",\n },\n {\n name: \"councilQuorum\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"feeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"babeTotalInstances\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"babeInstancesToFinalize\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"minVpCommissionBps\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"tRefund\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"tStale\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"minPeginFeeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"proverCircuitVersion\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"minPrepeginDepth\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getOffchainParamsByVersion\",\n inputs: [\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n internalType: \"struct IProtocolParams.VersionedOffchainParams\",\n components: [\n {\n name: \"timelockAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"timelockChallengeAssert\",\n type: \"uint256\",\n internalType: \"uint256\",\n },\n {\n name: \"securityCouncilKeys\",\n type: \"bytes32[]\",\n internalType: \"bytes32[]\",\n },\n {\n name: \"councilQuorum\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"feeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"babeTotalInstances\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"babeInstancesToFinalize\",\n type: \"uint8\",\n internalType: \"uint8\",\n },\n {\n name: \"minVpCommissionBps\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"tRefund\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"tStale\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n {\n name: \"minPeginFeeRate\",\n type: \"uint64\",\n internalType: \"uint64\",\n },\n {\n name: \"proverCircuitVersion\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n {\n name: \"minPrepeginDepth\",\n type: \"uint32\",\n internalType: \"uint32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"latestOffchainParamsVersion\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getUniversalChallengersByVersion\",\n inputs: [\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentUniversalChallengers\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"latestUniversalChallengersVersion\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n] as const;\n","/**\n * ApplicationRegistry Contract ABI\n *\n * Minimal ABI containing only the vault keeper read functions needed by the SDK.\n * Generated from vault-contracts-aave-v4 IApplicationRegistry.sol interface.\n *\n * @module contracts/abis/ApplicationRegistry\n */\n\nexport const ApplicationRegistryABI = [\n {\n type: \"function\",\n name: \"getVaultKeepersByVersion\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"versionNumber\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentVaultKeepers\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n internalType: \"struct BTCVaultTypes.AddressBTCKeyPair[]\",\n components: [\n {\n name: \"ethAddress\",\n type: \"address\",\n internalType: \"address\",\n },\n {\n name: \"btcPubKey\",\n type: \"bytes32\",\n internalType: \"bytes32\",\n },\n ],\n },\n ],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"getCurrentVaultKeepersVersion\",\n inputs: [\n {\n name: \"appEntryPoint\",\n type: \"address\",\n internalType: \"address\",\n },\n ],\n outputs: [\n {\n name: \"\",\n type: \"uint16\",\n internalType: \"uint16\",\n },\n ],\n stateMutability: \"view\",\n },\n] as const;\n"],"names":["ProtocolParamsABI","ApplicationRegistryABI"],"mappings":"AASO,MAAMA,IAAoB;AAAA,EAC/B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAA;AAAA,IACR,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAA;AAAA,IACR,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAA;AAAA,IACR,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAA;AAAA,IACR,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAA;AAAA,IACR,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAErB,GCtSaC,IAAyB;AAAA,EACpC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,MAEhB;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,UAEhB;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,IAEF,iBAAiB;AAAA,EAAA;AAErB;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var T=Object.defineProperty;var B=(e,t,r)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var b=(e,t,r)=>B(e,typeof t!="symbol"?t+"":t,r);const v=require("bitcoinjs-lib"),g=require("./bitcoin-CHfKAhcI.cjs"),E=require("./sha2-DsrLC4NM.cjs");require("@babylonlabs-io/babylon-tbv-rust-wasm");const u=require("./verifyScriptPathSchnorrSignature-Cl7tu77P.cjs"),x=require("./signing-Bnsro0hE.cjs");function O(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const f=O(v),k=106,H=32,h=34;function R(e,t,r){const s=g.stripHexPrefix(e),c=f.Transaction.fromHex(s);if(c.outs.length<=t)throw new Error(`Pre-PegIn auth-anchor OP_RETURN missing: tx has ${c.outs.length} outputs, expected at least ${t+1} (vault outputs + OP_RETURN)`);const i=c.outs[t],o=i.script;if(o.length!==h||o[0]!==k||o[1]!==H)throw new Error(`Pre-PegIn auth-anchor OP_RETURN at vout ${t} has unexpected script encoding (got ${o.length}-byte script with prefix 0x${o.slice(0,Math.min(2,o.length)).toString("hex")}; expected ${h}-byte OP_RETURN + PUSH32 layout)`);const P=o.slice(2).toString("hex").toLowerCase();if(P!==r.toLowerCase())throw new Error(`Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${t}: tx pushes ${P}, expected ${r}`);if(i.value!==0)throw new Error(`Pre-PegIn auth-anchor OP_RETURN at vout ${t} has non-zero value ${i.value}; OP_RETURN outputs must be 0-value`)}function m(e){let t;try{t=f.Transaction.fromHex(g.stripHexPrefix(e))}catch{return}const r=[];for(let s=0;s<t.outs.length;s++){const c=t.outs[s],i=c.script;i.length===h&&i[0]===k&&i[1]===H&&c.value===0&&r.push({vout:s,hash:i.slice(2).toString("hex").toLowerCase()})}return r.length===1?r[0]:void 0}const y=66;function w(e){if(!e.startsWith("0x")&&!e.startsWith("0X"))throw new Error("Expected 0x-prefixed hex string");const t=e.slice(2);if(t.length%2!==0)throw new Error(`Hex string has odd length: ${t.length}`);if(!/^[0-9a-fA-F]*$/.test(t))throw new Error("Hex string contains non-hex characters");const r=new Uint8Array(t.length/2);for(let s=0;s<r.length;s++)r[s]=parseInt(t.slice(s*2,s*2+2),16);return r}function _(e){return`0x${Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}`}function p(e,t){if(e.length!==y)throw new Error(`${t} must be exactly 32 bytes (${y} hex chars with 0x prefix), got ${e.length}`)}function S(e){p(e,"Secret");const t=w(e),r=E.sha256(t);return _(r)}function $(e,t){return p(e,"Secret"),p(t,"Hashlock"),w(t),S(e).toLowerCase()===t.toLowerCase()}const d=0;class U{constructor(t){b(this,"config");this.config=t}async signPayoutTransaction(t){const r=await this.config.btcWallet.getPublicKeyHex(),{depositorPubkey:s}=g.validateWalletPubkey(r,t.depositorBtcPubkey),c=await u.buildPayoutPsbt({payoutTxHex:t.payoutTxHex,peginTxHex:t.peginTxHex,assertTxHex:t.assertTxHex,depositorBtcPubkey:s,vaultProviderBtcPubkey:t.vaultProviderBtcPubkey,vaultKeeperBtcPubkeys:t.vaultKeeperBtcPubkeys,universalChallengerBtcPubkeys:t.universalChallengerBtcPubkeys,timelockPegin:t.timelockPegin,network:this.config.network,claimerBtcPubkey:t.claimerBtcPubkey,registeredPayoutScriptPubKey:t.registeredPayoutScriptPubKey,commissionBps:t.commissionBps}),i=await this.config.btcWallet.signPsbt(c.psbtHex,x.createTaprootScriptPathSignOptions(r,1));u.assertPsbtUnsignedTxMatches({requestedPsbtHex:c.psbtHex,returnedPsbtHex:i});const o=u.extractPayoutSignature(i,s);return u.assertScriptPathSchnorrSignature({requestedPsbtHex:c.psbtHex,signatureHex:o,signerXOnlyPubkeyHex:s,inputIndex:d}),{signature:o,depositorBtcPubkey:s}}getNetwork(){return this.config.network}supportsBatchSigning(){return typeof this.config.btcWallet.signPsbts=="function"}async signPayoutTransactionsBatch(t){if(!this.supportsBatchSigning())throw new Error("Wallet does not support batch signing (signPsbts method not available)");const r=await this.config.btcWallet.getPublicKeyHex(),s=[],c=[],i=[];for(const n of t){const{depositorPubkey:a}=g.validateWalletPubkey(r,n.depositorBtcPubkey);i.push(a);const l=await u.buildPayoutPsbt({payoutTxHex:n.payoutTxHex,peginTxHex:n.peginTxHex,assertTxHex:n.assertTxHex,depositorBtcPubkey:a,vaultProviderBtcPubkey:n.vaultProviderBtcPubkey,vaultKeeperBtcPubkeys:n.vaultKeeperBtcPubkeys,universalChallengerBtcPubkeys:n.universalChallengerBtcPubkeys,timelockPegin:n.timelockPegin,network:this.config.network,claimerBtcPubkey:n.claimerBtcPubkey,registeredPayoutScriptPubKey:n.registeredPayoutScriptPubKey,commissionBps:n.commissionBps});s.push(l.psbtHex),c.push(x.createTaprootScriptPathSignOptions(r,1))}const o=await this.config.btcWallet.signPsbts(s,c);if(o.length!==t.length)throw new Error(`Expected ${t.length} signed PSBTs but received ${o.length}`);const P=[];for(let n=0;n<t.length;n++){const a=i[n];u.assertPsbtUnsignedTxMatches({requestedPsbtHex:s[n],returnedPsbtHex:o[n]});const l=u.extractPayoutSignature(o[n],a);u.assertScriptPathSchnorrSignature({requestedPsbtHex:s[n],signatureHex:l,signerXOnlyPubkeyHex:a,inputIndex:d}),P.push({payoutSignature:l,depositorBtcPubkey:a})}return P}}exports.PayoutManager=U;exports.assertAuthAnchorOpReturn=R;exports.computeHashlock=S;exports.findAuthAnchorOpReturn=m;exports.validateSecretAgainstHashlock=$;
|
|
2
|
-
//# sourceMappingURL=PayoutManager-BZVEyi10.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PayoutManager-BZVEyi10.cjs","sources":["../src/tbv/core/managers/pegin/assertAuthAnchorOpReturn.ts","../src/tbv/core/services/htlc/index.ts","../src/tbv/core/managers/PayoutManager.ts"],"sourcesContent":["/**\n * Structural verifier for the auth-anchor OP_RETURN in a funded\n * Pre-PegIn transaction.\n *\n * @module managers/pegin/assertAuthAnchorOpReturn\n */\n\nimport * as bitcoin from \"bitcoinjs-lib\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\n\n/** OP_RETURN opcode. */\nconst OP_RETURN = 0x6a;\n/** Push-32-bytes opcode (raw push, not OP_PUSHDATA1). */\nconst OP_PUSH32 = 0x20;\n/** Encoded length of a standard OP_RETURN script with a 32-byte payload. */\nconst OP_RETURN_PUSH32_SCRIPT_LEN = 1 + 1 + 32;\n\n/**\n * Verify the broadcast Pre-PegIn carries the expected OP_RETURN\n * commitment to the auth anchor.\n *\n * The OP_RETURN sits at `vout = vaultCount` (right after the per-vault\n * HTLC outputs and before the depositor-claim/change outputs) and\n * pushes the 32-byte `SHA256(authAnchor)`. The script encoding is\n * exactly `OP_RETURN || PUSH32 || <32 bytes>` (34 bytes). A\n * non-conformant WASM build that omitted the OP_RETURN, swapped its\n * position, or changed its push payload would let the depositor\n * obtain a valid bearer token for a Pre-PegIn whose on-chain\n * commitment doesn't actually bind the anchor — degrading the auth\n * from on-chain-bound to a shared secret. Fail closed.\n *\n * @throws If the OP_RETURN is missing, mis-located, mis-encoded, or\n * pushes a payload other than `expectedAuthAnchorHashHex`.\n */\nexport function assertAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n vaultCount: number,\n expectedAuthAnchorHashHex: string,\n): void {\n const cleanHex = stripHexPrefix(fundedPrePeginTxHex);\n const tx = bitcoin.Transaction.fromHex(cleanHex);\n\n if (tx.outs.length <= vaultCount) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN missing: tx has ${tx.outs.length} ` +\n `outputs, expected at least ${vaultCount + 1} (vault outputs + OP_RETURN)`,\n );\n }\n\n const opReturnOutput = tx.outs[vaultCount];\n const script = opReturnOutput.script;\n if (\n script.length !== OP_RETURN_PUSH32_SCRIPT_LEN ||\n script[0] !== OP_RETURN ||\n script[1] !== OP_PUSH32\n ) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has unexpected ` +\n `script encoding (got ${script.length}-byte script with prefix ` +\n `0x${script.slice(0, Math.min(2, script.length)).toString(\"hex\")}; ` +\n `expected ${OP_RETURN_PUSH32_SCRIPT_LEN}-byte OP_RETURN + PUSH32 layout)`,\n );\n }\n\n const pushedHex = script.slice(2).toString(\"hex\").toLowerCase();\n if (pushedHex !== expectedAuthAnchorHashHex.toLowerCase()) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${vaultCount}: ` +\n `tx pushes ${pushedHex}, expected ${expectedAuthAnchorHashHex}`,\n );\n }\n\n if (opReturnOutput.value !== 0) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has non-zero ` +\n `value ${opReturnOutput.value}; OP_RETURN outputs must be 0-value`,\n );\n }\n}\n\n/**\n * Scan a funded Pre-PegIn transaction for its auth-anchor commitment\n * (an `OP_RETURN || PUSH32 || <32 bytes>` output with value 0).\n *\n * Returns `{ vout, hash }` when exactly one such output is found.\n * Returns `undefined` when:\n * - the hex is unparseable,\n * - no matching output exists (legacy non-auth-anchored Pre-PegIn),\n * - more than one matching output exists (ambiguous / malformed).\n *\n * Used by the refund orchestrator to (a) locate the on-chain anchor\n * regardless of how many HTLCs preceded it and (b) detect multi-vault\n * funded transactions structurally: the single-vault refund path\n * reconstructs only one hashlock and expects the anchor at vout 1, so\n * any other vout signals a layout this call cannot safely refund.\n */\nexport function findAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n): { vout: number; hash: string } | undefined {\n let tx: bitcoin.Transaction;\n try {\n tx = bitcoin.Transaction.fromHex(stripHexPrefix(fundedPrePeginTxHex));\n } catch {\n return undefined;\n }\n\n const hits: { vout: number; hash: string }[] = [];\n for (let i = 0; i < tx.outs.length; i++) {\n const output = tx.outs[i];\n const script = output.script;\n if (\n script.length === OP_RETURN_PUSH32_SCRIPT_LEN &&\n script[0] === OP_RETURN &&\n script[1] === OP_PUSH32 &&\n output.value === 0\n ) {\n hits.push({\n vout: i,\n hash: script.slice(2).toString(\"hex\").toLowerCase(),\n });\n }\n }\n\n return hits.length === 1 ? hits[0] : undefined;\n}\n","/**\n * HTLC Secret / Hashlock Utilities\n *\n * Pure functions for computing and validating SHA-256 hashlocks used in the\n * vault deposit protocol's HTLC (Hash Time Lock Contract).\n *\n * The SDK does NOT generate secrets — that is the caller's responsibility.\n * Today callers use `crypto.getRandomValues(32)`; when the `deriveContextHash`\n * wallet API ships, callers will use `wallet.deriveContextHash(\"babylon-btc-vault\", ctx)`.\n * These utilities work identically regardless of how the secret was produced.\n *\n * On-chain contract validation (BTCVaultRegistry.activateVaultWithSecret):\n * if (sha256(abi.encodePacked(s)) != hashlock) revert InvalidSecret();\n *\n * @module htlc\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport type { Hex } from \"viem\";\n\n/** Expected hex length for a 0x-prefixed bytes32 value. */\nconst HEX_BYTES32_LENGTH = 66; // \"0x\" + 64 hex chars\n\n/**\n * Decode a 0x-prefixed hex string to bytes, with strict validation.\n * @throws if the input is not a valid 0x-prefixed hex string\n */\nfunction hexToBytes(hex: Hex): Uint8Array {\n if (!hex.startsWith(\"0x\") && !hex.startsWith(\"0X\")) {\n throw new Error(\"Expected 0x-prefixed hex string\");\n }\n const clean = hex.slice(2);\n if (clean.length % 2 !== 0) {\n throw new Error(`Hex string has odd length: ${clean.length}`);\n }\n if (!/^[0-9a-fA-F]*$/.test(clean)) {\n throw new Error(\"Hex string contains non-hex characters\");\n }\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Encode a Uint8Array as a 0x-prefixed lowercase hex string.\n */\nfunction bytesToHex(bytes: Uint8Array): Hex {\n return `0x${Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\n/**\n * Validate that a value is a 0x-prefixed bytes32 (exactly 32 bytes).\n * @throws if the value is not exactly 32 bytes\n */\nfunction assertBytes32(value: Hex, label: string): void {\n if (value.length !== HEX_BYTES32_LENGTH) {\n throw new Error(\n `${label} must be exactly 32 bytes (${HEX_BYTES32_LENGTH} hex chars with 0x prefix), got ${value.length}`,\n );\n }\n}\n\n/**\n * Compute the SHA-256 hashlock from a secret preimage.\n *\n * Matches the on-chain validation: `sha256(abi.encodePacked(s))` where `s` is a `bytes32`.\n * `abi.encodePacked(bytes32)` is just the raw 32 bytes — no ABI padding.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @returns 0x-prefixed bytes32 SHA-256 hash\n * @throws if secret is not exactly 32 bytes\n */\nexport function computeHashlock(secret: Hex): Hex {\n assertBytes32(secret, \"Secret\");\n const secretBytes = hexToBytes(secret);\n const hash = sha256(secretBytes);\n return bytesToHex(hash);\n}\n\n/**\n * Validate that a secret's SHA-256 hash matches the expected hashlock.\n *\n * Use this for client-side pre-validation before sending the activation\n * transaction to avoid wasting gas on a contract revert.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @param hashlock - 0x-prefixed bytes32 expected hashlock from the vault\n * @returns true if SHA-256(secret) matches the hashlock\n * @throws if secret or hashlock is not exactly 32 bytes\n */\nexport function validateSecretAgainstHashlock(\n secret: Hex,\n hashlock: Hex,\n): boolean {\n assertBytes32(secret, \"Secret\");\n assertBytes32(hashlock, \"Hashlock\");\n // Validate hashlock is valid hex (secret is validated inside computeHashlock)\n hexToBytes(hashlock);\n\n const computed = computeHashlock(secret);\n return computed.toLowerCase() === hashlock.toLowerCase();\n}\n","/**\n * Payout Manager\n *\n * High-level manager that orchestrates the payout signing flow by coordinating\n * SDK primitives ({@link buildPayoutPsbt}, {@link extractPayoutSignature})\n * with a user-provided Bitcoin wallet.\n *\n * The Payout transaction references the Assert transaction (input 1).\n *\n * @see {@link PeginManager} - For Steps 1–4 of the peg-in flow\n * @see {@link buildPayoutPsbt} - Lower-level primitive for custom implementations\n * @see {@link extractPayoutSignature} - Extract signatures from signed PSBTs\n *\n * @module managers/PayoutManager\n */\n\nimport type { BitcoinWallet, SignPsbtOptions } from \"../../../shared/wallets\";\nimport {\n assertPsbtUnsignedTxMatches,\n assertScriptPathSchnorrSignature,\n buildPayoutPsbt,\n extractPayoutSignature,\n validateWalletPubkey,\n type Network,\n} from \"../primitives\";\nimport { createTaprootScriptPathSignOptions } from \"../utils/signing\";\n\n/** Payout PSBTs are signed by the depositor on input 0 (Taproot script-path). */\nconst PAYOUT_SIGNED_INPUT_INDEX = 0;\n\n/**\n * Configuration for the PayoutManager.\n */\nexport interface PayoutManagerConfig {\n /**\n * Bitcoin network to use for transactions.\n */\n network: Network;\n\n /**\n * Bitcoin wallet for signing payout transactions.\n */\n btcWallet: BitcoinWallet;\n}\n\n/**\n * Base parameters shared by both payout transaction types.\n */\ninterface SignPayoutBaseParams {\n /**\n * Peg-in transaction hex.\n * The original transaction that created the vault output being spent.\n */\n peginTxHex: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex).\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex).\n */\n vaultKeeperBtcPubkeys: string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex).\n */\n universalChallengerBtcPubkeys: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex). This MUST be the\n * key registered on-chain for the vault — typically read from\n * `BTCVaultRegistry.getBtcVaultBasicInfo(...).depositorBtcPubKey`.\n *\n * Required: omitting it would degrade `validateWalletPubkey` to a\n * self-comparison, allowing the wrong wallet to produce a signature\n * over a script tree that doesn't match the on-chain UTXO.\n */\n depositorBtcPubkey: string;\n\n /**\n * The on-chain registered depositor payout scriptPubKey (hex, with or without 0x prefix).\n * Used to validate that the VP-provided payout transaction actually pays to the\n * correct depositor payout address before signing.\n */\n registeredPayoutScriptPubKey: string;\n\n /**\n * The claimer's x-only BTC public key for this payout (64-char hex, no prefix).\n * Forwarded to {@link buildPayoutPsbt} for per-role output validation.\n */\n claimerBtcPubkey: string;\n\n /**\n * VP commission in basis points (`1..=9999`). Forwarded to {@link buildPayoutPsbt}.\n */\n commissionBps: number;\n}\n\n/**\n * Parameters for signing a Payout transaction.\n *\n * Payout is used in the challenge path after Assert, when the claimer proves validity.\n * Input 1 references the Assert transaction.\n */\nexport interface SignPayoutParams extends SignPayoutBaseParams {\n /**\n * Payout transaction hex (unsigned).\n * This is the transaction from the vault provider that needs depositor signature.\n */\n payoutTxHex: string;\n\n /**\n * Assert transaction hex.\n * Payout input 1 references Assert output 0.\n */\n assertTxHex: string;\n}\n\n/**\n * Result of signing a payout transaction.\n */\nexport interface PayoutSignatureResult {\n /**\n * 64-byte Schnorr signature (128 hex characters).\n */\n signature: string;\n\n /**\n * Depositor's BTC public key used for signing.\n */\n depositorBtcPubkey: string;\n}\n\n/**\n * High-level manager for payout transaction signing.\n *\n * @remarks\n * After registering your peg-in on Ethereum (Step 3), the vault provider prepares\n * claim/payout transaction pairs. You must sign each payout transaction using this\n * manager and submit the signatures to the vault provider's RPC API.\n *\n * **What happens internally:**\n * 1. Validates your wallet's public key matches the vault's depositor\n * 2. Builds an unsigned PSBT with taproot script path spend info\n * 3. Signs input 0 (the vault UTXO) with your wallet\n * 4. Extracts the 64-byte Schnorr signature\n *\n * **Note:** The payout transaction has 2 inputs. PayoutManager only signs input 0\n * (from the peg-in tx). Input 1 (from the assert tx) is signed by the vault provider.\n *\n * @see {@link PeginManager} - For the complete peg-in flow context\n * @see {@link buildPayoutPsbt} - Lower-level primitive used internally\n * @see {@link extractPayoutSignature} - Signature extraction primitive\n */\nexport class PayoutManager {\n private readonly config: PayoutManagerConfig;\n\n /**\n * Creates a new PayoutManager instance.\n *\n * @param config - Manager configuration including wallet\n */\n constructor(config: PayoutManagerConfig) {\n this.config = config;\n }\n\n /**\n * Signs a Payout transaction and extracts the Schnorr signature.\n *\n * Flow:\n * 1. Vault provider submits Claim transaction\n * 2. Claimer submits Assert transaction to prove validity\n * 3. Payout can be executed (references Assert tx)\n *\n * This method orchestrates the following steps:\n * 1. Get wallet's public key and convert to x-only format\n * 2. Validate wallet pubkey matches on-chain depositor pubkey (if provided)\n * 3. Build unsigned PSBT using primitives\n * 4. Sign PSBT via btcWallet.signPsbt()\n * 5. Extract 64-byte Schnorr signature using primitives\n *\n * The returned signature can be submitted to the vault provider API.\n *\n * @param params - Payout signing parameters\n * @returns Signature result with 64-byte Schnorr signature and depositor pubkey\n * @throws Error if wallet pubkey doesn't match depositor pubkey\n * @throws Error if wallet operations fail or signature extraction fails\n */\n async signPayoutTransaction(\n params: SignPayoutParams,\n ): Promise<PayoutSignatureResult> {\n // Validate wallet pubkey matches depositor and get both formats\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n params.depositorBtcPubkey,\n );\n\n // Build unsigned PSBT for Payout (uses Assert tx). Per-role output\n // validation happens inside buildPayoutPsbt against the resolved input\n // values.\n const payoutPsbt = await buildPayoutPsbt({\n payoutTxHex: params.payoutTxHex,\n peginTxHex: params.peginTxHex,\n assertTxHex: params.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: params.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: params.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: params.universalChallengerBtcPubkeys,\n timelockPegin: params.timelockPegin,\n network: this.config.network,\n claimerBtcPubkey: params.claimerBtcPubkey,\n registeredPayoutScriptPubKey: params.registeredPayoutScriptPubKey,\n commissionBps: params.commissionBps,\n });\n\n // Sign PSBT via wallet (Taproot script-path spend, input 0 only)\n const signedPsbtHex = await this.config.btcWallet.signPsbt(\n payoutPsbt.psbtHex,\n createTaprootScriptPathSignOptions(walletPubkeyRaw, 1),\n );\n\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: payoutPsbt.psbtHex,\n returnedPsbtHex: signedPsbtHex,\n });\n\n // Extract Schnorr signature\n const signature = extractPayoutSignature(signedPsbtHex, depositorPubkey);\n // Critical Path #7: verify the signature against a sighash recomputed from\n // the PSBT we built, not the wallet-returned one.\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: payoutPsbt.psbtHex,\n signatureHex: signature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n return {\n signature,\n depositorBtcPubkey: depositorPubkey,\n };\n }\n\n /**\n * Gets the configured Bitcoin network.\n *\n * @returns The Bitcoin network (mainnet, testnet, signet, regtest)\n */\n getNetwork(): Network {\n return this.config.network;\n }\n\n /**\n * Checks if the wallet supports batch signing (signPsbts).\n *\n * @returns true if batch signing is supported\n */\n supportsBatchSigning(): boolean {\n return typeof this.config.btcWallet.signPsbts === \"function\";\n }\n\n /**\n * Batch signs multiple payout transactions (1 per claimer).\n * This allows signing all transactions with a single wallet interaction.\n *\n * @param transactions - Array of payout params to sign\n * @returns Array of signature results matching input order\n * @throws Error if wallet doesn't support batch signing\n * @throws Error if any signing operation fails\n */\n async signPayoutTransactionsBatch(transactions: SignPayoutParams[]): Promise<\n Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }>\n > {\n if (!this.supportsBatchSigning()) {\n throw new Error(\n \"Wallet does not support batch signing (signPsbts method not available)\",\n );\n }\n\n // Get wallet pubkey once\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n\n // Build all PSBTs (1 per claimer)\n const psbtsToSign: string[] = [];\n const signOptions: SignPsbtOptions[] = [];\n const depositorPubkeys: string[] = [];\n\n for (const tx of transactions) {\n // Validate wallet pubkey matches depositor\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n tx.depositorBtcPubkey,\n );\n depositorPubkeys.push(depositorPubkey);\n\n // Build Payout PSBT (output validation runs inside buildPayoutPsbt\n // against resolved input values).\n const payoutPsbt = await buildPayoutPsbt({\n payoutTxHex: tx.payoutTxHex,\n peginTxHex: tx.peginTxHex,\n assertTxHex: tx.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: tx.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: tx.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: tx.universalChallengerBtcPubkeys,\n timelockPegin: tx.timelockPegin,\n network: this.config.network,\n claimerBtcPubkey: tx.claimerBtcPubkey,\n registeredPayoutScriptPubKey: tx.registeredPayoutScriptPubKey,\n commissionBps: tx.commissionBps,\n });\n psbtsToSign.push(payoutPsbt.psbtHex);\n signOptions.push(createTaprootScriptPathSignOptions(walletPubkeyRaw, 1));\n }\n\n // Batch sign all PSBTs with single wallet interaction\n const signedPsbts = await this.config.btcWallet.signPsbts!(\n psbtsToSign,\n signOptions,\n );\n\n // Validate that wallet returned the expected number of signed PSBTs\n if (signedPsbts.length !== transactions.length) {\n throw new Error(\n `Expected ${transactions.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n\n // Extract signatures from signed PSBTs\n const results: Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }> = [];\n\n for (let i = 0; i < transactions.length; i++) {\n const depositorPubkey = depositorPubkeys[i];\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: psbtsToSign[i],\n returnedPsbtHex: signedPsbts[i],\n });\n const payoutSignature = extractPayoutSignature(\n signedPsbts[i],\n depositorPubkey,\n );\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: psbtsToSign[i],\n signatureHex: payoutSignature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n results.push({\n payoutSignature,\n depositorBtcPubkey: depositorPubkey,\n });\n }\n\n return results;\n }\n}\n"],"names":["OP_RETURN","OP_PUSH32","OP_RETURN_PUSH32_SCRIPT_LEN","assertAuthAnchorOpReturn","fundedPrePeginTxHex","vaultCount","expectedAuthAnchorHashHex","cleanHex","stripHexPrefix","tx","bitcoin","opReturnOutput","script","pushedHex","findAuthAnchorOpReturn","hits","i","output","HEX_BYTES32_LENGTH","hexToBytes","hex","clean","bytes","bytesToHex","b","assertBytes32","value","label","computeHashlock","secret","secretBytes","hash","sha256","validateSecretAgainstHashlock","hashlock","PAYOUT_SIGNED_INPUT_INDEX","PayoutManager","config","__publicField","params","walletPubkeyRaw","depositorPubkey","validateWalletPubkey","payoutPsbt","buildPayoutPsbt","signedPsbtHex","createTaprootScriptPathSignOptions","assertPsbtUnsignedTxMatches","signature","extractPayoutSignature","assertScriptPathSchnorrSignature","transactions","psbtsToSign","signOptions","depositorPubkeys","signedPsbts","results","payoutSignature"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PayoutManager-D26nGR-e.js","sources":["../src/tbv/core/managers/pegin/assertAuthAnchorOpReturn.ts","../src/tbv/core/services/htlc/index.ts","../src/tbv/core/managers/PayoutManager.ts"],"sourcesContent":["/**\n * Structural verifier for the auth-anchor OP_RETURN in a funded\n * Pre-PegIn transaction.\n *\n * @module managers/pegin/assertAuthAnchorOpReturn\n */\n\nimport * as bitcoin from \"bitcoinjs-lib\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\n\n/** OP_RETURN opcode. */\nconst OP_RETURN = 0x6a;\n/** Push-32-bytes opcode (raw push, not OP_PUSHDATA1). */\nconst OP_PUSH32 = 0x20;\n/** Encoded length of a standard OP_RETURN script with a 32-byte payload. */\nconst OP_RETURN_PUSH32_SCRIPT_LEN = 1 + 1 + 32;\n\n/**\n * Verify the broadcast Pre-PegIn carries the expected OP_RETURN\n * commitment to the auth anchor.\n *\n * The OP_RETURN sits at `vout = vaultCount` (right after the per-vault\n * HTLC outputs and before the depositor-claim/change outputs) and\n * pushes the 32-byte `SHA256(authAnchor)`. The script encoding is\n * exactly `OP_RETURN || PUSH32 || <32 bytes>` (34 bytes). A\n * non-conformant WASM build that omitted the OP_RETURN, swapped its\n * position, or changed its push payload would let the depositor\n * obtain a valid bearer token for a Pre-PegIn whose on-chain\n * commitment doesn't actually bind the anchor — degrading the auth\n * from on-chain-bound to a shared secret. Fail closed.\n *\n * @throws If the OP_RETURN is missing, mis-located, mis-encoded, or\n * pushes a payload other than `expectedAuthAnchorHashHex`.\n */\nexport function assertAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n vaultCount: number,\n expectedAuthAnchorHashHex: string,\n): void {\n const cleanHex = stripHexPrefix(fundedPrePeginTxHex);\n const tx = bitcoin.Transaction.fromHex(cleanHex);\n\n if (tx.outs.length <= vaultCount) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN missing: tx has ${tx.outs.length} ` +\n `outputs, expected at least ${vaultCount + 1} (vault outputs + OP_RETURN)`,\n );\n }\n\n const opReturnOutput = tx.outs[vaultCount];\n const script = opReturnOutput.script;\n if (\n script.length !== OP_RETURN_PUSH32_SCRIPT_LEN ||\n script[0] !== OP_RETURN ||\n script[1] !== OP_PUSH32\n ) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has unexpected ` +\n `script encoding (got ${script.length}-byte script with prefix ` +\n `0x${script.slice(0, Math.min(2, script.length)).toString(\"hex\")}; ` +\n `expected ${OP_RETURN_PUSH32_SCRIPT_LEN}-byte OP_RETURN + PUSH32 layout)`,\n );\n }\n\n const pushedHex = script.slice(2).toString(\"hex\").toLowerCase();\n if (pushedHex !== expectedAuthAnchorHashHex.toLowerCase()) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${vaultCount}: ` +\n `tx pushes ${pushedHex}, expected ${expectedAuthAnchorHashHex}`,\n );\n }\n\n if (opReturnOutput.value !== 0) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has non-zero ` +\n `value ${opReturnOutput.value}; OP_RETURN outputs must be 0-value`,\n );\n }\n}\n\n/**\n * Scan a funded Pre-PegIn transaction for its auth-anchor commitment\n * (an `OP_RETURN || PUSH32 || <32 bytes>` output with value 0).\n *\n * Returns `{ vout, hash }` when exactly one such output is found.\n * Returns `undefined` when:\n * - the hex is unparseable,\n * - no matching output exists (legacy non-auth-anchored Pre-PegIn),\n * - more than one matching output exists (ambiguous / malformed).\n *\n * Used by the refund orchestrator to (a) locate the on-chain anchor\n * regardless of how many HTLCs preceded it and (b) detect multi-vault\n * funded transactions structurally: the single-vault refund path\n * reconstructs only one hashlock and expects the anchor at vout 1, so\n * any other vout signals a layout this call cannot safely refund.\n */\nexport function findAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n): { vout: number; hash: string } | undefined {\n let tx: bitcoin.Transaction;\n try {\n tx = bitcoin.Transaction.fromHex(stripHexPrefix(fundedPrePeginTxHex));\n } catch {\n return undefined;\n }\n\n const hits: { vout: number; hash: string }[] = [];\n for (let i = 0; i < tx.outs.length; i++) {\n const output = tx.outs[i];\n const script = output.script;\n if (\n script.length === OP_RETURN_PUSH32_SCRIPT_LEN &&\n script[0] === OP_RETURN &&\n script[1] === OP_PUSH32 &&\n output.value === 0\n ) {\n hits.push({\n vout: i,\n hash: script.slice(2).toString(\"hex\").toLowerCase(),\n });\n }\n }\n\n return hits.length === 1 ? hits[0] : undefined;\n}\n","/**\n * HTLC Secret / Hashlock Utilities\n *\n * Pure functions for computing and validating SHA-256 hashlocks used in the\n * vault deposit protocol's HTLC (Hash Time Lock Contract).\n *\n * The SDK does NOT generate secrets — that is the caller's responsibility.\n * Today callers use `crypto.getRandomValues(32)`; when the `deriveContextHash`\n * wallet API ships, callers will use `wallet.deriveContextHash(\"babylon-btc-vault\", ctx)`.\n * These utilities work identically regardless of how the secret was produced.\n *\n * On-chain contract validation (BTCVaultRegistry.activateVaultWithSecret):\n * if (sha256(abi.encodePacked(s)) != hashlock) revert InvalidSecret();\n *\n * @module htlc\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport type { Hex } from \"viem\";\n\n/** Expected hex length for a 0x-prefixed bytes32 value. */\nconst HEX_BYTES32_LENGTH = 66; // \"0x\" + 64 hex chars\n\n/**\n * Decode a 0x-prefixed hex string to bytes, with strict validation.\n * @throws if the input is not a valid 0x-prefixed hex string\n */\nfunction hexToBytes(hex: Hex): Uint8Array {\n if (!hex.startsWith(\"0x\") && !hex.startsWith(\"0X\")) {\n throw new Error(\"Expected 0x-prefixed hex string\");\n }\n const clean = hex.slice(2);\n if (clean.length % 2 !== 0) {\n throw new Error(`Hex string has odd length: ${clean.length}`);\n }\n if (!/^[0-9a-fA-F]*$/.test(clean)) {\n throw new Error(\"Hex string contains non-hex characters\");\n }\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Encode a Uint8Array as a 0x-prefixed lowercase hex string.\n */\nfunction bytesToHex(bytes: Uint8Array): Hex {\n return `0x${Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\n/**\n * Validate that a value is a 0x-prefixed bytes32 (exactly 32 bytes).\n * @throws if the value is not exactly 32 bytes\n */\nfunction assertBytes32(value: Hex, label: string): void {\n if (value.length !== HEX_BYTES32_LENGTH) {\n throw new Error(\n `${label} must be exactly 32 bytes (${HEX_BYTES32_LENGTH} hex chars with 0x prefix), got ${value.length}`,\n );\n }\n}\n\n/**\n * Compute the SHA-256 hashlock from a secret preimage.\n *\n * Matches the on-chain validation: `sha256(abi.encodePacked(s))` where `s` is a `bytes32`.\n * `abi.encodePacked(bytes32)` is just the raw 32 bytes — no ABI padding.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @returns 0x-prefixed bytes32 SHA-256 hash\n * @throws if secret is not exactly 32 bytes\n */\nexport function computeHashlock(secret: Hex): Hex {\n assertBytes32(secret, \"Secret\");\n const secretBytes = hexToBytes(secret);\n const hash = sha256(secretBytes);\n return bytesToHex(hash);\n}\n\n/**\n * Validate that a secret's SHA-256 hash matches the expected hashlock.\n *\n * Use this for client-side pre-validation before sending the activation\n * transaction to avoid wasting gas on a contract revert.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @param hashlock - 0x-prefixed bytes32 expected hashlock from the vault\n * @returns true if SHA-256(secret) matches the hashlock\n * @throws if secret or hashlock is not exactly 32 bytes\n */\nexport function validateSecretAgainstHashlock(\n secret: Hex,\n hashlock: Hex,\n): boolean {\n assertBytes32(secret, \"Secret\");\n assertBytes32(hashlock, \"Hashlock\");\n // Validate hashlock is valid hex (secret is validated inside computeHashlock)\n hexToBytes(hashlock);\n\n const computed = computeHashlock(secret);\n return computed.toLowerCase() === hashlock.toLowerCase();\n}\n","/**\n * Payout Manager\n *\n * High-level manager that orchestrates the payout signing flow by coordinating\n * SDK primitives ({@link buildPayoutPsbt}, {@link extractPayoutSignature})\n * with a user-provided Bitcoin wallet.\n *\n * The Payout transaction references the Assert transaction (input 1).\n *\n * @see {@link PeginManager} - For Steps 1–4 of the peg-in flow\n * @see {@link buildPayoutPsbt} - Lower-level primitive for custom implementations\n * @see {@link extractPayoutSignature} - Extract signatures from signed PSBTs\n *\n * @module managers/PayoutManager\n */\n\nimport type { BitcoinWallet, SignPsbtOptions } from \"../../../shared/wallets\";\nimport {\n assertPsbtUnsignedTxMatches,\n assertScriptPathSchnorrSignature,\n buildPayoutPsbt,\n extractPayoutSignature,\n validateWalletPubkey,\n type Network,\n} from \"../primitives\";\nimport { createTaprootScriptPathSignOptions } from \"../utils/signing\";\n\n/** Payout PSBTs are signed by the depositor on input 0 (Taproot script-path). */\nconst PAYOUT_SIGNED_INPUT_INDEX = 0;\n\n/**\n * Configuration for the PayoutManager.\n */\nexport interface PayoutManagerConfig {\n /**\n * Bitcoin network to use for transactions.\n */\n network: Network;\n\n /**\n * Bitcoin wallet for signing payout transactions.\n */\n btcWallet: BitcoinWallet;\n}\n\n/**\n * Base parameters shared by both payout transaction types.\n */\ninterface SignPayoutBaseParams {\n /**\n * Peg-in transaction hex.\n * The original transaction that created the vault output being spent.\n */\n peginTxHex: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex).\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex).\n */\n vaultKeeperBtcPubkeys: string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex).\n */\n universalChallengerBtcPubkeys: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex). This MUST be the\n * key registered on-chain for the vault — typically read from\n * `BTCVaultRegistry.getBtcVaultBasicInfo(...).depositorBtcPubKey`.\n *\n * Required: omitting it would degrade `validateWalletPubkey` to a\n * self-comparison, allowing the wrong wallet to produce a signature\n * over a script tree that doesn't match the on-chain UTXO.\n */\n depositorBtcPubkey: string;\n\n /**\n * The on-chain registered depositor payout scriptPubKey (hex, with or without 0x prefix).\n * Used to validate that the VP-provided payout transaction actually pays to the\n * correct depositor payout address before signing.\n */\n registeredPayoutScriptPubKey: string;\n\n /**\n * The claimer's x-only BTC public key for this payout (64-char hex, no prefix).\n * Forwarded to {@link buildPayoutPsbt} for per-role output validation.\n */\n claimerBtcPubkey: string;\n\n /**\n * VP commission in basis points (`1..=9999`). Forwarded to {@link buildPayoutPsbt}.\n */\n commissionBps: number;\n}\n\n/**\n * Parameters for signing a Payout transaction.\n *\n * Payout is used in the challenge path after Assert, when the claimer proves validity.\n * Input 1 references the Assert transaction.\n */\nexport interface SignPayoutParams extends SignPayoutBaseParams {\n /**\n * Payout transaction hex (unsigned).\n * This is the transaction from the vault provider that needs depositor signature.\n */\n payoutTxHex: string;\n\n /**\n * Assert transaction hex.\n * Payout input 1 references Assert output 0.\n */\n assertTxHex: string;\n}\n\n/**\n * Result of signing a payout transaction.\n */\nexport interface PayoutSignatureResult {\n /**\n * 64-byte Schnorr signature (128 hex characters).\n */\n signature: string;\n\n /**\n * Depositor's BTC public key used for signing.\n */\n depositorBtcPubkey: string;\n}\n\n/**\n * High-level manager for payout transaction signing.\n *\n * @remarks\n * After registering your peg-in on Ethereum (Step 3), the vault provider prepares\n * claim/payout transaction pairs. You must sign each payout transaction using this\n * manager and submit the signatures to the vault provider's RPC API.\n *\n * **What happens internally:**\n * 1. Validates your wallet's public key matches the vault's depositor\n * 2. Builds an unsigned PSBT with taproot script path spend info\n * 3. Signs input 0 (the vault UTXO) with your wallet\n * 4. Extracts the 64-byte Schnorr signature\n *\n * **Note:** The payout transaction has 2 inputs. PayoutManager only signs input 0\n * (from the peg-in tx). Input 1 (from the assert tx) is signed by the vault provider.\n *\n * @see {@link PeginManager} - For the complete peg-in flow context\n * @see {@link buildPayoutPsbt} - Lower-level primitive used internally\n * @see {@link extractPayoutSignature} - Signature extraction primitive\n */\nexport class PayoutManager {\n private readonly config: PayoutManagerConfig;\n\n /**\n * Creates a new PayoutManager instance.\n *\n * @param config - Manager configuration including wallet\n */\n constructor(config: PayoutManagerConfig) {\n this.config = config;\n }\n\n /**\n * Signs a Payout transaction and extracts the Schnorr signature.\n *\n * Flow:\n * 1. Vault provider submits Claim transaction\n * 2. Claimer submits Assert transaction to prove validity\n * 3. Payout can be executed (references Assert tx)\n *\n * This method orchestrates the following steps:\n * 1. Get wallet's public key and convert to x-only format\n * 2. Validate wallet pubkey matches on-chain depositor pubkey (if provided)\n * 3. Build unsigned PSBT using primitives\n * 4. Sign PSBT via btcWallet.signPsbt()\n * 5. Extract 64-byte Schnorr signature using primitives\n *\n * The returned signature can be submitted to the vault provider API.\n *\n * @param params - Payout signing parameters\n * @returns Signature result with 64-byte Schnorr signature and depositor pubkey\n * @throws Error if wallet pubkey doesn't match depositor pubkey\n * @throws Error if wallet operations fail or signature extraction fails\n */\n async signPayoutTransaction(\n params: SignPayoutParams,\n ): Promise<PayoutSignatureResult> {\n // Validate wallet pubkey matches depositor and get both formats\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n params.depositorBtcPubkey,\n );\n\n // Build unsigned PSBT for Payout (uses Assert tx). Per-role output\n // validation happens inside buildPayoutPsbt against the resolved input\n // values.\n const payoutPsbt = await buildPayoutPsbt({\n payoutTxHex: params.payoutTxHex,\n peginTxHex: params.peginTxHex,\n assertTxHex: params.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: params.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: params.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: params.universalChallengerBtcPubkeys,\n timelockPegin: params.timelockPegin,\n network: this.config.network,\n claimerBtcPubkey: params.claimerBtcPubkey,\n registeredPayoutScriptPubKey: params.registeredPayoutScriptPubKey,\n commissionBps: params.commissionBps,\n });\n\n // Sign PSBT via wallet (Taproot script-path spend, input 0 only)\n const signedPsbtHex = await this.config.btcWallet.signPsbt(\n payoutPsbt.psbtHex,\n createTaprootScriptPathSignOptions(walletPubkeyRaw, 1),\n );\n\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: payoutPsbt.psbtHex,\n returnedPsbtHex: signedPsbtHex,\n });\n\n // Extract Schnorr signature\n const signature = extractPayoutSignature(signedPsbtHex, depositorPubkey);\n // Critical Path #7: verify the signature against a sighash recomputed from\n // the PSBT we built, not the wallet-returned one.\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: payoutPsbt.psbtHex,\n signatureHex: signature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n return {\n signature,\n depositorBtcPubkey: depositorPubkey,\n };\n }\n\n /**\n * Gets the configured Bitcoin network.\n *\n * @returns The Bitcoin network (mainnet, testnet, signet, regtest)\n */\n getNetwork(): Network {\n return this.config.network;\n }\n\n /**\n * Checks if the wallet supports batch signing (signPsbts).\n *\n * @returns true if batch signing is supported\n */\n supportsBatchSigning(): boolean {\n return typeof this.config.btcWallet.signPsbts === \"function\";\n }\n\n /**\n * Batch signs multiple payout transactions (1 per claimer).\n * This allows signing all transactions with a single wallet interaction.\n *\n * @param transactions - Array of payout params to sign\n * @returns Array of signature results matching input order\n * @throws Error if wallet doesn't support batch signing\n * @throws Error if any signing operation fails\n */\n async signPayoutTransactionsBatch(transactions: SignPayoutParams[]): Promise<\n Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }>\n > {\n if (!this.supportsBatchSigning()) {\n throw new Error(\n \"Wallet does not support batch signing (signPsbts method not available)\",\n );\n }\n\n // Get wallet pubkey once\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n\n // Build all PSBTs (1 per claimer)\n const psbtsToSign: string[] = [];\n const signOptions: SignPsbtOptions[] = [];\n const depositorPubkeys: string[] = [];\n\n for (const tx of transactions) {\n // Validate wallet pubkey matches depositor\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n tx.depositorBtcPubkey,\n );\n depositorPubkeys.push(depositorPubkey);\n\n // Build Payout PSBT (output validation runs inside buildPayoutPsbt\n // against resolved input values).\n const payoutPsbt = await buildPayoutPsbt({\n payoutTxHex: tx.payoutTxHex,\n peginTxHex: tx.peginTxHex,\n assertTxHex: tx.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: tx.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: tx.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: tx.universalChallengerBtcPubkeys,\n timelockPegin: tx.timelockPegin,\n network: this.config.network,\n claimerBtcPubkey: tx.claimerBtcPubkey,\n registeredPayoutScriptPubKey: tx.registeredPayoutScriptPubKey,\n commissionBps: tx.commissionBps,\n });\n psbtsToSign.push(payoutPsbt.psbtHex);\n signOptions.push(createTaprootScriptPathSignOptions(walletPubkeyRaw, 1));\n }\n\n // Batch sign all PSBTs with single wallet interaction\n const signedPsbts = await this.config.btcWallet.signPsbts!(\n psbtsToSign,\n signOptions,\n );\n\n // Validate that wallet returned the expected number of signed PSBTs\n if (signedPsbts.length !== transactions.length) {\n throw new Error(\n `Expected ${transactions.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n\n // Extract signatures from signed PSBTs\n const results: Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }> = [];\n\n for (let i = 0; i < transactions.length; i++) {\n const depositorPubkey = depositorPubkeys[i];\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: psbtsToSign[i],\n returnedPsbtHex: signedPsbts[i],\n });\n const payoutSignature = extractPayoutSignature(\n signedPsbts[i],\n depositorPubkey,\n );\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: psbtsToSign[i],\n signatureHex: payoutSignature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n results.push({\n payoutSignature,\n depositorBtcPubkey: depositorPubkey,\n });\n }\n\n return results;\n }\n}\n"],"names":["OP_RETURN","OP_PUSH32","OP_RETURN_PUSH32_SCRIPT_LEN","assertAuthAnchorOpReturn","fundedPrePeginTxHex","vaultCount","expectedAuthAnchorHashHex","cleanHex","stripHexPrefix","tx","bitcoin","opReturnOutput","script","pushedHex","findAuthAnchorOpReturn","hits","i","output","HEX_BYTES32_LENGTH","hexToBytes","hex","clean","bytes","bytesToHex","b","assertBytes32","value","label","computeHashlock","secret","secretBytes","hash","sha256","validateSecretAgainstHashlock","hashlock","PAYOUT_SIGNED_INPUT_INDEX","PayoutManager","config","__publicField","params","walletPubkeyRaw","depositorPubkey","validateWalletPubkey","payoutPsbt","buildPayoutPsbt","signedPsbtHex","createTaprootScriptPathSignOptions","assertPsbtUnsignedTxMatches","signature","extractPayoutSignature","assertScriptPathSchnorrSignature","transactions","psbtsToSign","signOptions","depositorPubkeys","signedPsbts","results","payoutSignature"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var Lt=Object.defineProperty;var Xt=(n,t,e)=>t in n?Lt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var E=(n,t,e)=>Xt(n,typeof t!="symbol"?t+"":t,e);const b=require("./sha2-DsrLC4NM.cjs"),K=require("bitcoinjs-lib"),et=require("buffer"),$=require("viem"),H=require("./BTCVaultRegistry.abi-JdeqLz4x.cjs"),R=require("./errors-CGcNP0rV.cjs"),F=require("@babylonlabs-io/babylon-tbv-rust-wasm"),O=require("./verifyScriptPathSchnorrSignature-Cl7tu77P.cjs"),j=require("./peginInput-DH6X4ITS.cjs"),l=require("./bitcoin-CHfKAhcI.cjs"),Dt=require("./signing-Bnsro0hE.cjs"),lt=require("./validation-u8W7Lp2x.cjs"),xt=require("./PayoutManager-BZVEyi10.cjs"),I=require("./waitForTransactionReceiptSmartAware-U706oKTc.cjs"),ut=require("./fundPeginTransaction-DuMwnytD.cjs"),nt=require("./mempoolApi-NMiYQAXI.cjs");function Kt(n){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const e in n)if(e!=="default"){const s=Object.getOwnPropertyDescriptor(n,e);Object.defineProperty(t,e,s.get?s:{enumerable:!0,get:()=>n[e]})}}return t.default=n,Object.freeze(t)}const yt=Kt(K),W=BigInt(2**32-1),ht=BigInt(32);function qt(n,t=!1){return t?{h:Number(n&W),l:Number(n>>ht&W)}:{h:Number(n>>ht&W)|0,l:Number(n&W)|0}}function Gt(n,t=!1){const e=n.length;let s=new Uint32Array(e),r=new Uint32Array(e);for(let o=0;o<e;o++){const{h:i,l:a}=qt(n[o],t);[s[o],r[o]]=[i,a]}return[s,r]}const zt=(n,t,e)=>n<<e|t>>>32-e,jt=(n,t,e)=>t<<e|n>>>32-e,Yt=(n,t,e)=>t<<e-32|n>>>64-e,Zt=(n,t,e)=>n<<e-32|t>>>64-e,N=32,Y=32,st=36,wt=32,q=4,Qt=q+N+q+wt;function rt(n,t,e){n[t]=e>>>24&255,n[t+1]=e>>>16&255,n[t+2]=e>>>8&255,n[t+3]=e&255}function Jt(n){if(n.txid.length!==Y)throw new Error(`outpoint.txid must be exactly ${Y} bytes, got ${n.txid.length}`);if(!Number.isInteger(n.vout)||n.vout<0||n.vout>4294967295)throw new Error(`outpoint.vout must be a u32, got ${n.vout}`);const t=new Uint8Array(st);return t.set(n.txid,0),rt(t,Y,n.vout),t}function dt(n,t){const e=Math.min(n.length,t.length);for(let s=0;s<e;s++)if(n[s]!==t[s])return n[s]-t[s];return n.length-t.length}function kt(n){if(n.length===0)throw new Error("buildFundingOutpointsCommitment: outpoints must be non-empty");const t=n.map(Jt);t.sort(dt);for(let s=1;s<t.length;s++)if(dt(t[s-1],t[s])===0)throw new Error("buildFundingOutpointsCommitment: duplicate outpoint detected");const e=new Uint8Array(t.length*st);for(let s=0;s<t.length;s++)e.set(t[s],s*st);return b.sha256(e)}function Et(n){if(n.depositorBtcPubkey.length!==N)throw new Error(`vaultContext: depositorBtcPubkey must be exactly ${N} bytes, got ${n.depositorBtcPubkey.length}`);const t=kt(n.fundingOutpoints),e=new Uint8Array(Qt);let s=0;return rt(e,s,N),s+=q,e.set(n.depositorBtcPubkey,s),s+=N,rt(e,s,wt),s+=q,e.set(t,s),e}const Tt="babylon-btc-vault",Bt=32,gt=Bt*2,te=/^[0-9a-f]+$/;async function _t(n,t){const e=Et(t),s=l.uint8ArrayToHex(e),r=await n.deriveContextHash(Tt,s);if(typeof r!="string")throw new Error(`deriveVaultRoot: wallet must return a string, got ${typeof r}`);if(r.length!==gt)throw new Error(`deriveVaultRoot: wallet must return a ${gt}-character hex string (${Bt} bytes), got length ${r.length}`);if(!te.test(r))throw new Error("deriveVaultRoot: wallet must return lowercase hex per derive-context-hash.md §2.1; got value with non-lowercase or non-hex characters");return l.hexToUint8Array(r)}const ee=Uint8Array.from([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]),At=Uint8Array.from(new Array(16).fill(0).map((n,t)=>t)),ne=At.map(n=>(9*n+5)%16),St=(()=>{const e=[[At],[ne]];for(let s=0;s<4;s++)for(let r of e)r.push(r[s].map(o=>ee[o]));return e})(),vt=St[0],It=St[1],Ht=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[12,13,11,15,6,9,9,7,12,15,11,13,7,8,7,7],[13,15,14,11,7,7,6,8,13,14,13,12,5,5,6,9],[14,11,12,14,8,6,5,5,15,12,15,14,9,9,8,6],[15,12,13,13,9,5,8,6,14,11,12,11,8,6,5,5]].map(n=>Uint8Array.from(n)),se=vt.map((n,t)=>n.map(e=>Ht[t][e])),re=It.map((n,t)=>n.map(e=>Ht[t][e])),oe=Uint32Array.from([0,1518500249,1859775393,2400959708,2840853838]),ie=Uint32Array.from([1352829926,1548603684,1836072691,2053994217,0]);function ft(n,t,e,s){return n===0?t^e^s:n===1?t&e|~t&s:n===2?(t|~e)^s:n===3?t&s|e&~s:t^(e|~s)}const L=new Uint32Array(16);class ae extends b.HashMD{constructor(){super(64,20,8,!0);E(this,"h0",1732584193);E(this,"h1",-271733879);E(this,"h2",-1732584194);E(this,"h3",271733878);E(this,"h4",-1009589776)}get(){const{h0:e,h1:s,h2:r,h3:o,h4:i}=this;return[e,s,r,o,i]}set(e,s,r,o,i){this.h0=e|0,this.h1=s|0,this.h2=r|0,this.h3=o|0,this.h4=i|0}process(e,s){for(let f=0;f<16;f++,s+=4)L[f]=e.getUint32(s,!0);let r=this.h0|0,o=r,i=this.h1|0,a=i,c=this.h2|0,d=c,u=this.h3|0,P=u,x=this.h4|0,y=x;for(let f=0;f<5;f++){const p=4-f,T=oe[f],S=ie[f],B=vt[f],m=It[f],w=se[f],k=re[f];for(let g=0;g<16;g++){const h=b.rotl(r+ft(f,i,c,u)+L[B[g]]+T,w[g])+x|0;r=x,x=u,u=b.rotl(c,10)|0,c=i,i=h}for(let g=0;g<16;g++){const h=b.rotl(o+ft(p,a,d,P)+L[m[g]]+S,k[g])+y|0;o=y,y=P,P=b.rotl(d,10)|0,d=a,a=h}}this.set(this.h1+c+P|0,this.h2+u+y|0,this.h3+x+o|0,this.h4+r+a|0,this.h0+i+d|0)}roundClean(){b.clean(L)}destroy(){this.destroyed=!0,b.clean(this.buffer),this.set(0,0,0,0,0)}}const ce=b.createHasher(()=>new ae),le=BigInt(0),V=BigInt(1),ue=BigInt(2),he=BigInt(7),de=BigInt(256),ge=BigInt(113),Ct=[],Rt=[],Ot=[];for(let n=0,t=V,e=1,s=0;n<24;n++){[e,s]=[s,(2*e+3*s)%5],Ct.push(2*(5*s+e)),Rt.push((n+1)*(n+2)/2%64);let r=le;for(let o=0;o<7;o++)t=(t<<V^(t>>he)*ge)%de,t&ue&&(r^=V<<(V<<BigInt(o))-V);Ot.push(r)}const $t=Gt(Ot,!0),fe=$t[0],pe=$t[1],pt=(n,t,e)=>e>32?Yt(n,t,e):zt(n,t,e),mt=(n,t,e)=>e>32?Zt(n,t,e):jt(n,t,e);function me(n,t=24){const e=new Uint32Array(10);for(let s=24-t;s<24;s++){for(let i=0;i<10;i++)e[i]=n[i]^n[i+10]^n[i+20]^n[i+30]^n[i+40];for(let i=0;i<10;i+=2){const a=(i+8)%10,c=(i+2)%10,d=e[c],u=e[c+1],P=pt(d,u,1)^e[a],x=mt(d,u,1)^e[a+1];for(let y=0;y<50;y+=10)n[i+y]^=P,n[i+y+1]^=x}let r=n[2],o=n[3];for(let i=0;i<24;i++){const a=Rt[i],c=pt(r,o,a),d=mt(r,o,a),u=Ct[i];r=n[u],o=n[u+1],n[u]=c,n[u+1]=d}for(let i=0;i<50;i+=10){for(let a=0;a<10;a++)e[a]=n[i+a];for(let a=0;a<10;a++)n[i+a]^=~e[(a+2)%10]&e[(a+4)%10]}n[0]^=fe[s],n[1]^=pe[s]}b.clean(e)}class at{constructor(t,e,s,r=!1,o=24){E(this,"state");E(this,"pos",0);E(this,"posOut",0);E(this,"finished",!1);E(this,"state32");E(this,"destroyed",!1);E(this,"blockLen");E(this,"suffix");E(this,"outputLen");E(this,"enableXOF",!1);E(this,"rounds");if(this.blockLen=t,this.suffix=e,this.outputLen=s,this.enableXOF=r,this.rounds=o,b.anumber(s,"outputLen"),!(0<t&&t<200))throw new Error("only keccak-f1600 function is supported");this.state=new Uint8Array(200),this.state32=b.u32(this.state)}clone(){return this._cloneInto()}keccak(){b.swap32IfBE(this.state32),me(this.state32,this.rounds),b.swap32IfBE(this.state32),this.posOut=0,this.pos=0}update(t){b.aexists(this),b.abytes(t);const{blockLen:e,state:s}=this,r=t.length;for(let o=0;o<r;){const i=Math.min(e-this.pos,r-o);for(let a=0;a<i;a++)s[this.pos++]^=t[o++];this.pos===e&&this.keccak()}return this}finish(){if(this.finished)return;this.finished=!0;const{state:t,suffix:e,pos:s,blockLen:r}=this;t[s]^=e,(e&128)!==0&&s===r-1&&this.keccak(),t[r-1]^=128,this.keccak()}writeInto(t){b.aexists(this,!1),b.abytes(t),this.finish();const e=this.state,{blockLen:s}=this;for(let r=0,o=t.length;r<o;){this.posOut>=s&&this.keccak();const i=Math.min(s-this.posOut,o-r);t.set(e.subarray(this.posOut,this.posOut+i),r),this.posOut+=i,r+=i}return t}xofInto(t){if(!this.enableXOF)throw new Error("XOF is not possible for this instance");return this.writeInto(t)}xof(t){return b.anumber(t),this.xofInto(new Uint8Array(t))}digestInto(t){if(b.aoutput(t,this),this.finished)throw new Error("digest() was already called");return this.writeInto(t),this.destroy(),t}digest(){return this.digestInto(new Uint8Array(this.outputLen))}destroy(){this.destroyed=!0,b.clean(this.state)}_cloneInto(t){const{blockLen:e,suffix:s,outputLen:r,rounds:o,enableXOF:i}=this;return t||(t=new at(e,s,r,i,o)),t.state32.set(this.state32),t.pos=this.pos,t.posOut=this.posOut,t.finished=this.finished,t.rounds=o,t.suffix=s,t.outputLen=r,t.enableXOF=i,t.destroyed=this.destroyed,t}}const Pe=(n,t,e,s={})=>b.createHasher(()=>new at(t,n,e),s),be=Pe(1,136,32),Pt=64,_=20,ot=4,Ut=2,xe=0,ye=1,X=[64,64],we=n=>Array.from(n).map(t=>t.toString(16).padStart(2,"0")).join("");function ct(n){return ce(b.sha256(n))}function Vt(n){return(1<<n)-1}function ke(n){let t=1;for(;t*t<n+1;)t++;return Math.max(t,2)}function Ee(n){const t=ot,e=n*Vt(t);return{d:t,n,checksum_radix:ke(e)}}function Z(n,t){const e=[];let s=t;for(;s>0;)e.push(s&255),s>>>=8;const r=new Uint8Array(n.length+e.length);r.set(n);for(let o=0;o<e.length;o++)r[n.length+o]=e[o];return ct(r)}function Q(n,t){let e=n;for(let s=0;s<t;s++)e=ct(e);return e}function Te(n,t){const e=Vt(t.d),s=t.checksum_radix-1,r=Math.floor(t.n*e/t.checksum_radix),o=[];for(let u=0;u<t.n;u++){const P=Z(n,u+Ut),x=Q(P,e);o.push(Array.from(x))}const i=Z(n,xe),a=Q(i,s),c=Z(n,ye),d=Q(c,r);return{config:t,message_terminals:o,checksum_major_terminal:Array.from(d),checksum_minor_terminal:Array.from(a)}}async function Mt(n){try{if(n.length!==Pt)throw new Error(`WOTS seed must be exactly ${Pt} bytes, got ${n.length}`);const t=[];for(let e=0;e<X.length;e++){const s=X[e],r=Ee(s),o=new Uint8Array(n.length+1);o.set(n),o[n.length]=e;const i=ct(o);try{const a=Te(i,r);if(a.config.d!==ot)throw new Error(`Block ${e}: expected d=${ot}, got d=${a.config.d}`);if(a.config.n!==s)throw new Error(`Block ${e}: expected n=${s}, got n=${a.config.n}`);if(a.message_terminals.length!==s)throw new Error(`Block ${e}: expected ${s} message terminals, got ${a.message_terminals.length}`);for(let c=0;c<a.message_terminals.length;c++)if(a.message_terminals[c].length!==_)throw new Error(`Block ${e} terminal ${c}: expected ${_} bytes, got ${a.message_terminals[c].length}`);if(a.checksum_minor_terminal.length!==_)throw new Error(`Block ${e} checksum_minor: expected ${_} bytes`);if(a.checksum_major_terminal.length!==_)throw new Error(`Block ${e} checksum_major: expected ${_} bytes`);t.push(a)}finally{o.fill(0),i.fill(0)}}if(t.length!==X.length)throw new Error(`Expected ${X.length} blocks, got ${t.length}`);return t}finally{n.fill(0)}}function J(n,t,e){if(n.length!==_)throw new Error(`Block ${t} ${e}: expected ${_} bytes, got ${n.length}`);for(let s=0;s<n.length;s++){const r=n[s];if(!Number.isInteger(r)||r<0||r>255)throw new Error(`Block ${t} ${e}[${s}]: invalid byte value ${r}`)}}function Nt(n){if(n.length===0)throw new Error("Public keys array must not be empty");for(let o=0;o<n.length;o++){const i=n[o];J(i.checksum_minor_terminal,o,"checksum_minor_terminal"),J(i.checksum_major_terminal,o,"checksum_major_terminal");for(let a=0;a<i.message_terminals.length;a++)J(i.message_terminals[a],o,`message_terminal[${a}]`)}let t=0;for(const o of n)t+=Ut+o.message_terminals.length;const e=new Uint8Array(t*_);let s=0;for(const o of n){e.set(o.checksum_minor_terminal,s),s+=_,e.set(o.checksum_major_terminal,s),s+=_;for(const i of o.message_terminals)e.set(i,s),s+=_}const r=be(e);return`0x${we(r)}`}async function Be(n,t){const e=[],s=[],r=[],o=[];try{for(let i=0;i<t;i++){const a=await F.expandWotsSeed(n,i);try{const d=await Mt(a);e.push(d),s.push(Nt(d))}finally{a.fill(0)}const c=await F.expandHashlockSecret(n,i);try{const d=l.uint8ArrayToHex(c);r.push(d),o.push(xt.computeHashlock(l.ensureHexPrefix(d)).slice(2))}finally{c.fill(0)}}}finally{n.fill(0)}return{perVaultWotsKeys:e,wotsPkHashes:s,htlcSecretHexes:r,hashlocks:o}}const _e=/^0x[0-9a-f]+$/i,Ae=/^[0-9a-f]+$/i,Se=/^[A-Za-z0-9+/]+={0,2}$/;function M(n){if(typeof n!="string"||n.length===0)throw new Error("BTC wallet returned empty public key");return l.processPublicKeyToXOnly(n).toLowerCase()}function ve(n){if(typeof n!="string"||n.length===0)throw new Error("BTC wallet returned empty BIP-322 signature");if(n.startsWith("0x")||n.startsWith("0X")){if(!_e.test(n)||n.length<4||n.length%2!==0)throw new Error("BTC wallet returned malformed hex BIP-322 signature");return n.toLowerCase()}if(Ae.test(n)){if(n.length%2!==0)throw new Error("BTC wallet returned malformed hex BIP-322 signature");return`0x${n.toLowerCase()}`}if(!Se.test(n)||n.length%4!==0)throw new Error("BTC wallet returned malformed base64 BIP-322 signature");const t=et.Buffer.from(n,"base64");if(t.length===0||t.toString("base64")!==n)throw new Error("BTC wallet returned malformed base64 BIP-322 signature");return`0x${t.toString("hex")}`}async function Ie(n,t,e){if(typeof n.signPsbts=="function"){const r=await n.signPsbts(t,e);if(r.length!==t.length)throw new Error(`Expected ${t.length} signed PSBTs but received ${r.length}`);return r}const s=[];for(let r=0;r<t.length;r++){const o=await n.signPsbt(t[r],e[r]);s.push(o)}return s}const Ft=0,D=25,it=9999,tt="00".repeat(32);function He(n,t){const e={bitcoin:"bc",testnet:"tb",signet:"tb",regtest:"bcrt"};try{const s=yt.address.fromBech32(n);return s.prefix===e[t]&&s.version===0&&s.data.length===20}catch{return!1}}function Ce(n,t,e,s){const r=e==null?void 0:e[`${n}:${t}`];return r?Promise.resolve({txid:n,vout:t,value:r.value,scriptPubKey:r.scriptPubKey}):nt.getUtxoInfo(n,t,s)}const bt=12e4;class Re{constructor(t){E(this,"config");this.config=t}async preparePegin(t){if(t.amounts.length===0)throw new Error("amounts must contain at least one entry");const e=await this.config.btcWallet.getPublicKeyHex(),s=M(e);if(!l.isAddressFromPublicKey(t.changeAddress,e,this.config.btcNetwork))throw new Error(`Pre-PegIn changeAddress "${t.changeAddress}" is not derived from the connected wallet's public key. Refusing to build a tx that would send change to an address the signing key doesn't control.`);const r=await this.prepareSizing(s,t),o=r.selectedUTXOs.map(p=>({txid:l.hexToUint8Array(p.txid),vout:p.vout})),i=await _t(this.config.btcWallet,{depositorBtcPubkey:l.hexToUint8Array(s),fundingOutpoints:o});let a,c;try{const p=await F.expandAuthAnchor(i);try{a=l.uint8ArrayToHex(p),c=l.uint8ArrayToHex(b.sha256(p))}finally{p.fill(0)}}catch(p){throw i.fill(0),p}const d=await Be(i,t.amounts.length),{perVaultWotsKeys:u,wotsPkHashes:P,htlcSecretHexes:x,hashlocks:y}=d,f=await this.preparePeginCommit({depositorBtcPubkeyRaw:e,depositorBtcPubkey:s,hashlocks:y,authAnchorHash:c,sizing:r,params:t});for(let p=0;p<f.perVault.length;p++)if(f.perVault[p].htlcVout!==p)throw new Error(`Internal invariant violation: htlcVout/index mismatch at vault ${p} (expected ${p}, got ${f.perVault[p].htlcVout})`);return xt.assertAuthAnchorOpReturn(f.fundedPrePeginTxHex,t.amounts.length,c),{transaction:{...f,selectedUTXOs:r.selectedUTXOs,fee:r.fee,changeAmount:r.changeAmount},depositorBtcPubkey:s,derivedSecrets:{perVaultWotsKeys:u,wotsPkHashes:P,htlcSecretHexes:x,authAnchorHex:a}}}async prepareSizing(t,e){const s=e.amounts.map(()=>tt),r=e.vaultKeeperBtcPubkeys.length,o=await O.buildPrePeginPsbt({depositorPubkey:t,vaultProviderPubkey:l.stripHexPrefix(e.vaultProviderBtcPubkey),vaultKeeperPubkeys:e.vaultKeeperBtcPubkeys.map(l.stripHexPrefix),universalChallengerPubkeys:e.universalChallengerBtcPubkeys.map(l.stripHexPrefix),hashlocks:s,timelockRefund:e.timelockRefund,pegInAmounts:e.amounts,feeRate:e.protocolFeeRate,minPeginFeeRate:e.minPeginFeeRate,numLocalChallengers:r,councilQuorum:e.councilQuorum,councilSize:e.councilSize,network:this.config.btcNetwork,authAnchorHash:tt}),i=I.selectUtxosForPegin([...e.availableUTXOs],o.totalOutputValue,e.mempoolFeeRate,ut.peginOutputCount(o.htlcValues.length,!0));return{selectedUTXOs:i.selectedUTXOs,fee:i.fee,changeAmount:i.changeAmount}}async preparePeginCommit(t){const{depositorBtcPubkeyRaw:e,depositorBtcPubkey:s,hashlocks:r,authAnchorHash:o,sizing:i,params:a}=t,c=tt.toLowerCase();for(let h=0;h<r.length;h++)if(r[h].toLowerCase()===c)throw new Error(`preparePeginCommit refusing to build with sizing-pass placeholder hashlock at vault ${h} — internal substitution bug`);if(o.toLowerCase()===c)throw new Error("preparePeginCommit refusing to build with sizing-pass placeholder auth-anchor hash — internal substitution bug");const d=l.stripHexPrefix(a.vaultProviderBtcPubkey),u=a.vaultKeeperBtcPubkeys.map(l.stripHexPrefix),P=a.universalChallengerBtcPubkeys.map(l.stripHexPrefix),x=u.length,y={depositorPubkey:s,vaultProviderPubkey:d,vaultKeeperPubkeys:u,universalChallengerPubkeys:P,hashlocks:r,timelockRefund:a.timelockRefund,pegInAmounts:a.amounts,feeRate:a.protocolFeeRate,minPeginFeeRate:a.minPeginFeeRate,numLocalChallengers:x,councilQuorum:a.councilQuorum,councilSize:a.councilSize,network:this.config.btcNetwork,authAnchorHash:o},f=await O.buildPrePeginPsbt(y),p=l.getNetwork(this.config.btcNetwork),T=ut.fundPeginTransaction({unfundedTxHex:f.psbtHex,selectedUTXOs:i.selectedUTXOs,changeAddress:a.changeAddress,changeAmount:i.changeAmount,network:p}),S=l.stripHexPrefix(I.calculateBtcTxHash(T)),B=[],m=[],w=[];for(let h=0;h<r.length;h++){const A=await O.buildPeginTxFromFundedPrePegin({prePeginParams:y,timelockPegin:a.timelockPegin,fundedPrePeginTxHex:T,htlcVout:h}),v=await j.buildPeginInputPsbt({peginTxHex:A.txHex,fundedPrePeginTxHex:T,depositorPubkey:s,vaultProviderPubkey:d,vaultKeeperPubkeys:u,universalChallengerPubkeys:P,hashlock:r[h],timelockRefund:a.timelockRefund,network:this.config.btcNetwork});B.push(A),m.push(v.psbtHex),w.push(Dt.createTaprootScriptPathSignOptions(e,1))}const k=await Ie(this.config.btcWallet,m,w),g=[];for(let h=0;h<k.length;h++){O.assertPsbtUnsignedTxMatches({requestedPsbtHex:m[h],returnedPsbtHex:k[h]});const A=j.extractPeginInputSignature(k[h],s);O.assertScriptPathSchnorrSignature({requestedPsbtHex:m[h],signatureHex:A,signerXOnlyPubkeyHex:s,inputIndex:0});const v=j.finalizePeginInputPsbt(k[h]);g.push({htlcVout:h,htlcValue:f.htlcValues[h],peginTxHex:v,peginTxid:B[h].txid,peginInputSignature:A,vaultScriptPubKey:B[h].vaultScriptPubKey})}return{fundedPrePeginTxHex:T,prePeginTxid:S,perVault:g}}async signAndBroadcast(t){const{fundedPrePeginTxHex:e,depositorBtcPubkey:s}=t,r=e.startsWith("0x")?e.slice(2):e,o=K.Transaction.fromHex(r);if(o.ins.length===0)throw new Error("Transaction has no inputs");const i=new K.Psbt;i.setVersion(o.version),i.setLocktime(o.locktime);const a=et.Buffer.from(M(s),"hex"),c=this.config.mempoolApiUrl,d=o.ins.map(m=>{const w=et.Buffer.from(m.hash).reverse().toString("hex"),k=m.index;return Ce(w,k,t.localPrevouts,c).then(g=>({input:m,utxoData:g,txid:w,vout:k}))}),u=await Promise.all(d),P=u.reduce((m,w)=>m+BigInt(w.utxoData.value),0n),x=o.outs.reduce((m,w)=>m+BigInt(w.value),0n);if(P<x)throw new Error(`UTXO value mismatch: total input value (${P} sat) is less than total output value (${x} sat). This may indicate the mempool API returned manipulated UTXO data.`);const y=P-x;if(y>lt.MAX_REASONABLE_FEE_SATS)throw new Error(`Implied transaction fee (${y} sat) exceeds maximum reasonable fee (${lt.MAX_REASONABLE_FEE_SATS} sat). This may indicate manipulated UTXO data.`);for(const{input:m,utxoData:w,txid:k,vout:g}of u){const h=I.getPsbtInputFields({value:w.value,scriptPubKey:w.scriptPubKey},a);i.addInput({hash:m.hash,index:m.index,sequence:m.sequence,...h})}for(const m of o.outs)i.addOutput({script:m.script,value:m.value});const f=i.toHex(),p=await this.config.btcWallet.signPsbt(f);O.assertPsbtUnsignedTxMatches({requestedPsbtHex:f,returnedPsbtHex:p});const T=K.Psbt.fromHex(p);try{T.finalizeAllInputs()}catch(m){if(!T.data.inputs.every(k=>k.finalScriptWitness||k.finalScriptSig))throw new Error(`PSBT finalization failed and wallet did not auto-finalize: ${m}`)}const S=T.extractTransaction().toHex();return await nt.pushTx(S,c)}async registerPeginOnChain(t){const{unsignedPrePeginTx:e,depositorSignedPeginTx:s,vaultProvider:r,hashlock:o,htlcVout:i,depositorPayoutBtcAddress:a,depositorWotsPkHash:c,popSignature:d}=t;if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const u=this.config.ethWallet.account.address;if(!$.isAddressEqual(d.depositorEthAddress,u))throw new Error(`Proof of possession was signed for ${d.depositorEthAddress} but the Ethereum wallet is currently connected to ${u}. Reconnect the original account or call signProofOfPossession() again.`);const P=await this.assertPopMatchesBtcWallet(d),x=d.btcPopSignature,y=l.ensureHexPrefix(d.depositorBtcPubkey),f=l.ensureHexPrefix(e),p=l.ensureHexPrefix(s),T=a??await this.config.btcWallet.getAddress(),S=this.resolvePayoutScriptPubKey(P,T),B=I.calculateBtcTxHash(p),m=await F.deriveVaultId(l.stripHexPrefix(B),l.stripHexPrefix(u)),w=l.ensureHexPrefix(m);if(await this.checkVaultExists(w))throw new Error(`Vault already exists (ID: ${w}, peginTxHash: ${B}). Vault IDs are derived from the pegin transaction hash and depositor address. To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`);const g=this.config.publicClient;let h;try{h=await g.readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:H.BTCVaultRegistryABI,functionName:"getPegInFee",args:[r]})}catch(U){throw new Error("Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct.",{cause:U})}const A=await this.resolveMaxAcceptableCommissionBps(r,t.quotedCommissionBps),v=$.encodeFunctionData({abi:H.BTCVaultRegistryABI,functionName:"submitPeginRequest",args:[u,y,x,f,p,r,A,o,i,S,c]});let C;try{C=await g.estimateGas({to:this.config.vaultContracts.btcVaultRegistry,data:v,value:h,account:this.config.ethWallet.account.address})}catch(U){R.handleContractError(U)}let G;try{G=await this.config.ethWallet.sendTransaction({to:this.config.vaultContracts.btcVaultRegistry,data:v,value:h,account:this.config.ethWallet.account,chain:this.config.ethChain,gas:C})}catch(U){R.handleContractError(U)}const z=await I.waitForTransactionReceiptSmartAware({publicClient:g,walletAddress:this.config.ethWallet.account.address,hash:G,timeout:bt});return z.status==="reverted"&&R.handleContractError(new Error(`Transaction reverted. Hash: ${z.transactionHash}. Check the transaction on block explorer for details.`)),{ethTxHash:z.transactionHash,vaultId:w,peginTxHash:B}}async registerPeginBatchOnChain(t){const{vaultProvider:e,unsignedPrePeginTx:s,requests:r,popSignature:o}=t;if(r.length===0)throw new Error("Batch pegin requires at least one request");if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const i=this.config.ethWallet.account.address;if(!$.isAddressEqual(o.depositorEthAddress,i))throw new Error(`Proof of possession was signed for ${o.depositorEthAddress} but the Ethereum wallet is currently connected to ${i}. Reconnect the original account or call signProofOfPossession() again.`);const a=await this.assertPopMatchesBtcWallet(o),c=o.btcPopSignature,d=r.map(g=>this.resolvePayoutScriptPubKey(a,g.depositorPayoutBtcAddress)),u=[];for(const g of r){const h=l.ensureHexPrefix(g.depositorSignedPeginTx),A=I.calculateBtcTxHash(h),v=await F.deriveVaultId(l.stripHexPrefix(A),l.stripHexPrefix(i)),C=l.ensureHexPrefix(v);if(await this.checkVaultExists(C))throw new Error(`Vault already exists (ID: ${C}, peginTxHash: ${A}). To create a new vault, use different UTXOs or a different amount.`);u.push({vaultId:C,peginTxHash:A})}const P=this.config.publicClient;let x;try{x=await P.readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:H.BTCVaultRegistryABI,functionName:"getPegInFee",args:[e]})}catch(g){throw new Error("Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct.",{cause:g})}const y=x*BigInt(r.length),f=await this.resolveMaxAcceptableCommissionBps(e,t.quotedCommissionBps),p=l.ensureHexPrefix(o.depositorBtcPubkey),T=l.ensureHexPrefix(s),S=r.map((g,h)=>({depositorBtcPubKey:p,btcPopSignature:c,unsignedPrePeginTx:T,depositorSignedPeginTx:l.ensureHexPrefix(g.depositorSignedPeginTx),hashlock:g.hashlock,htlcVout:g.htlcVout,referralCode:Ft,depositorPayoutBtcAddress:d[h],depositorWotsPkHash:g.depositorWotsPkHash})),B=$.encodeFunctionData({abi:H.BTCVaultRegistryABI,functionName:"submitPeginRequestBatch",args:[i,e,f,S]});let m;try{m=await P.estimateGas({to:this.config.vaultContracts.btcVaultRegistry,data:B,value:y,account:this.config.ethWallet.account.address})}catch(g){R.handleContractError(g)}let w;try{w=await this.config.ethWallet.sendTransaction({to:this.config.vaultContracts.btcVaultRegistry,data:B,value:y,account:this.config.ethWallet.account,chain:this.config.ethChain,gas:m})}catch(g){R.handleContractError(g)}const k=await I.waitForTransactionReceiptSmartAware({publicClient:P,walletAddress:this.config.ethWallet.account.address,hash:w,timeout:bt});return k.status==="reverted"&&R.handleContractError(new Error(`Batch transaction reverted. Hash: ${k.transactionHash}. Check the transaction on block explorer for details.`)),{ethTxHash:k.transactionHash,vaults:u}}async resolveMaxAcceptableCommissionBps(t,e){let s;try{s=await new nt.ViemVaultRegistryReader(this.config.publicClient,this.config.vaultContracts.btcVaultRegistry).getVaultProviderCommission(t)}catch(r){throw new Error("Failed to query vault provider commission from the contract. Please check your network connection and that the contract address is correct.",{cause:r})}if(e!==void 0){if(s>e+D)throw new Error(`Vault provider commission changed since quote: quoted ${e} bps, chain currently reports ${s} bps (allowed drift ${D} bps). Please refresh to see the new commission and try again.`);return Math.min(e+D,it)}return Math.min(s+D,it)}async checkVaultExists(t){return(await this.config.publicClient.readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:H.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[t]})).depositor!==$.zeroAddress}resolvePayoutScriptPubKey(t,e){if(!l.isAddressFromPublicKey(e,t,this.config.btcNetwork))throw l.stripHexPrefix(t).length===l.X_ONLY_PUBKEY_HEX_LEN&&He(e,this.config.btcNetwork)?new Error(`BTC payout address "${e}" is a P2WPKH (Native SegWit) address, but the connected wallet only exposes an x-only public key. P2WPKH validation requires a compressed key with known y-parity. Use a P2TR (Taproot) payout address instead.`):new Error(`BTC payout address "${e}" is not derived from the connected wallet's public key. The payout sink must be controlled by the same key that signs the pegin; refusing to register a mismatched address.`);const s=l.getNetwork(this.config.btcNetwork);try{return`0x${yt.address.toOutputScript(e,s).toString("hex")}`}catch{throw new Error(`Invalid BTC payout address: "${e}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`)}}async signProofOfPossession(){if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const t=this.config.ethWallet.account.address,e=M(await this.config.btcWallet.getPublicKeyHex()),s=this.config.vaultContracts.btcVaultRegistry,r=`${t.toLowerCase()}:${this.config.ethChain.id}:pegin:${s.toLowerCase()}`,o=await this.config.btcWallet.signMessage(r,"bip322-simple");return{btcPopSignature:ve(o),depositorEthAddress:t,depositorBtcPubkey:e}}async assertPopMatchesBtcWallet(t){const e=await this.config.btcWallet.getPublicKeyHex(),s=M(e),r=M(t.depositorBtcPubkey);if(s!==r)throw new Error(`Proof of possession was signed with BTC pubkey ${r} but the BTC wallet is currently connected to ${s}. Reconnect the original wallet or call signProofOfPossession() again.`);return e}getNetwork(){return this.config.btcNetwork}getVaultContractAddress(){return this.config.vaultContracts.btcVaultRegistry}}const Oe=80,$e=250,Ue=300,Ve=22,Wt="ab";function Me(n,t){const e=Wt.repeat(Ue),s=l.stripHexPrefix(n).toLowerCase(),r=t.toString(16).padStart(8,"0"),o=`${s}${r}`,i=e.slice(o.length);return`0x${o}${i}`}function Ne(n,t){const e=s=>`0x${Wt.repeat(s)}`;return{depositorBtcPubKey:e(32),btcPopSignature:e(Oe),unsignedPrePeginTx:e($e),depositorSignedPeginTx:Me(n,t),hashlock:e(32),htlcVout:t,referralCode:Ft,depositorPayoutBtcAddress:e(Ve),depositorWotsPkHash:e(32)}}async function Fe(n){const{publicClient:t,btcVaultRegistry:e,depositorEthAddress:s,vaultProvider:r,batchSize:o}=n;if(o<=0)throw new Error(`estimateSubmitPeginRequestBatchGas requires batchSize >= 1 (received ${o})`);const a=await t.readContract({address:e,abi:H.BTCVaultRegistryABI,functionName:"getPegInFee",args:[r]})*BigInt(o),c=Array.from({length:o},(u,P)=>Ne(s,P)),d=$.encodeFunctionData({abi:H.BTCVaultRegistryABI,functionName:"submitPeginRequestBatch",args:[s,r,it,c]});return t.estimateGas({to:e,data:d,value:a,account:s})}exports.PeginManager=Re;exports.VAULT_APP_NAME=Tt;exports.buildFundingOutpointsCommitment=kt;exports.buildVaultContext=Et;exports.computeWotsBlockPublicKeysHash=Nt;exports.deriveVaultRoot=_t;exports.deriveWotsBlocksFromSeed=Mt;exports.estimateSubmitPeginRequestBatchGas=Fe;
|
|
2
|
-
//# sourceMappingURL=PeginManager-BvxfSwsr.cjs.map
|