@babylonlabs-io/ts-sdk 3.3.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/dist/{BTCVaultRegistry.abi-BzNTa_EU.js → BTCVaultRegistry.abi-DnP4UkB5.js} +9 -140
  2. package/dist/BTCVaultRegistry.abi-DnP4UkB5.js.map +1 -0
  3. package/dist/{BTCVaultRegistry.abi-BH2-LHxN.cjs → BTCVaultRegistry.abi-DzbfZ9_s.cjs} +2 -2
  4. package/dist/BTCVaultRegistry.abi-DzbfZ9_s.cjs.map +1 -0
  5. package/dist/{PayoutManager-xEGvTbhL.js → PayoutManager-BUWP-H-q.js} +3 -3
  6. package/dist/PayoutManager-BUWP-H-q.js.map +1 -0
  7. package/dist/{PayoutManager-B1Ev0r7o.cjs → PayoutManager-Dopxq_Jv.cjs} +2 -2
  8. package/dist/PayoutManager-Dopxq_Jv.cjs.map +1 -0
  9. package/dist/{PeginManager-D2R4Q1bN.cjs → PeginManager-CMbRRTnr.cjs} +2 -2
  10. package/dist/PeginManager-CMbRRTnr.cjs.map +1 -0
  11. package/dist/{PeginManager-CQ9bVPR3.js → PeginManager-Cas6_j7t.js} +7 -7
  12. package/dist/PeginManager-Cas6_j7t.js.map +1 -0
  13. package/dist/{ProtocolParams.abi-Cv77fsUe.js → ProtocolParams.abi-CuDl7AuC.js} +3 -3
  14. package/dist/{ProtocolParams.abi-Cv77fsUe.js.map → ProtocolParams.abi-CuDl7AuC.js.map} +1 -1
  15. package/dist/{ProtocolParams.abi-BgEZaQ2I.cjs → ProtocolParams.abi-DWfIh6VH.cjs} +2 -2
  16. package/dist/{ProtocolParams.abi-BgEZaQ2I.cjs.map → ProtocolParams.abi-DWfIh6VH.cjs.map} +1 -1
  17. package/dist/VaultErrors.abi-Dc3UnB_h.js +5 -0
  18. package/dist/{VaultErrors.abi-Boz4w97c.js.map → VaultErrors.abi-Dc3UnB_h.js.map} +1 -1
  19. package/dist/VaultErrors.abi-Hjn1CdLs.cjs +2 -0
  20. package/dist/{VaultErrors.abi-DQ18kM0L.cjs.map → VaultErrors.abi-Hjn1CdLs.cjs.map} +1 -1
  21. package/dist/{buildAndBroadcastReclaim-CQANDXVJ.js → buildAndBroadcastReclaim-ByXYSUwj.js} +372 -337
  22. package/dist/buildAndBroadcastReclaim-ByXYSUwj.js.map +1 -0
  23. package/dist/buildAndBroadcastReclaim-OBWjvzuC.cjs +2 -0
  24. package/dist/buildAndBroadcastReclaim-OBWjvzuC.cjs.map +1 -0
  25. package/dist/challengeAssert-eUMgmpMk.cjs +2 -0
  26. package/dist/challengeAssert-eUMgmpMk.cjs.map +1 -0
  27. package/dist/{challengeAssert-B2otuf7y.js → challengeAssert-pJP7MKhG.js} +164 -164
  28. package/dist/challengeAssert-pJP7MKhG.js.map +1 -0
  29. package/dist/constants-BCg6O0PX.cjs +2 -0
  30. package/dist/constants-BCg6O0PX.cjs.map +1 -0
  31. package/dist/constants-CmDDuM3L.js +50 -0
  32. package/dist/constants-CmDDuM3L.js.map +1 -0
  33. package/dist/{index-BRsWXDlv.js → index-B-9aXMxk.js} +6 -6
  34. package/dist/{index-BRsWXDlv.js.map → index-B-9aXMxk.js.map} +1 -1
  35. package/dist/{index-C6avwx1s.cjs → index-Dn7RlsKK.cjs} +2 -2
  36. package/dist/{index-C6avwx1s.cjs.map → index-Dn7RlsKK.cjs.map} +1 -1
  37. package/dist/index.cjs +1 -1
  38. package/dist/index.js +68 -67
  39. package/dist/pegin-registration-client-DLlaZbsZ.cjs +2 -0
  40. package/dist/pegin-registration-client-DLlaZbsZ.cjs.map +1 -0
  41. package/dist/{pegin-registration-client-Cvjk4ILq.js → pegin-registration-client-ZI0k10_3.js} +90 -96
  42. package/dist/pegin-registration-client-ZI0k10_3.js.map +1 -0
  43. package/dist/{primeVpAuth-D4UWXQ76.js → primeVpAuth-C-ET0XF4.js} +2 -2
  44. package/dist/{primeVpAuth-D4UWXQ76.js.map → primeVpAuth-C-ET0XF4.js.map} +1 -1
  45. package/dist/{primeVpAuth-CXNXYKrh.cjs → primeVpAuth-Ch-ig2My.cjs} +2 -2
  46. package/dist/{primeVpAuth-CXNXYKrh.cjs.map → primeVpAuth-Ch-ig2My.cjs.map} +1 -1
  47. package/dist/registration-records-CKc0OVuK.cjs +2 -0
  48. package/dist/registration-records-CKc0OVuK.cjs.map +1 -0
  49. package/dist/{registration-records-DJJC2NiO.js → registration-records-D39ApuHS.js} +141 -141
  50. package/dist/registration-records-D39ApuHS.js.map +1 -0
  51. package/dist/{signer-set-reader-GrFe_rsW.cjs → signer-set-reader-CJfV-GDz.cjs} +2 -2
  52. package/dist/signer-set-reader-CJfV-GDz.cjs.map +1 -0
  53. package/dist/{signer-set-reader-CSUe92zE.js → signer-set-reader-DiwLeqik.js} +3 -3
  54. package/dist/signer-set-reader-DiwLeqik.js.map +1 -0
  55. package/dist/tbv/core/clients/eth/index.cjs +1 -1
  56. package/dist/tbv/core/clients/eth/index.js +4 -4
  57. package/dist/tbv/core/clients/eth/operation-key-reader.d.ts +5 -1
  58. package/dist/tbv/core/clients/eth/operation-key-reader.d.ts.map +1 -1
  59. package/dist/tbv/core/clients/eth/protocol-params-validation.d.ts.map +1 -1
  60. package/dist/tbv/core/clients/eth/registration-logs-error.d.ts +6 -6
  61. package/dist/tbv/core/clients/eth/registration-records.d.ts +1 -1
  62. package/dist/tbv/core/clients/eth/signer-set-reader.d.ts.map +1 -1
  63. package/dist/tbv/core/clients/eth/types.d.ts +32 -13
  64. package/dist/tbv/core/clients/eth/types.d.ts.map +1 -1
  65. package/dist/tbv/core/clients/eth/vault-registry-reader.d.ts +1 -1
  66. package/dist/tbv/core/clients/eth/vault-registry-reader.d.ts.map +1 -1
  67. package/dist/tbv/core/clients/index.cjs +1 -1
  68. package/dist/tbv/core/clients/index.d.ts +4 -2
  69. package/dist/tbv/core/clients/index.d.ts.map +1 -1
  70. package/dist/tbv/core/clients/index.js +6 -6
  71. package/dist/tbv/core/clients/vault-provider/status/index.cjs +1 -1
  72. package/dist/tbv/core/clients/vault-provider/status/index.js +1 -1
  73. package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts +5 -111
  74. package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts.map +1 -1
  75. package/dist/tbv/core/contracts/abis/ProtocolParams.abi.d.ts +2 -2
  76. package/dist/tbv/core/contracts/abis/vaultErrors.abi.json.d.ts +1 -1
  77. package/dist/tbv/core/contracts/index.cjs +1 -1
  78. package/dist/tbv/core/contracts/index.js +3 -3
  79. package/dist/tbv/core/deposit-terms/__tests__/rebuildDepositTermsCore.test.d.ts +1 -1
  80. package/dist/tbv/core/deposit-terms/commissionCeiling.d.ts +1 -1
  81. package/dist/tbv/core/deposit-terms/depositTerms.d.ts +11 -9
  82. package/dist/tbv/core/deposit-terms/depositTerms.d.ts.map +1 -1
  83. package/dist/tbv/core/deposit-terms/rebuildDepositTermsCore.d.ts.map +1 -1
  84. package/dist/tbv/core/index.cjs +1 -1
  85. package/dist/tbv/core/index.js +69 -68
  86. package/dist/tbv/core/managers/PayoutManager.d.ts +9 -3
  87. package/dist/tbv/core/managers/PayoutManager.d.ts.map +1 -1
  88. package/dist/tbv/core/managers/PeginManager.d.ts +13 -3
  89. package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
  90. package/dist/tbv/core/managers/index.cjs +1 -1
  91. package/dist/tbv/core/managers/index.js +2 -2
  92. package/dist/tbv/core/primitives/__tests__/vaultCoreVersion.test.d.ts +1 -1
  93. package/dist/tbv/core/primitives/challengers.d.ts +12 -5
  94. package/dist/tbv/core/primitives/challengers.d.ts.map +1 -1
  95. package/dist/tbv/core/primitives/index.cjs +1 -1
  96. package/dist/tbv/core/primitives/index.d.ts +1 -1
  97. package/dist/tbv/core/primitives/index.js +3 -3
  98. package/dist/tbv/core/primitives/psbt/__tests__/deriveExpectedPeginPayoutScriptPubKey.test.d.ts +1 -1
  99. package/dist/tbv/core/primitives/psbt/assertWasmPeginSizing.d.ts.map +1 -1
  100. package/dist/tbv/core/primitives/psbt/constants.d.ts +38 -13
  101. package/dist/tbv/core/primitives/psbt/constants.d.ts.map +1 -1
  102. package/dist/tbv/core/primitives/psbt/depositorClaim.d.ts +3 -6
  103. package/dist/tbv/core/primitives/psbt/depositorClaim.d.ts.map +1 -1
  104. package/dist/tbv/core/primitives/psbt/pegin.d.ts +29 -9
  105. package/dist/tbv/core/primitives/psbt/pegin.d.ts.map +1 -1
  106. package/dist/tbv/core/primitives/psbt/refund.d.ts.map +1 -1
  107. package/dist/tbv/core/recovery/peginParamsCandidates.d.ts +1 -1
  108. package/dist/tbv/core/recovery/reconstructPeginParams.d.ts.map +1 -1
  109. package/dist/tbv/core/services/delegated-claim/__tests__/realWasmWatchtowerArtifacts.test.d.ts +2 -2
  110. package/dist/tbv/core/services/delegated-claim/assembleWatchtowerArtifacts.d.ts +2 -1
  111. package/dist/tbv/core/services/delegated-claim/assembleWatchtowerArtifacts.d.ts.map +1 -1
  112. package/dist/tbv/core/services/delegated-claim/challengerBinding.d.ts +3 -3
  113. package/dist/tbv/core/services/delegated-claim/challengerBinding.d.ts.map +1 -1
  114. package/dist/tbv/core/services/delegated-claim/deriveClaimerWotsKeypair.d.ts +1 -1
  115. package/dist/tbv/core/services/delegated-claim/deriveClaimerWotsKeypair.d.ts.map +1 -1
  116. package/dist/tbv/core/services/delegated-claim/planDelegatedClaimSigning.d.ts +2 -1
  117. package/dist/tbv/core/services/delegated-claim/planDelegatedClaimSigning.d.ts.map +1 -1
  118. package/dist/tbv/core/services/delegated-claim/readDelegatedClaimVaultContext.d.ts +1 -1
  119. package/dist/tbv/core/services/delegated-claim/readDelegatedClaimVaultContext.d.ts.map +1 -1
  120. package/dist/tbv/core/services/delegated-claim/readWatchtowerArtifacts.d.ts +3 -3
  121. package/dist/tbv/core/services/delegated-claim/readWatchtowerArtifacts.d.ts.map +1 -1
  122. package/dist/tbv/core/services/delegated-claim/types.d.ts +8 -9
  123. package/dist/tbv/core/services/delegated-claim/types.d.ts.map +1 -1
  124. package/dist/tbv/core/services/deposit/__tests__/signDepositorGraph.realGraph.test.d.ts +3 -3
  125. package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts +19 -4
  126. package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts.map +1 -1
  127. package/dist/tbv/core/services/deposit/signDepositorGraph.d.ts +17 -3
  128. package/dist/tbv/core/services/deposit/signDepositorGraph.d.ts.map +1 -1
  129. package/dist/tbv/core/services/index.cjs +1 -1
  130. package/dist/tbv/core/services/index.js +44 -43
  131. package/dist/tbv/core/services/participants/readStampedParticipantKeys.d.ts +19 -7
  132. package/dist/tbv/core/services/participants/readStampedParticipantKeys.d.ts.map +1 -1
  133. package/dist/tbv/core/services/refund/__tests__/readRefundPrePeginContext.test.d.ts +12 -0
  134. package/dist/tbv/core/services/refund/__tests__/readRefundPrePeginContext.test.d.ts.map +1 -0
  135. package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts +41 -12
  136. package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts.map +1 -1
  137. package/dist/tbv/core/services/refund/index.d.ts +1 -0
  138. package/dist/tbv/core/services/refund/index.d.ts.map +1 -1
  139. package/dist/tbv/core/services/refund/readRefundPrePeginContext.d.ts +41 -0
  140. package/dist/tbv/core/services/refund/readRefundPrePeginContext.d.ts.map +1 -0
  141. package/dist/tbv/core/wasm/index.cjs.map +1 -1
  142. package/dist/tbv/core/wasm/index.d.ts +8 -11
  143. package/dist/tbv/core/wasm/index.d.ts.map +1 -1
  144. package/dist/tbv/core/wasm/index.js.map +1 -1
  145. package/dist/tbv/index.cjs +1 -1
  146. package/dist/tbv/index.js +69 -68
  147. package/dist/toRefundInputs-BSQjDOK9.cjs +2 -0
  148. package/dist/toRefundInputs-BSQjDOK9.cjs.map +1 -0
  149. package/dist/{toRefundInputs-DH-1bRNY.js → toRefundInputs-BbbvPb2A.js} +175 -173
  150. package/dist/toRefundInputs-BbbvPb2A.js.map +1 -0
  151. package/dist/{types-BC2TGzcp.cjs → types-BnZIbDHb.cjs} +2 -2
  152. package/dist/types-BnZIbDHb.cjs.map +1 -0
  153. package/dist/{types-24A9Qoxb.js → types-K_aM5GZO.js} +39 -39
  154. package/dist/types-K_aM5GZO.js.map +1 -0
  155. package/dist/{verifyKeyPathSchnorrSignature-IIj3Z2se.js → verifyKeyPathSchnorrSignature-DPXOFOol.js} +2 -2
  156. package/dist/{verifyKeyPathSchnorrSignature-IIj3Z2se.js.map → verifyKeyPathSchnorrSignature-DPXOFOol.js.map} +1 -1
  157. package/dist/{verifyKeyPathSchnorrSignature-BRTpEH9X.cjs → verifyKeyPathSchnorrSignature-DcxCojp0.cjs} +2 -2
  158. package/dist/{verifyKeyPathSchnorrSignature-BRTpEH9X.cjs.map → verifyKeyPathSchnorrSignature-DcxCojp0.cjs.map} +1 -1
  159. package/dist/verifyScriptPathSchnorrSignature-CgDa9Rcg.cjs +2 -0
  160. package/dist/verifyScriptPathSchnorrSignature-CgDa9Rcg.cjs.map +1 -0
  161. package/dist/{verifyScriptPathSchnorrSignature-owu3BfyT.js → verifyScriptPathSchnorrSignature-D-fdi-sG.js} +462 -459
  162. package/dist/verifyScriptPathSchnorrSignature-D-fdi-sG.js.map +1 -0
  163. package/package.json +3 -3
  164. package/dist/BTCVaultRegistry.abi-BH2-LHxN.cjs.map +0 -1
  165. package/dist/BTCVaultRegistry.abi-BzNTa_EU.js.map +0 -1
  166. package/dist/PayoutManager-B1Ev0r7o.cjs.map +0 -1
  167. package/dist/PayoutManager-xEGvTbhL.js.map +0 -1
  168. package/dist/PeginManager-CQ9bVPR3.js.map +0 -1
  169. package/dist/PeginManager-D2R4Q1bN.cjs.map +0 -1
  170. package/dist/VaultErrors.abi-Boz4w97c.js +0 -5
  171. package/dist/VaultErrors.abi-DQ18kM0L.cjs +0 -2
  172. package/dist/buildAndBroadcastReclaim-CQANDXVJ.js.map +0 -1
  173. package/dist/buildAndBroadcastReclaim-DPk36Uhp.cjs +0 -2
  174. package/dist/buildAndBroadcastReclaim-DPk36Uhp.cjs.map +0 -1
  175. package/dist/challengeAssert-B2otuf7y.js.map +0 -1
  176. package/dist/challengeAssert-C3eMcM5Y.cjs +0 -2
  177. package/dist/challengeAssert-C3eMcM5Y.cjs.map +0 -1
  178. package/dist/constants-CAm10Qwp.cjs +0 -2
  179. package/dist/constants-CAm10Qwp.cjs.map +0 -1
  180. package/dist/constants-CvQZuxKv.js +0 -48
  181. package/dist/constants-CvQZuxKv.js.map +0 -1
  182. package/dist/pegin-registration-client-CdRyXP3j.cjs +0 -2
  183. package/dist/pegin-registration-client-CdRyXP3j.cjs.map +0 -1
  184. package/dist/pegin-registration-client-Cvjk4ILq.js.map +0 -1
  185. package/dist/registration-records-DJJC2NiO.js.map +0 -1
  186. package/dist/registration-records-XQMIKjGV.cjs +0 -2
  187. package/dist/registration-records-XQMIKjGV.cjs.map +0 -1
  188. package/dist/signer-set-reader-CSUe92zE.js.map +0 -1
  189. package/dist/signer-set-reader-GrFe_rsW.cjs.map +0 -1
  190. package/dist/toRefundInputs-DH-1bRNY.js.map +0 -1
  191. package/dist/toRefundInputs-DRmK83fv.cjs +0 -2
  192. package/dist/toRefundInputs-DRmK83fv.cjs.map +0 -1
  193. package/dist/types-24A9Qoxb.js.map +0 -1
  194. package/dist/types-BC2TGzcp.cjs.map +0 -1
  195. package/dist/verifyScriptPathSchnorrSignature-CahYx5Td.cjs +0 -2
  196. package/dist/verifyScriptPathSchnorrSignature-CahYx5Td.cjs.map +0 -1
  197. package/dist/verifyScriptPathSchnorrSignature-owu3BfyT.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"pegin-registration-client-CdRyXP3j.cjs","sources":["../src/tbv/core/deposit-terms/commissionCeiling.ts","../src/tbv/core/clients/eth/vault-registry-reader.ts","../src/tbv/core/clients/eth/pegin-registration-client.ts"],"sourcesContent":["/**\n * The depositor's commission ceiling (`maxAcceptableCommissionBps`) policy:\n * quoted VP commission + drift headroom, capped below the contract's\n * exclusive bound. Shared by `PeginManager` (the approved terms) and the\n * registration calldata so both carry the same ceiling; a resume rebuild reads\n * that submitted value back from the `PegInSubmittedV2` log instead.\n *\n * @module deposit-terms/commissionCeiling\n */\n\n/*\n * Commission-check map (each guards a DIFFERENT boundary — do not consolidate):\n * 1. assertVpCommissionInProtocolRange (vault app, vaultPayoutSignatureService)\n * — chain-read trust boundary; mirrors VPKeyRegistryLogic.sol bounds.\n * 2. capMaxAcceptableCommissionBps (here) — depositor quote → ceiling policy;\n * mirrors PeginLogic.sol's strict > check via the +25bps headroom.\n * 3. buildDepositTerms range check — public-API precondition on the projection\n * that mints the device-enforced commissionFee.\n * 4. payout.ts commission cap — the VP-built tx's output value vs bps at the\n * signing site (CLAUDE.md Critical Path #3).\n * 5. envelope.ts dust/cross-field gates (ledger-vault-signer) — firmware-only\n * constants, pre-device-I/O (Critical Path #7).\n */\n\nimport { MAX_VP_COMMISSION_BPS_EXCLUSIVE } from \"../primitives/psbt/constants\";\n\n/**\n * Headroom (in basis points) added to the current VP commission to compute\n * `maxAcceptableCommissionBps` at submit time. Lets the VP raise its\n * commission by up to this amount between read and submit without forcing\n * a re-quote. Capped by {@link MAX_ACCEPTABLE_COMMISSION_BPS_CAP}.\n *\n * Contract check is strict `>` (PeginLogic.sol `VaultProviderCommissionExceeded`\n * revert), so +25 allows up\n * to +25 bps of drift.\n */\nexport const COMMISSION_BPS_HEADROOM = 25;\n\n/**\n * Hard ceiling for `maxAcceptableCommissionBps`. The contract enforces\n * `commissionBps < 10000`, so any value at/above that is unreachable;\n * `9999` is the maximum useful cap.\n */\nexport const MAX_ACCEPTABLE_COMMISSION_BPS_CAP = 9999;\n\n/**\n * The commission ceiling submitted as registration calldata and mirrored\n * into `DepositTerms.commissionFee`: quoted + drift headroom, capped.\n * Single source for both consumers — feed it the SAME quoted bps at prepare\n * and register time so device-accept stays coextensive with contract-accept.\n */\nexport function capMaxAcceptableCommissionBps(bps: number): number {\n // Validate the raw quote before headroom shifts its domain — a negative\n // quote must throw here, not become a small \"legal\" ceiling.\n // Reject an out-of-range quote outright — clamping it to 9999 would turn a\n // bad read into a 99.99% ceiling, the exact failure the cap exists to stop.\n if (\n !Number.isInteger(bps) ||\n bps < 0 ||\n bps >= MAX_VP_COMMISSION_BPS_EXCLUSIVE\n ) {\n throw new Error(\n `Quoted commissionBps must be an integer in ` +\n `[0, ${MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${bps}`,\n );\n }\n return Math.min(\n bps + COMMISSION_BPS_HEADROOM,\n MAX_ACCEPTABLE_COMMISSION_BPS_CAP,\n );\n}\n","/**\n * Concrete BTCVaultRegistry reader using viem's readContract.\n *\n * This is an optional utility — callers can use their own implementation\n * of the VaultRegistryReader interface.\n */\n\nimport type { Abi, Address, Hex, PublicClient } from \"viem\";\nimport { getAbiItem } from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { BTCVaultRegistryKeyEpochsABI } from \"../../contracts/abis/BTCVaultRegistryKeyEpochs.abi\";\nimport { VaultClaimableByNotFoundError } from \"./claimable-event-error\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertValidOffchainParamsVersion } from \"./protocol-params-validation\";\nimport { RegistrationLogsUnavailableError } from \"./registration-logs-error\";\nimport { findRegistrationRecord } from \"./registration-records\";\nimport type {\n KeyEpochs,\n OnChainBtcPubkey,\n PeginRegistrationRecord,\n VaultBasicInfo,\n VaultClaimableByEvent,\n VaultData,\n VaultProtocolInfo,\n VaultRegistryReader,\n} from \"./types\";\n\n/**\n * Inclusive upper bound the BTCVaultRegistry contract enforces on a vault\n * provider's commission (the contract check is `< 10000`).\n */\nconst MAX_VP_COMMISSION_BPS = 9999;\n\n/** Raw `getBtcVaultBasicInfo` tuple as decoded by viem. */\ntype RawVaultBasicInfo = {\n depositor: Address;\n depositorBtcPubKey: Hex;\n amount: bigint;\n vaultProvider: Address;\n status: number;\n applicationEntryPoint: Address;\n createdAt: bigint;\n};\n\n/**\n * Raw `getBtcVaultProtocolInfo` tuple as decoded by viem.\n *\n * Mirrors the ABI's components. The trailing key epochs are read through the\n * separate key-epochs ABI, so this prefix stops at `vaultCoreVersion`.\n */\ntype RawVaultProtocolInfo = {\n depositorSignedPeginTx: Hex;\n universalChallengersVersion: number;\n appVaultKeepersVersion: number;\n offchainParamsVersion: number;\n verifiedAt: bigint;\n depositorWotsPkHash: Hex;\n hashlock: Hex;\n htlcVout: number;\n depositorPopSignature: Hex;\n prePeginTxHash: Hex;\n vaultProviderCommissionBps: number;\n claimExpiredUntil: bigint;\n vaultCoreVersion: number;\n};\n\nfunction mapVaultBasicInfo(result: RawVaultBasicInfo): VaultBasicInfo {\n return {\n depositor: result.depositor,\n depositorBtcPubKey: result.depositorBtcPubKey,\n amount: result.amount,\n vaultProvider: result.vaultProvider,\n status: result.status,\n applicationEntryPoint: result.applicationEntryPoint,\n createdAt: result.createdAt,\n };\n}\n\nfunction mapVaultProtocolInfo(result: RawVaultProtocolInfo): VaultProtocolInfo {\n const offchainParamsVersion = Number(result.offchainParamsVersion);\n assertValidOffchainParamsVersion(offchainParamsVersion);\n return {\n depositorSignedPeginTx: result.depositorSignedPeginTx,\n universalChallengersVersion: result.universalChallengersVersion,\n appVaultKeepersVersion: result.appVaultKeepersVersion,\n offchainParamsVersion,\n verifiedAt: result.verifiedAt,\n depositorWotsPkHash: result.depositorWotsPkHash,\n hashlock: result.hashlock,\n htlcVout: result.htlcVout,\n depositorPopSignature: result.depositorPopSignature,\n prePeginTxHash: result.prePeginTxHash,\n vaultProviderCommissionBps: result.vaultProviderCommissionBps,\n claimExpiredUntil: result.claimExpiredUntil,\n vaultCoreVersion: result.vaultCoreVersion,\n };\n}\n\n/**\n * Exclusive upper bound for a `uint64` epoch.\n *\n * viem does not range-check a decoded `uint64`, so a misaligned decode can\n * hand back a value far larger than the field can hold. Rejecting those is\n * cheap defence in depth against a mis-decode of the extended ABI.\n *\n * The state this is load-bearing for is narrower than \"a registry that predates\n * RFC-006\". Against a *fully* pre-RFC-006 registry the path fails closed on its\n * own: `resolveParticipantKeysAtEpochs` goes on to call\n * `getOperationBtcKeyAtEpochOrGenesis` on ApplicationRegistry and\n * ProtocolParams, which do not exist there, so the multicall reverts and these\n * epochs are never used. The reachable gap is a registry that *has* the\n * operation-key getters but whose `BTCVaultProtocolInfo` struct is not\n * extended — there the tail-data epochs resolve with no error at all, and this\n * range check is the only thing looking at them.\n *\n * Even for that case it is only a backstop, and a weak one: a misaligned decode\n * can land on a small, plausible-looking integer this range accepts. Correctness\n * rests on only ever pointing at an RFC-006 registry, which is a deployment\n * precondition rather than something this call can establish — see\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2192 for where that\n * check is owned, and `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\nconst UINT64_EXCLUSIVE_UPPER_BOUND = 1n << 64n;\n\n/**\n * The epoch a vault provider's registration key is bonded at.\n *\n * A provider's operation-key history is append-only and every appended version\n * is stamped at epoch 1 or later, so epoch 0 always resolves to the key set at\n * registration. This is what lets `getOperationBtcKeyAtEpoch` stand in for the\n * removed `getVaultProviderBTCKey` getter.\n */\nconst VP_GENESIS_KEY_EPOCH = 0n;\n\n/**\n * Both registration events, queried together so one answer settles whether a\n * vault's V2 log is missing (pre-upgrade registration) or the node served no\n * logs for the block at all.\n */\nconst PEGIN_SUBMITTED_EVENTS = [\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmitted\" }),\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmittedV2\" }),\n] as const;\n\nconst VAULT_CLAIMABLE_BY_EVENT = getAbiItem({\n abi: BTCVaultRegistryABI,\n name: \"VaultClaimableBy\",\n});\n\n/**\n * Block span of one `VaultClaimableBy` query: btc-vault's own scan chunk\n * (`EVENT_QUERY_CHUNK_BLOCKS = 7200`, `crates/eth-client/src/client.rs:793`\n * @ ac4954e7), about a day of Ethereum blocks, so a recent redeem costs one\n * request. Not every provider serves a range this wide — an Alchemy free key\n * caps `eth_getLogs` at 10 blocks\n * (https://www.alchemy.com/docs/reference/eth-getlogs) — and a provider that\n * answered a wide range short instead of erroring would make this scan report\n * not-found, so confirming the RPC honours 7,200-block ranges is a\n * prerequisite of a claim run.\n */\nconst VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS = 7_200n;\n\nfunction maxBigint(a: bigint, b: bigint): bigint {\n return a > b ? a : b;\n}\n\n/**\n * A `PegInSubmittedV2` log's decoded args, as viem's strict `getLogs` hands\n * them back after the `eventName` narrowing.\n */\ninterface PegInSubmittedV2Args {\n vaultId: Hex;\n peginTxHash: Hex;\n depositor: Address;\n vaultProvider: Address;\n amount: bigint;\n vaultCoreVersion: number;\n universalChallengersVersion: number;\n appVaultKeepersVersion: number;\n proverCircuitVersion: number;\n offchainParamsVersion: number;\n depositorPayoutBtcAddress: Hex;\n depositorWotsPkHash: Hex;\n hashlock: Hex;\n htlcVout: number;\n unsignedPrePeginTx: Hex;\n maxAcceptableCommissionBps: number;\n}\n\nfunction mapRegistrationRecord(\n args: PegInSubmittedV2Args,\n blockNumber: bigint,\n): PeginRegistrationRecord {\n // A plain decode of every V2 log in the block, strangers' included: nothing\n // here parses a transaction or bound-checks a script, so one malformed\n // registration elsewhere in the block cannot fail the caller's read. The\n // strict per-record checks live in registration-records.ts. A duplicate\n // vault id is not covered: a vault registers once, so two logs for one id\n // are an inconsistent node and fail the read closed (see the caller).\n return {\n vaultId: args.vaultId.toLowerCase() as Hex,\n depositor: args.depositor,\n vaultProvider: args.vaultProvider,\n amount: args.amount,\n vaultCoreVersion: args.vaultCoreVersion,\n universalChallengersVersion: args.universalChallengersVersion,\n appVaultKeepersVersion: args.appVaultKeepersVersion,\n proverCircuitVersion: args.proverCircuitVersion,\n offchainParamsVersion: args.offchainParamsVersion,\n peginTxHash: args.peginTxHash.toLowerCase() as Hex,\n depositorPayoutScriptPubKey:\n args.depositorPayoutBtcAddress.toLowerCase() as Hex,\n unsignedPrePeginTx: args.unsignedPrePeginTx,\n maxAcceptableCommissionBps: args.maxAcceptableCommissionBps,\n blockNumber,\n };\n}\n\nfunction assertEpochInRange(\n value: bigint,\n field: string,\n vaultId: Hex,\n): bigint {\n if (value < 0n || value >= UINT64_EXCLUSIVE_UPPER_BOUND) {\n throw new Error(\n `getBtcVaultProtocolInfo returned ${field}=${value} for vault ${vaultId}, ` +\n `outside the uint64 range — the registry may predate RFC-006`,\n );\n }\n return value;\n}\n\nfunction mapKeyEpochs(result: KeyEpochs, vaultId: Hex): KeyEpochs {\n return {\n vpKeyEpoch: assertEpochInRange(result.vpKeyEpoch, \"vpKeyEpoch\", vaultId),\n appKeeperKeyEpoch: assertEpochInRange(\n result.appKeeperKeyEpoch,\n \"appKeeperKeyEpoch\",\n vaultId,\n ),\n ucKeyEpoch: assertEpochInRange(result.ucKeyEpoch, \"ucKeyEpoch\", vaultId),\n };\n}\n\n/**\n * Concrete vault registry reader using viem.\n *\n * Usage:\n * ```ts\n * const reader = new ViemVaultRegistryReader(publicClient, registryAddress);\n * const data = await reader.getVaultData(vaultId);\n * ```\n */\nexport class ViemVaultRegistryReader implements VaultRegistryReader {\n constructor(\n private publicClient: PublicClient,\n private contractAddress: Address,\n ) {}\n\n /**\n * Read the VP's **genesis** (registration) x-only BTC pubkey — the key bonded\n * at version 0, which never moves when the operator rotates.\n *\n * Resolved as \"the operation key at epoch 0\" rather than through the\n * dedicated `getVaultProviderBTCKey` getter, which\n * https://github.com/babylonlabs-io/vault-contracts-aave-v4/pull/539 removes.\n * Epoch 0 predates any rotation — appended versions are stamped at epoch 1 or\n * later — so it resolves to the registration key, and the contracts team has\n * confirmed that is a property we can rely on rather than an implementation\n * detail. The devnet comparison behind that claim — both getters returning the\n * identical key for a provider that *has* rotated, while\n * `getCurrentOperationBtcKey` differed — is recorded in\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2188.\n *\n * This makes the read RFC-006-only, where the removed getter also existed on a\n * legacy registry. That costs nothing: every caller of this method already\n * resolves participant keys through `OperationKeyReader`, so all of them\n * require an RFC-006 registry regardless.\n *\n * Validates length, hex form, and secp256k1 curve membership before minting\n * the brand. Returns 64-char lowercase hex without the `0x` prefix.\n */\n async getVaultProviderGenesisBtcPubKey(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<OnChainBtcPubkey> {\n return this.getVaultProviderOperationBtcKeyAtEpoch(\n vpAddress,\n VP_GENESIS_KEY_EPOCH,\n blockNumber,\n );\n }\n\n /**\n * Read the VP operation key selected by `epoch`.\n *\n * This is public rather than hidden inside `OperationKeyReader` because\n * subject-specific VP authentication needs exactly one participant: the\n * gRPC bootstrap is signed by the key frozen into the vault, while the\n * JSON-RPC bootstrap is signed by the provider's live key.\n */\n async getVaultProviderOperationBtcKeyAtEpoch(\n vpAddress: Address,\n epoch: bigint,\n blockNumber?: bigint,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getOperationBtcKeyAtEpoch\",\n args: [vpAddress, epoch],\n blockNumber,\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getOperationBtcKeyAtEpoch (vp=${vpAddress}, epoch=${epoch})`,\n );\n }\n\n /**\n * Read the application entry point a vault provider is registered for.\n *\n * This is the registry's own `vaultProviders[vp].applicationEntryPoint`, and\n * it is the value the peg-in submit path resolves internally — it selects\n * which application's vault-keeper roster, roster version and keeper key\n * epoch a deposit is bonded to. The dApp separately carries an entry point\n * from its own configuration; the two agree today, but they are different\n * sources of truth, so the build path reads this one and asserts the\n * configured value matches it rather than trusting either alone.\n */\n async getVaultProviderApplication(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<Address> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderApplication\",\n args: [vpAddress],\n blockNumber,\n })) as Address;\n }\n\n /**\n * Read a vault provider's *current* RFC-006 operation BTC key.\n *\n * Falls back on-chain to the registration key when the provider has never\n * rotated, so this returns the same value as\n * `getVaultProviderGenesisBtcPubKey` until the first rotation.\n *\n * This is the key the VP's server uses for JSON-RPC-subject authentication.\n * The gRPC-subject bootstrap is instead bound to the existing vault's frozen\n * epoch and resolves through `getVaultProviderOperationBtcKeyAtEpoch`.\n */\n async getCurrentVaultProviderOperationBtcKey(\n vpAddress: Address,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getCurrentOperationBtcKey\",\n args: [vpAddress],\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getCurrentOperationBtcKey (vp=${vpAddress})`,\n );\n }\n\n /**\n * Read a vault's frozen RFC-006 operation-key epochs.\n *\n * Reads `getBtcVaultProtocolInfo` through the **extended** ABI, which is only\n * valid against an RFC-006 registry: against one whose `BTCVaultProtocolInfo`\n * struct is not extended this call does not fail for a populated vault, it\n * silently returns three words of tail data as epochs. Nothing here can detect\n * that, so the guarantee is a deployment one — every network this ships to has\n * the RFC-006 getters, and mainnet is a fresh RFC-006 deploy.\n *\n * A registry missing the operation-key getters entirely is the *safer* of the\n * two cases: `resolveParticipantKeysAtEpochs` reverts downstream and these\n * epochs never reach key resolution. See {@link UINT64_EXCLUSIVE_UPPER_BOUND}\n * for which state the range check actually guards, and\n * `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\n async getVaultKeyEpochs(vaultId: Hex): Promise<KeyEpochs> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as unknown as KeyEpochs;\n\n return mapKeyEpochs(result, vaultId);\n }\n\n async getVaultKeyEpochsBatch(vaultIds: readonly Hex[]): Promise<KeyEpochs[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) =>\n mapKeyEpochs(info as unknown as KeyEpochs, vaultIds[i]),\n );\n }\n\n async getVaultBasicInfo(vaultId: Hex): Promise<VaultBasicInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as RawVaultBasicInfo;\n\n return mapVaultBasicInfo(result);\n }\n\n async getVaultProtocolInfo(vaultId: Hex): Promise<VaultProtocolInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as RawVaultProtocolInfo;\n\n return mapVaultProtocolInfo(result);\n }\n\n async getProtocolInfoBatch(\n vaultIds: readonly Hex[],\n ): Promise<VaultProtocolInfo[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) => {\n const result = info as unknown as RawVaultProtocolInfo;\n if (\n !result.depositorSignedPeginTx ||\n result.depositorSignedPeginTx === \"0x\"\n ) {\n // An empty record is not proof the vault is absent: a lagging RPC\n // node returns HTTP 200 with a zero struct, so no retry below this\n // layer can see it. Single-shot is only safe because the finality\n // gate (`waitForPeginRegistrationDepth`) runs first on the deposit\n // path — move this ahead of it and the read-after-write race returns.\n // The vault app matches this message to render \"still confirming\".\n throw new Error(\n `Vault ${vaultIds[i]} not found on-chain or has no pegin transaction`,\n );\n }\n return mapVaultProtocolInfo(result);\n });\n }\n\n /**\n * Read the protocol pegin fee (in wei) for a given vault provider.\n * Mirrors the `getPegInFee(address)` view on BTCVaultRegistry.\n */\n async getPegInFee(vaultProvider: Address): Promise<bigint> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n }\n\n /**\n * Read a vault provider's current commission in basis points from\n * BTCVaultRegistry. The contract enforces `commissionBps < 10000`, so the\n * legitimate range is `[0, 9999]`; anything outside indicates a wrong\n * contract address or ABI drift and is surfaced as an error rather than\n * trusted.\n */\n async getVaultProviderCommission(vaultProvider: Address): Promise<number> {\n // viem infers `number` from the `uint16` return in the `as const` ABI.\n const bps = await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderCommission\",\n args: [vaultProvider],\n });\n\n if (!Number.isInteger(bps) || bps < 0 || bps > MAX_VP_COMMISSION_BPS) {\n throw new Error(\n `getVaultProviderCommission returned ${bps} bps for ${vaultProvider}, ` +\n `outside the protocol range [0, ${MAX_VP_COMMISSION_BPS}]`,\n );\n }\n\n return bps;\n }\n\n async getVaultData(vaultId: Hex): Promise<VaultData> {\n // One round-trip for both structs (hard-fail): they feed signing/refund/\n // broadcast rebinds, so reading them in a single multicall also pins both\n // to the same block — no basic/protocol skew across two `eth_call`s.\n const [basicRaw, protocolRaw] = await this.publicClient.multicall({\n contracts: [\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n },\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n },\n ],\n allowFailure: false,\n });\n\n const basic = mapVaultBasicInfo(basicRaw);\n const protocol = mapVaultProtocolInfo(protocolRaw);\n\n if (\n !protocol.depositorSignedPeginTx ||\n protocol.depositorSignedPeginTx === \"0x\"\n ) {\n throw new Error(\n `Vault ${vaultId} not found on-chain or has no pegin transaction`,\n );\n }\n\n return { basic, protocol };\n }\n\n /** @inheritdoc */\n async getRegistrationRecordsAtBlock(\n createdAt: bigint,\n ): Promise<PeginRegistrationRecord[]> {\n // Deliberately no `vaultId` topic filter: both events must come back in\n // ONE answer for the empty-vs-missing discriminator below to hold, and\n // viem's multi-event form takes no `args` — so the block's registration\n // logs are fetched whole and ids are matched client-side. strict: a log\n // whose data does not decode against the ABI is dropped (viem\n // parseEventLogs) instead of surfacing as `args: {}`.\n const logs = await this.publicClient.getLogs({\n address: this.contractAddress,\n events: PEGIN_SUBMITTED_EVENTS,\n fromBlock: createdAt,\n toBlock: createdAt,\n strict: true,\n });\n if (logs.length === 0) {\n throw new RegistrationLogsUnavailableError(createdAt);\n }\n\n const records = new Map<string, PeginRegistrationRecord>();\n for (const log of logs) {\n if (log.eventName !== \"PegInSubmittedV2\") continue;\n const record = mapRegistrationRecord(log.args, log.blockNumber);\n // Lenient decoding covers a malformed log, not a duplicate: a vault\n // registers once, so two logs for any id mean the node is inconsistent\n // and every record from this block is suspect — fail closed by design.\n if (records.has(record.vaultId)) {\n throw new Error(\n `Expected one PegInSubmittedV2 log for vault ${record.vaultId} at block ${createdAt}, ` +\n `found more than one`,\n );\n }\n records.set(record.vaultId, record);\n }\n // The registry emits V1 and V2 together on every submission\n // (vault-contracts-aave-v4 `PeginLogic.sol:144-147` @ c559f5c2), so this\n // is as readily a node that served only part of the block as a pre-#548\n // registry — retryable either way.\n if (records.size === 0) {\n throw new RegistrationLogsUnavailableError(\n createdAt,\n `Block ${createdAt} holds ${logs.length} PegInSubmitted registration log(s) but no ` +\n `PegInSubmittedV2 log: either the node served a partial answer for block ${createdAt} ` +\n `(retry, preferably another node) or the registry predates the depositor's commission ` +\n `ceiling (vault-contracts-aave-v4 #548) and the ceiling cannot be recovered on-chain`,\n );\n }\n return [...records.values()];\n }\n\n /**\n * Read the depositor's commission ceiling (`maxAcceptableCommissionBps`)\n * for vaults registered in the same block, from their `PegInSubmittedV2`\n * logs. Returned in `vaultIds` order.\n *\n * The contract bound-checks the ceiling and discards it (PeginLogic.sol,\n * `VaultProviderCommissionExceeded`), so the registration log is its only\n * on-chain source. Vault ids are matched case-insensitively.\n *\n * @throws As {@link getRegistrationRecordsAtBlock}, plus the same typed\n * transient error when a vault has no registration log in its own\n * `createdAt` block.\n */\n async getMaxAcceptableCommissionBpsBatch(\n vaultIds: readonly Hex[],\n createdAt: bigint,\n ): Promise<number[]> {\n if (vaultIds.length === 0) return [];\n\n const records = await this.getRegistrationRecordsAtBlock(createdAt);\n return vaultIds.map(\n (vaultId) =>\n findRegistrationRecord(records, vaultId, createdAt)\n .maxAcceptableCommissionBps,\n );\n }\n\n /** @inheritdoc */\n async getVaultClaimableBy(\n vaultId: Hex,\n claimerPk: Hex,\n createdAt: bigint,\n ): Promise<VaultClaimableByEvent> {\n const claimer = assertOnChainBtcPubkey(\n claimerPk,\n `getVaultClaimableBy claimer (vault=${vaultId})`,\n );\n const claimerTopic = `0x${claimer}` as Hex;\n // viem re-filters the decoded logs client-side against `args`, comparing a\n // bytes32 with `===` against lower-case hex (parseEventLogs.ts:140,172-188).\n const vaultIdTopic = vaultId.toLowerCase() as Hex;\n // Finalized, not latest: the block found here is what the prover proves\n // against, and an unfinalized redeem can reorg away (btc-vault binds the\n // same scan to its finality level, eth-client client.rs:5989-6040).\n const { number: finalized } = await this.publicClient.getBlock({\n blockTag: \"finalized\",\n });\n if (finalized < createdAt) {\n throw new Error(\n `Finalized block ${finalized} is below vault ${vaultId}'s registration block ${createdAt}; ` +\n `the registration is not finalized yet, or the node is behind it`,\n );\n }\n\n // Newest first: the redeem usually trails the tip by far less than it\n // trails the registration. The contract emits every VaultClaimableBy of a\n // vault in one transaction, so the first non-empty chunk is the answer.\n let toBlock = finalized;\n for (;;) {\n const fromBlock = maxBigint(\n createdAt,\n toBlock - VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS + 1n,\n );\n const logs = await this.publicClient.getLogs({\n address: this.contractAddress,\n event: VAULT_CLAIMABLE_BY_EVENT,\n args: { vaultId: vaultIdTopic, claimerPK: claimerTopic },\n fromBlock,\n toBlock,\n strict: true,\n });\n // A redeem emits every VaultClaimableBy of a vault in ONE transaction\n // (RedeemLogic.sol), and `redeemForDepositor` emits the VP's key and\n // then the depositor's — so when those two keys are equal this filter\n // legitimately matches twice. Identical authorizations from one\n // transaction are the same fact; logs spanning transactions are not.\n if (logs.length > 1) {\n const transactions = new Set(logs.map((log) => log.transactionHash));\n if (transactions.size > 1) {\n throw new Error(\n `Found ${logs.length} VaultClaimableBy logs for vault ${vaultId} and claimer ` +\n `${claimerTopic} across ${transactions.size} transactions in blocks ` +\n `${fromBlock}..${toBlock}; a vault is redeemed once, so the node's answer ` +\n `is inconsistent`,\n );\n }\n }\n if (logs.length >= 1) {\n const log = logs[0];\n return {\n blockNumber: log.blockNumber,\n claimerPk: assertOnChainBtcPubkey(\n log.args.claimerPK,\n `VaultClaimableBy.claimerPK (vault=${vaultId})`,\n ),\n peginTxHash: log.args.peginTxHash,\n vaultCoreVersion: log.args.vaultCoreVersion,\n proverCircuitVersion: log.args.proverCircuitVersion,\n offchainParamsVersion: log.args.offchainParamsVersion,\n universalChallengersVersion: log.args.universalChallengersVersion,\n appVaultKeepersVersion: log.args.appVaultKeepersVersion,\n };\n }\n if (fromBlock === createdAt) {\n throw new VaultClaimableByNotFoundError(\n vaultId,\n claimerTopic,\n createdAt,\n finalized,\n );\n }\n toBlock = fromBlock - 1n;\n }\n }\n}\n","import {\n encodeFunctionData,\n isAddressEqual,\n zeroAddress,\n type Address,\n type Chain,\n type Hex,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { handleContractError } from \"../../contracts/errors\";\nimport {\n capMaxAcceptableCommissionBps,\n COMMISSION_BPS_HEADROOM,\n} from \"../../deposit-terms/commissionCeiling\";\nimport { waitForTransactionReceiptSmartAware } from \"../../utils/eth\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertPayoutScriptMatchesPopKey } from \"./payout-script\";\nimport { calculateBtcTxHash, derivePeginVaultId } from \"./pegin-transaction\";\nimport { ViemVaultRegistryReader } from \"./vault-registry-reader\";\n\n/** Referral code sent with peg-in registration. Zero means no referral. */\nexport const NO_REFERRAL_CODE = 0;\nconst UINT8_MAX = 255;\n// Match the prior vault-service timeout. A dropped transaction must not wait forever.\nconst RECEIPT_TIMEOUT_MS = 120_000;\n\nfunction ensureHex(value: string, label: string): Hex {\n const prefixed = value.startsWith(\"0x\")\n ? value\n : value.startsWith(\"0X\")\n ? `0x${value.slice(2)}`\n : `0x${value}`;\n if (!/^0x(?:[0-9a-fA-F]{2})+$/.test(prefixed)) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n return prefixed as Hex;\n}\n\nfunction assertBytes32(value: Hex, label: string): void {\n if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {\n throw new Error(`${label} must be a 32-byte hex value`);\n }\n}\n\n/** All-zero `bytes32` — the shape an unresolved fingerprint takes. */\nconst ZERO_BYTES32 =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n\n/**\n * The single validation point for `expectedFingerprint`, on both the singular\n * and batch paths.\n *\n * Zero is rejected separately from the shape check because it is a *well-formed*\n * `bytes32` that the registry can never accept — the live fingerprint is a\n * keccak256 over a domain-separated preimage — so it can only ever mean the\n * caller had no value and filled the slot. Catching it here turns a defaulted\n * field into a named error instead of an opaque on-chain revert with two\n * hashes and no hint.\n */\nfunction assertFingerprint(value: Hex): void {\n assertBytes32(value, \"expectedFingerprint\");\n if (value.toLowerCase() === ZERO_BYTES32) {\n throw new Error(\n \"expectedFingerprint must not be zero: the registry cannot resolve a \" +\n \"zero fingerprint, so this submission would always revert\",\n );\n }\n}\n\nfunction assertHtlcVout(value: number): void {\n if (!Number.isInteger(value) || value < 0 || value > UINT8_MAX) {\n throw new Error(`htlcVout must be a uint8, got ${value}`);\n }\n}\n\n/** A PoP prepared by a Bitcoin wallet, reusable by the ETH submit client. */\nexport interface PopSignature {\n btcPopSignature: Hex;\n depositorEthAddress: Address;\n /** x-only secp256k1 public key, 64 hex chars without `0x`. */\n depositorBtcPubkey: string;\n}\n\nexport interface ViemPeginRegistrationClientConfig {\n ethWallet: WalletClient;\n ethChain: Chain;\n publicClient: PublicClient;\n btcVaultRegistry: Address;\n receiptTimeoutMs?: number;\n /**\n * Refuse to register without a `quotedCommissionBps`. Set it to `true` when\n * the depositor approved deposit terms on a device: approval froze the\n * commission ceiling from the quote, so the chain-current fallback could\n * admit a commission the device would later refuse to pay out.\n *\n * Required, with no default: an omitted flag would silently pick the unsafe\n * direction for the integrator least able to probe the wallet capability.\n */\n requireQuotedCommissionBps: boolean;\n}\n\nexport interface RegisterPeginOnChainParams {\n unsignedPrePeginTx: string;\n depositorSignedPeginTx: string;\n vaultProvider: Address;\n hashlock: Hex;\n depositorWotsPkHash: Hex;\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n quotedCommissionBps?: number;\n /**\n * `keccak256(abi.encode(...))` over the protocol state the Pre-PegIn was\n * built against — see the SDK's `pegin-fingerprint` module.\n *\n * The registry recomputes it live at inclusion and reverts with\n * `PeginFingerprintChanged` on any difference, so it must be computed from\n * the same block-pinned snapshot that shaped the Bitcoin scripts. Required,\n * with no default: a fingerprint the caller did not resolve is not a\n * fingerprint, and the registry has no way to tell the two apart.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface PeginRegistrationResult {\n ethTxHash: Hex;\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface BatchPeginRegistrationItem {\n depositorSignedPeginTx: string;\n hashlock: Hex;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n depositorWotsPkHash: Hex;\n}\n\nexport interface RegisterPeginBatchOnChainParams {\n vaultProvider: Address;\n unsignedPrePeginTx: string;\n requests: BatchPeginRegistrationItem[];\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n quotedCommissionBps?: number;\n /**\n * See {@link RegisterPeginOnChainParams.expectedFingerprint}. One value for\n * the whole batch: the fingerprint takes no per-request input and a batch\n * fixes one vault provider, so every entry would resolve the same value.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface BatchPeginRegistrationResultItem {\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface PeginBatchRegistrationResult {\n ethTxHash: Hex;\n vaults: BatchPeginRegistrationResultItem[];\n}\n\n/**\n * Ethereum-only client for the on-chain half of peg-in registration.\n *\n * It consumes Bitcoin artifacts that were prepared earlier, but owns no BTC\n * wallet and imports neither Bitcoin libraries nor the Rust/WASM package.\n */\nexport class ViemPeginRegistrationClient {\n constructor(private readonly config: ViemPeginRegistrationClientConfig) {}\n\n async registerPeginOnChain(\n params: RegisterPeginOnChainParams,\n ): Promise<PeginRegistrationResult> {\n const request = {\n ...params,\n popSignature: { ...params.popSignature },\n };\n this.assertQuotedCommissionPresentWhenRequired(request.quotedCommissionBps);\n // Second, matching the batch path, so the two public entry points validate\n // in the same order and neither can drift behind a chain call.\n assertFingerprint(request.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(request.popSignature);\n const depositorBtcPubkey = this.normalizeBtcPubkey(request.popSignature);\n const btcPopSignature = ensureHex(\n request.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n const normalized = this.normalizeRequest(\n request,\n depositor,\n depositorBtcPubkey,\n );\n\n await this.assertVaultDoesNotExist(\n normalized.vaultId,\n normalized.peginTxHash,\n );\n const peginFee = await this.readPeginFee(request.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n request.vaultProvider,\n request.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequest\",\n args: [\n depositor,\n depositorBtcPubkey,\n btcPopSignature,\n normalized.unsignedPrePeginTx,\n normalized.depositorSignedPeginTx,\n request.vaultProvider,\n maxCommission,\n request.hashlock,\n request.htlcVout,\n normalized.payoutScript,\n request.depositorWotsPkHash,\n // Appended last on the singular overload; the batch takes it at\n // position 4 instead. Order is the selector, so do not \"tidy\" either.\n request.expectedFingerprint,\n ],\n });\n\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee,\n false,\n depositor,\n );\n return {\n ethTxHash,\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n };\n }\n\n async registerPeginBatchOnChain(\n params: RegisterPeginBatchOnChainParams,\n ): Promise<PeginBatchRegistrationResult> {\n const batch = {\n ...params,\n popSignature: { ...params.popSignature },\n requests: params.requests.map((request) => ({ ...request })),\n };\n if (batch.requests.length === 0) {\n throw new Error(\"Batch pegin requires at least one request\");\n }\n this.assertQuotedCommissionPresentWhenRequired(batch.quotedCommissionBps);\n assertFingerprint(batch.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(batch.popSignature);\n const unsignedPrePeginTx = ensureHex(\n batch.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorBtcPubkey = this.normalizeBtcPubkey(batch.popSignature);\n const btcPopSignature = ensureHex(\n batch.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n\n const vaults: BatchPeginRegistrationResultItem[] = [];\n const requests = [];\n const seenVaultIds = new Set<string>();\n for (const request of batch.requests) {\n const normalized = this.normalizeRequest(\n {\n ...request,\n unsignedPrePeginTx: batch.unsignedPrePeginTx,\n vaultProvider: batch.vaultProvider,\n depositorBtcPubkeyRaw: batch.depositorBtcPubkeyRaw,\n },\n depositor,\n depositorBtcPubkey,\n );\n if (seenVaultIds.has(normalized.vaultId)) {\n throw new Error(`Duplicate vault in batch: ${normalized.vaultId}`);\n }\n seenVaultIds.add(normalized.vaultId);\n vaults.push({\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n });\n requests.push({\n depositorBtcPubKey: depositorBtcPubkey,\n btcPopSignature,\n unsignedPrePeginTx,\n depositorSignedPeginTx: normalized.depositorSignedPeginTx,\n hashlock: request.hashlock,\n htlcVout: request.htlcVout,\n referralCode: NO_REFERRAL_CODE,\n depositorPayoutBtcAddress: normalized.payoutScript,\n depositorWotsPkHash: request.depositorWotsPkHash,\n });\n }\n for (const vault of vaults) {\n await this.assertVaultDoesNotExist(vault.vaultId, vault.peginTxHash);\n }\n\n const peginFee = await this.readPeginFee(batch.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n batch.vaultProvider,\n batch.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequestBatch\",\n // `expectedFingerprint` sits BEFORE `requests`, not appended. Reordering\n // these five changes the selector and the call stops existing.\n args: [\n depositor,\n batch.vaultProvider,\n maxCommission,\n batch.expectedFingerprint,\n requests,\n ],\n });\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee * BigInt(batch.requests.length),\n true,\n depositor,\n );\n return { ethTxHash, vaults };\n }\n\n private assertQuotedCommissionPresentWhenRequired(\n quotedCommissionBps?: number,\n ): void {\n if (\n quotedCommissionBps === undefined &&\n this.config.requireQuotedCommissionBps\n ) {\n throw new Error(\n \"quotedCommissionBps is required when the wallet approved deposit \" +\n \"terms: the registration ceiling must anchor to the approved quote.\",\n );\n }\n }\n\n private assertPopMatchesEthAccount(pop: PopSignature): Address {\n return this.assertEthAccount(pop.depositorEthAddress);\n }\n\n private assertEthAccount(expectedDepositor: Address): Address {\n const account = this.config.ethWallet.account;\n if (!account) throw new Error(\"Ethereum wallet account not found\");\n if (!isAddressEqual(expectedDepositor, account.address)) {\n throw new Error(\n `Proof of possession was signed for ${expectedDepositor} ` +\n `but the Ethereum wallet is currently connected to ${account.address}. ` +\n `Reconnect the original account or sign a new proof of possession.`,\n );\n }\n return account.address;\n }\n\n private normalizeBtcPubkey(pop: PopSignature): Hex {\n return `0x${assertOnChainBtcPubkey(\n ensureHex(pop.depositorBtcPubkey, \"Proof of possession BTC pubkey\"),\n \"Proof of possession BTC pubkey\",\n )}`;\n }\n\n // `expectedFingerprint` is omitted rather than accepted and ignored: nothing\n // here normalizes it, and requiring it would force the batch loop to thread a\n // value through a per-request helper that has no use for it. It is validated\n // once per call, at the top of each public method.\n private normalizeRequest(\n params: Omit<\n RegisterPeginOnChainParams,\n \"popSignature\" | \"expectedFingerprint\"\n >,\n depositor: Address,\n depositorBtcPubkey: Hex,\n ) {\n assertBytes32(params.hashlock, \"hashlock\");\n assertBytes32(params.depositorWotsPkHash, \"depositorWotsPkHash\");\n assertHtlcVout(params.htlcVout);\n const unsignedPrePeginTx = ensureHex(\n params.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorSignedPeginTx = ensureHex(\n params.depositorSignedPeginTx,\n \"depositorSignedPeginTx\",\n );\n const peginTxHash = calculateBtcTxHash(depositorSignedPeginTx);\n return {\n unsignedPrePeginTx,\n depositorSignedPeginTx,\n payoutScript: assertPayoutScriptMatchesPopKey(\n params.depositorPayoutScriptPubKey,\n depositorBtcPubkey,\n params.depositorBtcPubkeyRaw,\n ),\n peginTxHash,\n vaultId: ensureHex(derivePeginVaultId(peginTxHash, depositor), \"vaultId\"),\n };\n }\n\n private async assertVaultDoesNotExist(\n vaultId: Hex,\n peginTxHash: Hex,\n ): Promise<void> {\n const result = (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as { depositor: Address };\n if (result.depositor !== zeroAddress) {\n throw new Error(\n `Vault already exists (ID: ${vaultId}, peginTxHash: ${peginTxHash}). ` +\n `Vault IDs are derived from the pegin transaction hash and depositor address. ` +\n `To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`,\n );\n }\n }\n\n private async readPeginFee(vaultProvider: Address): Promise<bigint> {\n try {\n return (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n } catch (error) {\n throw new Error(\n \"Failed to query pegin fee from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n }\n\n private async resolveMaxAcceptableCommissionBps(\n vaultProvider: Address,\n quotedCommissionBps?: number,\n ): Promise<number> {\n let currentBps: number;\n try {\n currentBps = await new ViemVaultRegistryReader(\n this.config.publicClient,\n this.config.btcVaultRegistry,\n ).getVaultProviderCommission(vaultProvider);\n } catch (error) {\n throw new Error(\n \"Failed to query vault provider commission from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n if (quotedCommissionBps !== undefined) {\n if (currentBps > quotedCommissionBps + COMMISSION_BPS_HEADROOM) {\n throw new Error(\n `Vault provider commission changed since quote: quoted ${quotedCommissionBps} bps, ` +\n `chain currently reports ${currentBps} bps (allowed drift ${COMMISSION_BPS_HEADROOM} bps). ` +\n `Please refresh and try again.`,\n );\n }\n return capMaxAcceptableCommissionBps(quotedCommissionBps);\n }\n return capMaxAcceptableCommissionBps(currentBps);\n }\n\n private async sendAndWait(\n data: Hex,\n value: bigint,\n batch: boolean,\n depositor: Address,\n ): Promise<Hex> {\n let account = this.assertEthAccount(depositor);\n let gas: bigint;\n try {\n gas = await this.config.publicClient.estimateGas({\n to: this.config.btcVaultRegistry,\n data,\n value,\n account,\n });\n } catch (error) {\n handleContractError(error);\n }\n\n account = this.assertEthAccount(depositor);\n let submittedHash: Hex;\n try {\n submittedHash = await this.config.ethWallet.sendTransaction({\n to: this.config.btcVaultRegistry,\n data,\n value,\n gas,\n account,\n chain: this.config.ethChain,\n });\n } catch (error) {\n handleContractError(error);\n }\n const receipt = await waitForTransactionReceiptSmartAware({\n publicClient: this.config.publicClient,\n walletAddress: depositor,\n hash: submittedHash,\n timeout: this.config.receiptTimeoutMs ?? RECEIPT_TIMEOUT_MS,\n });\n if (receipt.status === \"reverted\") {\n handleContractError(\n new Error(\n `${batch ? \"Batch transaction\" : \"Transaction\"} reverted. ` +\n `Hash: ${receipt.transactionHash}. Check a block explorer for details.`,\n ),\n );\n }\n return receipt.transactionHash;\n }\n}\n"],"names":["COMMISSION_BPS_HEADROOM","MAX_ACCEPTABLE_COMMISSION_BPS_CAP","capMaxAcceptableCommissionBps","bps","MAX_VP_COMMISSION_BPS_EXCLUSIVE","MAX_VP_COMMISSION_BPS","mapVaultBasicInfo","result","mapVaultProtocolInfo","offchainParamsVersion","assertValidOffchainParamsVersion","UINT64_EXCLUSIVE_UPPER_BOUND","VP_GENESIS_KEY_EPOCH","PEGIN_SUBMITTED_EVENTS","getAbiItem","BTCVaultRegistryABI","VAULT_CLAIMABLE_BY_EVENT","VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS","maxBigint","a","b","mapRegistrationRecord","args","blockNumber","assertEpochInRange","value","field","vaultId","mapKeyEpochs","ViemVaultRegistryReader","publicClient","contractAddress","vpAddress","epoch","assertOnChainBtcPubkey","BTCVaultRegistryKeyEpochsABI","vaultIds","info","i","vaultProvider","basicRaw","protocolRaw","basic","protocol","createdAt","logs","RegistrationLogsUnavailableError","records","log","record","findRegistrationRecord","claimerPk","claimerTopic","vaultIdTopic","finalized","toBlock","fromBlock","transactions","VaultClaimableByNotFoundError","NO_REFERRAL_CODE","UINT8_MAX","RECEIPT_TIMEOUT_MS","ensureHex","label","prefixed","assertBytes32","ZERO_BYTES32","assertFingerprint","assertHtlcVout","ViemPeginRegistrationClient","config","params","request","depositor","depositorBtcPubkey","btcPopSignature","normalized","peginFee","maxCommission","callData","encodeFunctionData","batch","unsignedPrePeginTx","vaults","requests","seenVaultIds","vault","quotedCommissionBps","pop","expectedDepositor","account","isAddressEqual","depositorSignedPeginTx","peginTxHash","calculateBtcTxHash","assertPayoutScriptMatchesPopKey","derivePeginVaultId","zeroAddress","error","currentBps","data","gas","handleContractError","submittedHash","receipt","waitForTransactionReceiptSmartAware"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pegin-registration-client-Cvjk4ILq.js","sources":["../src/tbv/core/deposit-terms/commissionCeiling.ts","../src/tbv/core/clients/eth/vault-registry-reader.ts","../src/tbv/core/clients/eth/pegin-registration-client.ts"],"sourcesContent":["/**\n * The depositor's commission ceiling (`maxAcceptableCommissionBps`) policy:\n * quoted VP commission + drift headroom, capped below the contract's\n * exclusive bound. Shared by `PeginManager` (the approved terms) and the\n * registration calldata so both carry the same ceiling; a resume rebuild reads\n * that submitted value back from the `PegInSubmittedV2` log instead.\n *\n * @module deposit-terms/commissionCeiling\n */\n\n/*\n * Commission-check map (each guards a DIFFERENT boundary — do not consolidate):\n * 1. assertVpCommissionInProtocolRange (vault app, vaultPayoutSignatureService)\n * — chain-read trust boundary; mirrors VPKeyRegistryLogic.sol bounds.\n * 2. capMaxAcceptableCommissionBps (here) — depositor quote → ceiling policy;\n * mirrors PeginLogic.sol's strict > check via the +25bps headroom.\n * 3. buildDepositTerms range check — public-API precondition on the projection\n * that mints the device-enforced commissionFee.\n * 4. payout.ts commission cap — the VP-built tx's output value vs bps at the\n * signing site (CLAUDE.md Critical Path #3).\n * 5. envelope.ts dust/cross-field gates (ledger-vault-signer) — firmware-only\n * constants, pre-device-I/O (Critical Path #7).\n */\n\nimport { MAX_VP_COMMISSION_BPS_EXCLUSIVE } from \"../primitives/psbt/constants\";\n\n/**\n * Headroom (in basis points) added to the current VP commission to compute\n * `maxAcceptableCommissionBps` at submit time. Lets the VP raise its\n * commission by up to this amount between read and submit without forcing\n * a re-quote. Capped by {@link MAX_ACCEPTABLE_COMMISSION_BPS_CAP}.\n *\n * Contract check is strict `>` (PeginLogic.sol `VaultProviderCommissionExceeded`\n * revert), so +25 allows up\n * to +25 bps of drift.\n */\nexport const COMMISSION_BPS_HEADROOM = 25;\n\n/**\n * Hard ceiling for `maxAcceptableCommissionBps`. The contract enforces\n * `commissionBps < 10000`, so any value at/above that is unreachable;\n * `9999` is the maximum useful cap.\n */\nexport const MAX_ACCEPTABLE_COMMISSION_BPS_CAP = 9999;\n\n/**\n * The commission ceiling submitted as registration calldata and mirrored\n * into `DepositTerms.commissionFee`: quoted + drift headroom, capped.\n * Single source for both consumers — feed it the SAME quoted bps at prepare\n * and register time so device-accept stays coextensive with contract-accept.\n */\nexport function capMaxAcceptableCommissionBps(bps: number): number {\n // Validate the raw quote before headroom shifts its domain — a negative\n // quote must throw here, not become a small \"legal\" ceiling.\n // Reject an out-of-range quote outright — clamping it to 9999 would turn a\n // bad read into a 99.99% ceiling, the exact failure the cap exists to stop.\n if (\n !Number.isInteger(bps) ||\n bps < 0 ||\n bps >= MAX_VP_COMMISSION_BPS_EXCLUSIVE\n ) {\n throw new Error(\n `Quoted commissionBps must be an integer in ` +\n `[0, ${MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${bps}`,\n );\n }\n return Math.min(\n bps + COMMISSION_BPS_HEADROOM,\n MAX_ACCEPTABLE_COMMISSION_BPS_CAP,\n );\n}\n","/**\n * Concrete BTCVaultRegistry reader using viem's readContract.\n *\n * This is an optional utility — callers can use their own implementation\n * of the VaultRegistryReader interface.\n */\n\nimport type { Abi, Address, Hex, PublicClient } from \"viem\";\nimport { getAbiItem } from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { BTCVaultRegistryKeyEpochsABI } from \"../../contracts/abis/BTCVaultRegistryKeyEpochs.abi\";\nimport { VaultClaimableByNotFoundError } from \"./claimable-event-error\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertValidOffchainParamsVersion } from \"./protocol-params-validation\";\nimport { RegistrationLogsUnavailableError } from \"./registration-logs-error\";\nimport { findRegistrationRecord } from \"./registration-records\";\nimport type {\n KeyEpochs,\n OnChainBtcPubkey,\n PeginRegistrationRecord,\n VaultBasicInfo,\n VaultClaimableByEvent,\n VaultData,\n VaultProtocolInfo,\n VaultRegistryReader,\n} from \"./types\";\n\n/**\n * Inclusive upper bound the BTCVaultRegistry contract enforces on a vault\n * provider's commission (the contract check is `< 10000`).\n */\nconst MAX_VP_COMMISSION_BPS = 9999;\n\n/** Raw `getBtcVaultBasicInfo` tuple as decoded by viem. */\ntype RawVaultBasicInfo = {\n depositor: Address;\n depositorBtcPubKey: Hex;\n amount: bigint;\n vaultProvider: Address;\n status: number;\n applicationEntryPoint: Address;\n createdAt: bigint;\n};\n\n/**\n * Raw `getBtcVaultProtocolInfo` tuple as decoded by viem.\n *\n * Mirrors the ABI's components. The trailing key epochs are read through the\n * separate key-epochs ABI, so this prefix stops at `vaultCoreVersion`.\n */\ntype RawVaultProtocolInfo = {\n depositorSignedPeginTx: Hex;\n universalChallengersVersion: number;\n appVaultKeepersVersion: number;\n offchainParamsVersion: number;\n verifiedAt: bigint;\n depositorWotsPkHash: Hex;\n hashlock: Hex;\n htlcVout: number;\n depositorPopSignature: Hex;\n prePeginTxHash: Hex;\n vaultProviderCommissionBps: number;\n claimExpiredUntil: bigint;\n vaultCoreVersion: number;\n};\n\nfunction mapVaultBasicInfo(result: RawVaultBasicInfo): VaultBasicInfo {\n return {\n depositor: result.depositor,\n depositorBtcPubKey: result.depositorBtcPubKey,\n amount: result.amount,\n vaultProvider: result.vaultProvider,\n status: result.status,\n applicationEntryPoint: result.applicationEntryPoint,\n createdAt: result.createdAt,\n };\n}\n\nfunction mapVaultProtocolInfo(result: RawVaultProtocolInfo): VaultProtocolInfo {\n const offchainParamsVersion = Number(result.offchainParamsVersion);\n assertValidOffchainParamsVersion(offchainParamsVersion);\n return {\n depositorSignedPeginTx: result.depositorSignedPeginTx,\n universalChallengersVersion: result.universalChallengersVersion,\n appVaultKeepersVersion: result.appVaultKeepersVersion,\n offchainParamsVersion,\n verifiedAt: result.verifiedAt,\n depositorWotsPkHash: result.depositorWotsPkHash,\n hashlock: result.hashlock,\n htlcVout: result.htlcVout,\n depositorPopSignature: result.depositorPopSignature,\n prePeginTxHash: result.prePeginTxHash,\n vaultProviderCommissionBps: result.vaultProviderCommissionBps,\n claimExpiredUntil: result.claimExpiredUntil,\n vaultCoreVersion: result.vaultCoreVersion,\n };\n}\n\n/**\n * Exclusive upper bound for a `uint64` epoch.\n *\n * viem does not range-check a decoded `uint64`, so a misaligned decode can\n * hand back a value far larger than the field can hold. Rejecting those is\n * cheap defence in depth against a mis-decode of the extended ABI.\n *\n * The state this is load-bearing for is narrower than \"a registry that predates\n * RFC-006\". Against a *fully* pre-RFC-006 registry the path fails closed on its\n * own: `resolveParticipantKeysAtEpochs` goes on to call\n * `getOperationBtcKeyAtEpochOrGenesis` on ApplicationRegistry and\n * ProtocolParams, which do not exist there, so the multicall reverts and these\n * epochs are never used. The reachable gap is a registry that *has* the\n * operation-key getters but whose `BTCVaultProtocolInfo` struct is not\n * extended — there the tail-data epochs resolve with no error at all, and this\n * range check is the only thing looking at them.\n *\n * Even for that case it is only a backstop, and a weak one: a misaligned decode\n * can land on a small, plausible-looking integer this range accepts. Correctness\n * rests on only ever pointing at an RFC-006 registry, which is a deployment\n * precondition rather than something this call can establish — see\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2192 for where that\n * check is owned, and `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\nconst UINT64_EXCLUSIVE_UPPER_BOUND = 1n << 64n;\n\n/**\n * The epoch a vault provider's registration key is bonded at.\n *\n * A provider's operation-key history is append-only and every appended version\n * is stamped at epoch 1 or later, so epoch 0 always resolves to the key set at\n * registration. This is what lets `getOperationBtcKeyAtEpoch` stand in for the\n * removed `getVaultProviderBTCKey` getter.\n */\nconst VP_GENESIS_KEY_EPOCH = 0n;\n\n/**\n * Both registration events, queried together so one answer settles whether a\n * vault's V2 log is missing (pre-upgrade registration) or the node served no\n * logs for the block at all.\n */\nconst PEGIN_SUBMITTED_EVENTS = [\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmitted\" }),\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmittedV2\" }),\n] as const;\n\nconst VAULT_CLAIMABLE_BY_EVENT = getAbiItem({\n abi: BTCVaultRegistryABI,\n name: \"VaultClaimableBy\",\n});\n\n/**\n * Block span of one `VaultClaimableBy` query: btc-vault's own scan chunk\n * (`EVENT_QUERY_CHUNK_BLOCKS = 7200`, `crates/eth-client/src/client.rs:793`\n * @ ac4954e7), about a day of Ethereum blocks, so a recent redeem costs one\n * request. Not every provider serves a range this wide — an Alchemy free key\n * caps `eth_getLogs` at 10 blocks\n * (https://www.alchemy.com/docs/reference/eth-getlogs) — and a provider that\n * answered a wide range short instead of erroring would make this scan report\n * not-found, so confirming the RPC honours 7,200-block ranges is a\n * prerequisite of a claim run.\n */\nconst VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS = 7_200n;\n\nfunction maxBigint(a: bigint, b: bigint): bigint {\n return a > b ? a : b;\n}\n\n/**\n * A `PegInSubmittedV2` log's decoded args, as viem's strict `getLogs` hands\n * them back after the `eventName` narrowing.\n */\ninterface PegInSubmittedV2Args {\n vaultId: Hex;\n peginTxHash: Hex;\n depositor: Address;\n vaultProvider: Address;\n amount: bigint;\n vaultCoreVersion: number;\n universalChallengersVersion: number;\n appVaultKeepersVersion: number;\n proverCircuitVersion: number;\n offchainParamsVersion: number;\n depositorPayoutBtcAddress: Hex;\n depositorWotsPkHash: Hex;\n hashlock: Hex;\n htlcVout: number;\n unsignedPrePeginTx: Hex;\n maxAcceptableCommissionBps: number;\n}\n\nfunction mapRegistrationRecord(\n args: PegInSubmittedV2Args,\n blockNumber: bigint,\n): PeginRegistrationRecord {\n // A plain decode of every V2 log in the block, strangers' included: nothing\n // here parses a transaction or bound-checks a script, so one malformed\n // registration elsewhere in the block cannot fail the caller's read. The\n // strict per-record checks live in registration-records.ts. A duplicate\n // vault id is not covered: a vault registers once, so two logs for one id\n // are an inconsistent node and fail the read closed (see the caller).\n return {\n vaultId: args.vaultId.toLowerCase() as Hex,\n depositor: args.depositor,\n vaultProvider: args.vaultProvider,\n amount: args.amount,\n vaultCoreVersion: args.vaultCoreVersion,\n universalChallengersVersion: args.universalChallengersVersion,\n appVaultKeepersVersion: args.appVaultKeepersVersion,\n proverCircuitVersion: args.proverCircuitVersion,\n offchainParamsVersion: args.offchainParamsVersion,\n peginTxHash: args.peginTxHash.toLowerCase() as Hex,\n depositorPayoutScriptPubKey:\n args.depositorPayoutBtcAddress.toLowerCase() as Hex,\n unsignedPrePeginTx: args.unsignedPrePeginTx,\n maxAcceptableCommissionBps: args.maxAcceptableCommissionBps,\n blockNumber,\n };\n}\n\nfunction assertEpochInRange(\n value: bigint,\n field: string,\n vaultId: Hex,\n): bigint {\n if (value < 0n || value >= UINT64_EXCLUSIVE_UPPER_BOUND) {\n throw new Error(\n `getBtcVaultProtocolInfo returned ${field}=${value} for vault ${vaultId}, ` +\n `outside the uint64 range — the registry may predate RFC-006`,\n );\n }\n return value;\n}\n\nfunction mapKeyEpochs(result: KeyEpochs, vaultId: Hex): KeyEpochs {\n return {\n vpKeyEpoch: assertEpochInRange(result.vpKeyEpoch, \"vpKeyEpoch\", vaultId),\n appKeeperKeyEpoch: assertEpochInRange(\n result.appKeeperKeyEpoch,\n \"appKeeperKeyEpoch\",\n vaultId,\n ),\n ucKeyEpoch: assertEpochInRange(result.ucKeyEpoch, \"ucKeyEpoch\", vaultId),\n };\n}\n\n/**\n * Concrete vault registry reader using viem.\n *\n * Usage:\n * ```ts\n * const reader = new ViemVaultRegistryReader(publicClient, registryAddress);\n * const data = await reader.getVaultData(vaultId);\n * ```\n */\nexport class ViemVaultRegistryReader implements VaultRegistryReader {\n constructor(\n private publicClient: PublicClient,\n private contractAddress: Address,\n ) {}\n\n /**\n * Read the VP's **genesis** (registration) x-only BTC pubkey — the key bonded\n * at version 0, which never moves when the operator rotates.\n *\n * Resolved as \"the operation key at epoch 0\" rather than through the\n * dedicated `getVaultProviderBTCKey` getter, which\n * https://github.com/babylonlabs-io/vault-contracts-aave-v4/pull/539 removes.\n * Epoch 0 predates any rotation — appended versions are stamped at epoch 1 or\n * later — so it resolves to the registration key, and the contracts team has\n * confirmed that is a property we can rely on rather than an implementation\n * detail. The devnet comparison behind that claim — both getters returning the\n * identical key for a provider that *has* rotated, while\n * `getCurrentOperationBtcKey` differed — is recorded in\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2188.\n *\n * This makes the read RFC-006-only, where the removed getter also existed on a\n * legacy registry. That costs nothing: every caller of this method already\n * resolves participant keys through `OperationKeyReader`, so all of them\n * require an RFC-006 registry regardless.\n *\n * Validates length, hex form, and secp256k1 curve membership before minting\n * the brand. Returns 64-char lowercase hex without the `0x` prefix.\n */\n async getVaultProviderGenesisBtcPubKey(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<OnChainBtcPubkey> {\n return this.getVaultProviderOperationBtcKeyAtEpoch(\n vpAddress,\n VP_GENESIS_KEY_EPOCH,\n blockNumber,\n );\n }\n\n /**\n * Read the VP operation key selected by `epoch`.\n *\n * This is public rather than hidden inside `OperationKeyReader` because\n * subject-specific VP authentication needs exactly one participant: the\n * gRPC bootstrap is signed by the key frozen into the vault, while the\n * JSON-RPC bootstrap is signed by the provider's live key.\n */\n async getVaultProviderOperationBtcKeyAtEpoch(\n vpAddress: Address,\n epoch: bigint,\n blockNumber?: bigint,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getOperationBtcKeyAtEpoch\",\n args: [vpAddress, epoch],\n blockNumber,\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getOperationBtcKeyAtEpoch (vp=${vpAddress}, epoch=${epoch})`,\n );\n }\n\n /**\n * Read the application entry point a vault provider is registered for.\n *\n * This is the registry's own `vaultProviders[vp].applicationEntryPoint`, and\n * it is the value the peg-in submit path resolves internally — it selects\n * which application's vault-keeper roster, roster version and keeper key\n * epoch a deposit is bonded to. The dApp separately carries an entry point\n * from its own configuration; the two agree today, but they are different\n * sources of truth, so the build path reads this one and asserts the\n * configured value matches it rather than trusting either alone.\n */\n async getVaultProviderApplication(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<Address> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderApplication\",\n args: [vpAddress],\n blockNumber,\n })) as Address;\n }\n\n /**\n * Read a vault provider's *current* RFC-006 operation BTC key.\n *\n * Falls back on-chain to the registration key when the provider has never\n * rotated, so this returns the same value as\n * `getVaultProviderGenesisBtcPubKey` until the first rotation.\n *\n * This is the key the VP's server uses for JSON-RPC-subject authentication.\n * The gRPC-subject bootstrap is instead bound to the existing vault's frozen\n * epoch and resolves through `getVaultProviderOperationBtcKeyAtEpoch`.\n */\n async getCurrentVaultProviderOperationBtcKey(\n vpAddress: Address,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getCurrentOperationBtcKey\",\n args: [vpAddress],\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getCurrentOperationBtcKey (vp=${vpAddress})`,\n );\n }\n\n /**\n * Read a vault's frozen RFC-006 operation-key epochs.\n *\n * Reads `getBtcVaultProtocolInfo` through the **extended** ABI, which is only\n * valid against an RFC-006 registry: against one whose `BTCVaultProtocolInfo`\n * struct is not extended this call does not fail for a populated vault, it\n * silently returns three words of tail data as epochs. Nothing here can detect\n * that, so the guarantee is a deployment one — every network this ships to has\n * the RFC-006 getters, and mainnet is a fresh RFC-006 deploy.\n *\n * A registry missing the operation-key getters entirely is the *safer* of the\n * two cases: `resolveParticipantKeysAtEpochs` reverts downstream and these\n * epochs never reach key resolution. See {@link UINT64_EXCLUSIVE_UPPER_BOUND}\n * for which state the range check actually guards, and\n * `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\n async getVaultKeyEpochs(vaultId: Hex): Promise<KeyEpochs> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as unknown as KeyEpochs;\n\n return mapKeyEpochs(result, vaultId);\n }\n\n async getVaultKeyEpochsBatch(vaultIds: readonly Hex[]): Promise<KeyEpochs[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) =>\n mapKeyEpochs(info as unknown as KeyEpochs, vaultIds[i]),\n );\n }\n\n async getVaultBasicInfo(vaultId: Hex): Promise<VaultBasicInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as RawVaultBasicInfo;\n\n return mapVaultBasicInfo(result);\n }\n\n async getVaultProtocolInfo(vaultId: Hex): Promise<VaultProtocolInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as RawVaultProtocolInfo;\n\n return mapVaultProtocolInfo(result);\n }\n\n async getProtocolInfoBatch(\n vaultIds: readonly Hex[],\n ): Promise<VaultProtocolInfo[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) => {\n const result = info as unknown as RawVaultProtocolInfo;\n if (\n !result.depositorSignedPeginTx ||\n result.depositorSignedPeginTx === \"0x\"\n ) {\n // An empty record is not proof the vault is absent: a lagging RPC\n // node returns HTTP 200 with a zero struct, so no retry below this\n // layer can see it. Single-shot is only safe because the finality\n // gate (`waitForPeginRegistrationDepth`) runs first on the deposit\n // path — move this ahead of it and the read-after-write race returns.\n // The vault app matches this message to render \"still confirming\".\n throw new Error(\n `Vault ${vaultIds[i]} not found on-chain or has no pegin transaction`,\n );\n }\n return mapVaultProtocolInfo(result);\n });\n }\n\n /**\n * Read the protocol pegin fee (in wei) for a given vault provider.\n * Mirrors the `getPegInFee(address)` view on BTCVaultRegistry.\n */\n async getPegInFee(vaultProvider: Address): Promise<bigint> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n }\n\n /**\n * Read a vault provider's current commission in basis points from\n * BTCVaultRegistry. The contract enforces `commissionBps < 10000`, so the\n * legitimate range is `[0, 9999]`; anything outside indicates a wrong\n * contract address or ABI drift and is surfaced as an error rather than\n * trusted.\n */\n async getVaultProviderCommission(vaultProvider: Address): Promise<number> {\n // viem infers `number` from the `uint16` return in the `as const` ABI.\n const bps = await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderCommission\",\n args: [vaultProvider],\n });\n\n if (!Number.isInteger(bps) || bps < 0 || bps > MAX_VP_COMMISSION_BPS) {\n throw new Error(\n `getVaultProviderCommission returned ${bps} bps for ${vaultProvider}, ` +\n `outside the protocol range [0, ${MAX_VP_COMMISSION_BPS}]`,\n );\n }\n\n return bps;\n }\n\n async getVaultData(vaultId: Hex): Promise<VaultData> {\n // One round-trip for both structs (hard-fail): they feed signing/refund/\n // broadcast rebinds, so reading them in a single multicall also pins both\n // to the same block — no basic/protocol skew across two `eth_call`s.\n const [basicRaw, protocolRaw] = await this.publicClient.multicall({\n contracts: [\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n },\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n },\n ],\n allowFailure: false,\n });\n\n const basic = mapVaultBasicInfo(basicRaw);\n const protocol = mapVaultProtocolInfo(protocolRaw);\n\n if (\n !protocol.depositorSignedPeginTx ||\n protocol.depositorSignedPeginTx === \"0x\"\n ) {\n throw new Error(\n `Vault ${vaultId} not found on-chain or has no pegin transaction`,\n );\n }\n\n return { basic, protocol };\n }\n\n /** @inheritdoc */\n async getRegistrationRecordsAtBlock(\n createdAt: bigint,\n ): Promise<PeginRegistrationRecord[]> {\n // Deliberately no `vaultId` topic filter: both events must come back in\n // ONE answer for the empty-vs-missing discriminator below to hold, and\n // viem's multi-event form takes no `args` — so the block's registration\n // logs are fetched whole and ids are matched client-side. strict: a log\n // whose data does not decode against the ABI is dropped (viem\n // parseEventLogs) instead of surfacing as `args: {}`.\n const logs = await this.publicClient.getLogs({\n address: this.contractAddress,\n events: PEGIN_SUBMITTED_EVENTS,\n fromBlock: createdAt,\n toBlock: createdAt,\n strict: true,\n });\n if (logs.length === 0) {\n throw new RegistrationLogsUnavailableError(createdAt);\n }\n\n const records = new Map<string, PeginRegistrationRecord>();\n for (const log of logs) {\n if (log.eventName !== \"PegInSubmittedV2\") continue;\n const record = mapRegistrationRecord(log.args, log.blockNumber);\n // Lenient decoding covers a malformed log, not a duplicate: a vault\n // registers once, so two logs for any id mean the node is inconsistent\n // and every record from this block is suspect — fail closed by design.\n if (records.has(record.vaultId)) {\n throw new Error(\n `Expected one PegInSubmittedV2 log for vault ${record.vaultId} at block ${createdAt}, ` +\n `found more than one`,\n );\n }\n records.set(record.vaultId, record);\n }\n // The registry emits V1 and V2 together on every submission\n // (vault-contracts-aave-v4 `PeginLogic.sol:144-147` @ c559f5c2), so this\n // is as readily a node that served only part of the block as a pre-#548\n // registry — retryable either way.\n if (records.size === 0) {\n throw new RegistrationLogsUnavailableError(\n createdAt,\n `Block ${createdAt} holds ${logs.length} PegInSubmitted registration log(s) but no ` +\n `PegInSubmittedV2 log: either the node served a partial answer for block ${createdAt} ` +\n `(retry, preferably another node) or the registry predates the depositor's commission ` +\n `ceiling (vault-contracts-aave-v4 #548) and the ceiling cannot be recovered on-chain`,\n );\n }\n return [...records.values()];\n }\n\n /**\n * Read the depositor's commission ceiling (`maxAcceptableCommissionBps`)\n * for vaults registered in the same block, from their `PegInSubmittedV2`\n * logs. Returned in `vaultIds` order.\n *\n * The contract bound-checks the ceiling and discards it (PeginLogic.sol,\n * `VaultProviderCommissionExceeded`), so the registration log is its only\n * on-chain source. Vault ids are matched case-insensitively.\n *\n * @throws As {@link getRegistrationRecordsAtBlock}, plus the same typed\n * transient error when a vault has no registration log in its own\n * `createdAt` block.\n */\n async getMaxAcceptableCommissionBpsBatch(\n vaultIds: readonly Hex[],\n createdAt: bigint,\n ): Promise<number[]> {\n if (vaultIds.length === 0) return [];\n\n const records = await this.getRegistrationRecordsAtBlock(createdAt);\n return vaultIds.map(\n (vaultId) =>\n findRegistrationRecord(records, vaultId, createdAt)\n .maxAcceptableCommissionBps,\n );\n }\n\n /** @inheritdoc */\n async getVaultClaimableBy(\n vaultId: Hex,\n claimerPk: Hex,\n createdAt: bigint,\n ): Promise<VaultClaimableByEvent> {\n const claimer = assertOnChainBtcPubkey(\n claimerPk,\n `getVaultClaimableBy claimer (vault=${vaultId})`,\n );\n const claimerTopic = `0x${claimer}` as Hex;\n // viem re-filters the decoded logs client-side against `args`, comparing a\n // bytes32 with `===` against lower-case hex (parseEventLogs.ts:140,172-188).\n const vaultIdTopic = vaultId.toLowerCase() as Hex;\n // Finalized, not latest: the block found here is what the prover proves\n // against, and an unfinalized redeem can reorg away (btc-vault binds the\n // same scan to its finality level, eth-client client.rs:5989-6040).\n const { number: finalized } = await this.publicClient.getBlock({\n blockTag: \"finalized\",\n });\n if (finalized < createdAt) {\n throw new Error(\n `Finalized block ${finalized} is below vault ${vaultId}'s registration block ${createdAt}; ` +\n `the registration is not finalized yet, or the node is behind it`,\n );\n }\n\n // Newest first: the redeem usually trails the tip by far less than it\n // trails the registration. The contract emits every VaultClaimableBy of a\n // vault in one transaction, so the first non-empty chunk is the answer.\n let toBlock = finalized;\n for (;;) {\n const fromBlock = maxBigint(\n createdAt,\n toBlock - VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS + 1n,\n );\n const logs = await this.publicClient.getLogs({\n address: this.contractAddress,\n event: VAULT_CLAIMABLE_BY_EVENT,\n args: { vaultId: vaultIdTopic, claimerPK: claimerTopic },\n fromBlock,\n toBlock,\n strict: true,\n });\n // A redeem emits every VaultClaimableBy of a vault in ONE transaction\n // (RedeemLogic.sol), and `redeemForDepositor` emits the VP's key and\n // then the depositor's — so when those two keys are equal this filter\n // legitimately matches twice. Identical authorizations from one\n // transaction are the same fact; logs spanning transactions are not.\n if (logs.length > 1) {\n const transactions = new Set(logs.map((log) => log.transactionHash));\n if (transactions.size > 1) {\n throw new Error(\n `Found ${logs.length} VaultClaimableBy logs for vault ${vaultId} and claimer ` +\n `${claimerTopic} across ${transactions.size} transactions in blocks ` +\n `${fromBlock}..${toBlock}; a vault is redeemed once, so the node's answer ` +\n `is inconsistent`,\n );\n }\n }\n if (logs.length >= 1) {\n const log = logs[0];\n return {\n blockNumber: log.blockNumber,\n claimerPk: assertOnChainBtcPubkey(\n log.args.claimerPK,\n `VaultClaimableBy.claimerPK (vault=${vaultId})`,\n ),\n peginTxHash: log.args.peginTxHash,\n vaultCoreVersion: log.args.vaultCoreVersion,\n proverCircuitVersion: log.args.proverCircuitVersion,\n offchainParamsVersion: log.args.offchainParamsVersion,\n universalChallengersVersion: log.args.universalChallengersVersion,\n appVaultKeepersVersion: log.args.appVaultKeepersVersion,\n };\n }\n if (fromBlock === createdAt) {\n throw new VaultClaimableByNotFoundError(\n vaultId,\n claimerTopic,\n createdAt,\n finalized,\n );\n }\n toBlock = fromBlock - 1n;\n }\n }\n}\n","import {\n encodeFunctionData,\n isAddressEqual,\n zeroAddress,\n type Address,\n type Chain,\n type Hex,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { handleContractError } from \"../../contracts/errors\";\nimport {\n capMaxAcceptableCommissionBps,\n COMMISSION_BPS_HEADROOM,\n} from \"../../deposit-terms/commissionCeiling\";\nimport { waitForTransactionReceiptSmartAware } from \"../../utils/eth\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertPayoutScriptMatchesPopKey } from \"./payout-script\";\nimport { calculateBtcTxHash, derivePeginVaultId } from \"./pegin-transaction\";\nimport { ViemVaultRegistryReader } from \"./vault-registry-reader\";\n\n/** Referral code sent with peg-in registration. Zero means no referral. */\nexport const NO_REFERRAL_CODE = 0;\nconst UINT8_MAX = 255;\n// Match the prior vault-service timeout. A dropped transaction must not wait forever.\nconst RECEIPT_TIMEOUT_MS = 120_000;\n\nfunction ensureHex(value: string, label: string): Hex {\n const prefixed = value.startsWith(\"0x\")\n ? value\n : value.startsWith(\"0X\")\n ? `0x${value.slice(2)}`\n : `0x${value}`;\n if (!/^0x(?:[0-9a-fA-F]{2})+$/.test(prefixed)) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n return prefixed as Hex;\n}\n\nfunction assertBytes32(value: Hex, label: string): void {\n if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {\n throw new Error(`${label} must be a 32-byte hex value`);\n }\n}\n\n/** All-zero `bytes32` — the shape an unresolved fingerprint takes. */\nconst ZERO_BYTES32 =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n\n/**\n * The single validation point for `expectedFingerprint`, on both the singular\n * and batch paths.\n *\n * Zero is rejected separately from the shape check because it is a *well-formed*\n * `bytes32` that the registry can never accept — the live fingerprint is a\n * keccak256 over a domain-separated preimage — so it can only ever mean the\n * caller had no value and filled the slot. Catching it here turns a defaulted\n * field into a named error instead of an opaque on-chain revert with two\n * hashes and no hint.\n */\nfunction assertFingerprint(value: Hex): void {\n assertBytes32(value, \"expectedFingerprint\");\n if (value.toLowerCase() === ZERO_BYTES32) {\n throw new Error(\n \"expectedFingerprint must not be zero: the registry cannot resolve a \" +\n \"zero fingerprint, so this submission would always revert\",\n );\n }\n}\n\nfunction assertHtlcVout(value: number): void {\n if (!Number.isInteger(value) || value < 0 || value > UINT8_MAX) {\n throw new Error(`htlcVout must be a uint8, got ${value}`);\n }\n}\n\n/** A PoP prepared by a Bitcoin wallet, reusable by the ETH submit client. */\nexport interface PopSignature {\n btcPopSignature: Hex;\n depositorEthAddress: Address;\n /** x-only secp256k1 public key, 64 hex chars without `0x`. */\n depositorBtcPubkey: string;\n}\n\nexport interface ViemPeginRegistrationClientConfig {\n ethWallet: WalletClient;\n ethChain: Chain;\n publicClient: PublicClient;\n btcVaultRegistry: Address;\n receiptTimeoutMs?: number;\n /**\n * Refuse to register without a `quotedCommissionBps`. Set it to `true` when\n * the depositor approved deposit terms on a device: approval froze the\n * commission ceiling from the quote, so the chain-current fallback could\n * admit a commission the device would later refuse to pay out.\n *\n * Required, with no default: an omitted flag would silently pick the unsafe\n * direction for the integrator least able to probe the wallet capability.\n */\n requireQuotedCommissionBps: boolean;\n}\n\nexport interface RegisterPeginOnChainParams {\n unsignedPrePeginTx: string;\n depositorSignedPeginTx: string;\n vaultProvider: Address;\n hashlock: Hex;\n depositorWotsPkHash: Hex;\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n quotedCommissionBps?: number;\n /**\n * `keccak256(abi.encode(...))` over the protocol state the Pre-PegIn was\n * built against — see the SDK's `pegin-fingerprint` module.\n *\n * The registry recomputes it live at inclusion and reverts with\n * `PeginFingerprintChanged` on any difference, so it must be computed from\n * the same block-pinned snapshot that shaped the Bitcoin scripts. Required,\n * with no default: a fingerprint the caller did not resolve is not a\n * fingerprint, and the registry has no way to tell the two apart.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface PeginRegistrationResult {\n ethTxHash: Hex;\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface BatchPeginRegistrationItem {\n depositorSignedPeginTx: string;\n hashlock: Hex;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n depositorWotsPkHash: Hex;\n}\n\nexport interface RegisterPeginBatchOnChainParams {\n vaultProvider: Address;\n unsignedPrePeginTx: string;\n requests: BatchPeginRegistrationItem[];\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n quotedCommissionBps?: number;\n /**\n * See {@link RegisterPeginOnChainParams.expectedFingerprint}. One value for\n * the whole batch: the fingerprint takes no per-request input and a batch\n * fixes one vault provider, so every entry would resolve the same value.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface BatchPeginRegistrationResultItem {\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface PeginBatchRegistrationResult {\n ethTxHash: Hex;\n vaults: BatchPeginRegistrationResultItem[];\n}\n\n/**\n * Ethereum-only client for the on-chain half of peg-in registration.\n *\n * It consumes Bitcoin artifacts that were prepared earlier, but owns no BTC\n * wallet and imports neither Bitcoin libraries nor the Rust/WASM package.\n */\nexport class ViemPeginRegistrationClient {\n constructor(private readonly config: ViemPeginRegistrationClientConfig) {}\n\n async registerPeginOnChain(\n params: RegisterPeginOnChainParams,\n ): Promise<PeginRegistrationResult> {\n const request = {\n ...params,\n popSignature: { ...params.popSignature },\n };\n this.assertQuotedCommissionPresentWhenRequired(request.quotedCommissionBps);\n // Second, matching the batch path, so the two public entry points validate\n // in the same order and neither can drift behind a chain call.\n assertFingerprint(request.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(request.popSignature);\n const depositorBtcPubkey = this.normalizeBtcPubkey(request.popSignature);\n const btcPopSignature = ensureHex(\n request.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n const normalized = this.normalizeRequest(\n request,\n depositor,\n depositorBtcPubkey,\n );\n\n await this.assertVaultDoesNotExist(\n normalized.vaultId,\n normalized.peginTxHash,\n );\n const peginFee = await this.readPeginFee(request.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n request.vaultProvider,\n request.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequest\",\n args: [\n depositor,\n depositorBtcPubkey,\n btcPopSignature,\n normalized.unsignedPrePeginTx,\n normalized.depositorSignedPeginTx,\n request.vaultProvider,\n maxCommission,\n request.hashlock,\n request.htlcVout,\n normalized.payoutScript,\n request.depositorWotsPkHash,\n // Appended last on the singular overload; the batch takes it at\n // position 4 instead. Order is the selector, so do not \"tidy\" either.\n request.expectedFingerprint,\n ],\n });\n\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee,\n false,\n depositor,\n );\n return {\n ethTxHash,\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n };\n }\n\n async registerPeginBatchOnChain(\n params: RegisterPeginBatchOnChainParams,\n ): Promise<PeginBatchRegistrationResult> {\n const batch = {\n ...params,\n popSignature: { ...params.popSignature },\n requests: params.requests.map((request) => ({ ...request })),\n };\n if (batch.requests.length === 0) {\n throw new Error(\"Batch pegin requires at least one request\");\n }\n this.assertQuotedCommissionPresentWhenRequired(batch.quotedCommissionBps);\n assertFingerprint(batch.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(batch.popSignature);\n const unsignedPrePeginTx = ensureHex(\n batch.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorBtcPubkey = this.normalizeBtcPubkey(batch.popSignature);\n const btcPopSignature = ensureHex(\n batch.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n\n const vaults: BatchPeginRegistrationResultItem[] = [];\n const requests = [];\n const seenVaultIds = new Set<string>();\n for (const request of batch.requests) {\n const normalized = this.normalizeRequest(\n {\n ...request,\n unsignedPrePeginTx: batch.unsignedPrePeginTx,\n vaultProvider: batch.vaultProvider,\n depositorBtcPubkeyRaw: batch.depositorBtcPubkeyRaw,\n },\n depositor,\n depositorBtcPubkey,\n );\n if (seenVaultIds.has(normalized.vaultId)) {\n throw new Error(`Duplicate vault in batch: ${normalized.vaultId}`);\n }\n seenVaultIds.add(normalized.vaultId);\n vaults.push({\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n });\n requests.push({\n depositorBtcPubKey: depositorBtcPubkey,\n btcPopSignature,\n unsignedPrePeginTx,\n depositorSignedPeginTx: normalized.depositorSignedPeginTx,\n hashlock: request.hashlock,\n htlcVout: request.htlcVout,\n referralCode: NO_REFERRAL_CODE,\n depositorPayoutBtcAddress: normalized.payoutScript,\n depositorWotsPkHash: request.depositorWotsPkHash,\n });\n }\n for (const vault of vaults) {\n await this.assertVaultDoesNotExist(vault.vaultId, vault.peginTxHash);\n }\n\n const peginFee = await this.readPeginFee(batch.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n batch.vaultProvider,\n batch.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequestBatch\",\n // `expectedFingerprint` sits BEFORE `requests`, not appended. Reordering\n // these five changes the selector and the call stops existing.\n args: [\n depositor,\n batch.vaultProvider,\n maxCommission,\n batch.expectedFingerprint,\n requests,\n ],\n });\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee * BigInt(batch.requests.length),\n true,\n depositor,\n );\n return { ethTxHash, vaults };\n }\n\n private assertQuotedCommissionPresentWhenRequired(\n quotedCommissionBps?: number,\n ): void {\n if (\n quotedCommissionBps === undefined &&\n this.config.requireQuotedCommissionBps\n ) {\n throw new Error(\n \"quotedCommissionBps is required when the wallet approved deposit \" +\n \"terms: the registration ceiling must anchor to the approved quote.\",\n );\n }\n }\n\n private assertPopMatchesEthAccount(pop: PopSignature): Address {\n return this.assertEthAccount(pop.depositorEthAddress);\n }\n\n private assertEthAccount(expectedDepositor: Address): Address {\n const account = this.config.ethWallet.account;\n if (!account) throw new Error(\"Ethereum wallet account not found\");\n if (!isAddressEqual(expectedDepositor, account.address)) {\n throw new Error(\n `Proof of possession was signed for ${expectedDepositor} ` +\n `but the Ethereum wallet is currently connected to ${account.address}. ` +\n `Reconnect the original account or sign a new proof of possession.`,\n );\n }\n return account.address;\n }\n\n private normalizeBtcPubkey(pop: PopSignature): Hex {\n return `0x${assertOnChainBtcPubkey(\n ensureHex(pop.depositorBtcPubkey, \"Proof of possession BTC pubkey\"),\n \"Proof of possession BTC pubkey\",\n )}`;\n }\n\n // `expectedFingerprint` is omitted rather than accepted and ignored: nothing\n // here normalizes it, and requiring it would force the batch loop to thread a\n // value through a per-request helper that has no use for it. It is validated\n // once per call, at the top of each public method.\n private normalizeRequest(\n params: Omit<\n RegisterPeginOnChainParams,\n \"popSignature\" | \"expectedFingerprint\"\n >,\n depositor: Address,\n depositorBtcPubkey: Hex,\n ) {\n assertBytes32(params.hashlock, \"hashlock\");\n assertBytes32(params.depositorWotsPkHash, \"depositorWotsPkHash\");\n assertHtlcVout(params.htlcVout);\n const unsignedPrePeginTx = ensureHex(\n params.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorSignedPeginTx = ensureHex(\n params.depositorSignedPeginTx,\n \"depositorSignedPeginTx\",\n );\n const peginTxHash = calculateBtcTxHash(depositorSignedPeginTx);\n return {\n unsignedPrePeginTx,\n depositorSignedPeginTx,\n payoutScript: assertPayoutScriptMatchesPopKey(\n params.depositorPayoutScriptPubKey,\n depositorBtcPubkey,\n params.depositorBtcPubkeyRaw,\n ),\n peginTxHash,\n vaultId: ensureHex(derivePeginVaultId(peginTxHash, depositor), \"vaultId\"),\n };\n }\n\n private async assertVaultDoesNotExist(\n vaultId: Hex,\n peginTxHash: Hex,\n ): Promise<void> {\n const result = (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as { depositor: Address };\n if (result.depositor !== zeroAddress) {\n throw new Error(\n `Vault already exists (ID: ${vaultId}, peginTxHash: ${peginTxHash}). ` +\n `Vault IDs are derived from the pegin transaction hash and depositor address. ` +\n `To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`,\n );\n }\n }\n\n private async readPeginFee(vaultProvider: Address): Promise<bigint> {\n try {\n return (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n } catch (error) {\n throw new Error(\n \"Failed to query pegin fee from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n }\n\n private async resolveMaxAcceptableCommissionBps(\n vaultProvider: Address,\n quotedCommissionBps?: number,\n ): Promise<number> {\n let currentBps: number;\n try {\n currentBps = await new ViemVaultRegistryReader(\n this.config.publicClient,\n this.config.btcVaultRegistry,\n ).getVaultProviderCommission(vaultProvider);\n } catch (error) {\n throw new Error(\n \"Failed to query vault provider commission from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n if (quotedCommissionBps !== undefined) {\n if (currentBps > quotedCommissionBps + COMMISSION_BPS_HEADROOM) {\n throw new Error(\n `Vault provider commission changed since quote: quoted ${quotedCommissionBps} bps, ` +\n `chain currently reports ${currentBps} bps (allowed drift ${COMMISSION_BPS_HEADROOM} bps). ` +\n `Please refresh and try again.`,\n );\n }\n return capMaxAcceptableCommissionBps(quotedCommissionBps);\n }\n return capMaxAcceptableCommissionBps(currentBps);\n }\n\n private async sendAndWait(\n data: Hex,\n value: bigint,\n batch: boolean,\n depositor: Address,\n ): Promise<Hex> {\n let account = this.assertEthAccount(depositor);\n let gas: bigint;\n try {\n gas = await this.config.publicClient.estimateGas({\n to: this.config.btcVaultRegistry,\n data,\n value,\n account,\n });\n } catch (error) {\n handleContractError(error);\n }\n\n account = this.assertEthAccount(depositor);\n let submittedHash: Hex;\n try {\n submittedHash = await this.config.ethWallet.sendTransaction({\n to: this.config.btcVaultRegistry,\n data,\n value,\n gas,\n account,\n chain: this.config.ethChain,\n });\n } catch (error) {\n handleContractError(error);\n }\n const receipt = await waitForTransactionReceiptSmartAware({\n publicClient: this.config.publicClient,\n walletAddress: depositor,\n hash: submittedHash,\n timeout: this.config.receiptTimeoutMs ?? RECEIPT_TIMEOUT_MS,\n });\n if (receipt.status === \"reverted\") {\n handleContractError(\n new Error(\n `${batch ? \"Batch transaction\" : \"Transaction\"} reverted. ` +\n `Hash: ${receipt.transactionHash}. Check a block explorer for details.`,\n ),\n );\n }\n return receipt.transactionHash;\n }\n}\n"],"names":["COMMISSION_BPS_HEADROOM","MAX_ACCEPTABLE_COMMISSION_BPS_CAP","capMaxAcceptableCommissionBps","bps","MAX_VP_COMMISSION_BPS_EXCLUSIVE","MAX_VP_COMMISSION_BPS","mapVaultBasicInfo","result","mapVaultProtocolInfo","offchainParamsVersion","assertValidOffchainParamsVersion","UINT64_EXCLUSIVE_UPPER_BOUND","VP_GENESIS_KEY_EPOCH","PEGIN_SUBMITTED_EVENTS","getAbiItem","BTCVaultRegistryABI","VAULT_CLAIMABLE_BY_EVENT","VAULT_CLAIMABLE_BY_QUERY_CHUNK_BLOCKS","maxBigint","a","b","mapRegistrationRecord","args","blockNumber","assertEpochInRange","value","field","vaultId","mapKeyEpochs","ViemVaultRegistryReader","publicClient","contractAddress","vpAddress","epoch","assertOnChainBtcPubkey","BTCVaultRegistryKeyEpochsABI","vaultIds","info","i","vaultProvider","basicRaw","protocolRaw","basic","protocol","createdAt","logs","RegistrationLogsUnavailableError","records","log","record","findRegistrationRecord","claimerPk","claimerTopic","vaultIdTopic","finalized","toBlock","fromBlock","transactions","VaultClaimableByNotFoundError","NO_REFERRAL_CODE","UINT8_MAX","RECEIPT_TIMEOUT_MS","ensureHex","label","prefixed","assertBytes32","ZERO_BYTES32","assertFingerprint","assertHtlcVout","ViemPeginRegistrationClient","config","params","request","depositor","depositorBtcPubkey","btcPopSignature","normalized","peginFee","maxCommission","callData","encodeFunctionData","batch","unsignedPrePeginTx","vaults","requests","seenVaultIds","vault","quotedCommissionBps","pop","expectedDepositor","account","isAddressEqual","depositorSignedPeginTx","peginTxHash","calculateBtcTxHash","assertPayoutScriptMatchesPopKey","derivePeginVaultId","zeroAddress","error","currentBps","data","gas","handleContractError","submittedHash","receipt","waitForTransactionReceiptSmartAware"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registration-records-DJJC2NiO.js","sources":["../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/legacy.js","../src/tbv/core/clients/eth/onChainBtcPubkey.ts","../src/tbv/core/clients/eth/payout-script.ts","../src/tbv/core/clients/eth/pegin-transaction.ts","../src/tbv/core/clients/eth/claimable-event-error.ts","../src/tbv/core/clients/eth/protocol-params-validation.ts","../src/tbv/core/clients/eth/registration-logs-error.ts","../src/tbv/core/clients/eth/registration-records.ts"],"sourcesContent":["/**\n\nSHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions.\nDon't use them in a new protocol. What \"weak\" means:\n\n- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.\n- No practical pre-image attacks (only theoretical, 2^123.4)\n- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151\n * @module\n */\nimport { Chi, HashMD, Maj } from \"./_md.js\";\nimport { clean, createHasher, rotl } from \"./utils.js\";\n/** Initial SHA1 state */\nconst SHA1_IV = /* @__PURE__ */ Uint32Array.from([\n 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0,\n]);\n// Reusable temporary buffer\nconst SHA1_W = /* @__PURE__ */ new Uint32Array(80);\n/** Internal SHA1 legacy hash class. */\nexport class _SHA1 extends HashMD {\n A = SHA1_IV[0] | 0;\n B = SHA1_IV[1] | 0;\n C = SHA1_IV[2] | 0;\n D = SHA1_IV[3] | 0;\n E = SHA1_IV[4] | 0;\n constructor() {\n super(64, 20, 8, false);\n }\n get() {\n const { A, B, C, D, E } = this;\n return [A, B, C, D, E];\n }\n set(A, B, C, D, E) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n SHA1_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 80; i++)\n SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);\n // Compression function main loop, 80 rounds\n let { A, B, C, D, E } = this;\n for (let i = 0; i < 80; i++) {\n let F, K;\n if (i < 20) {\n F = Chi(B, C, D);\n K = 0x5a827999;\n }\n else if (i < 40) {\n F = B ^ C ^ D;\n K = 0x6ed9eba1;\n }\n else if (i < 60) {\n F = Maj(B, C, D);\n K = 0x8f1bbcdc;\n }\n else {\n F = B ^ C ^ D;\n K = 0xca62c1d6;\n }\n const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0;\n E = D;\n D = C;\n C = rotl(B, 30);\n B = A;\n A = T;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n this.set(A, B, C, D, E);\n }\n roundClean() {\n clean(SHA1_W);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/** SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */\nexport const sha1 = /* @__PURE__ */ createHasher(() => new _SHA1());\n/** Per-round constants */\nconst p32 = /* @__PURE__ */ Math.pow(2, 32);\nconst K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) => Math.floor(p32 * Math.abs(Math.sin(i + 1))));\n/** md5 initial state: same as sha1, but 4 u32 instead of 5. */\nconst MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4);\n// Reusable temporary buffer\nconst MD5_W = /* @__PURE__ */ new Uint32Array(16);\n/** Internal MD5 legacy hash class. */\nexport class _MD5 extends HashMD {\n A = MD5_IV[0] | 0;\n B = MD5_IV[1] | 0;\n C = MD5_IV[2] | 0;\n D = MD5_IV[3] | 0;\n constructor() {\n super(64, 16, 8, true);\n }\n get() {\n const { A, B, C, D } = this;\n return [A, B, C, D];\n }\n set(A, B, C, D) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n MD5_W[i] = view.getUint32(offset, true);\n // Compression function main loop, 64 rounds\n let { A, B, C, D } = this;\n for (let i = 0; i < 64; i++) {\n let F, g, s;\n if (i < 16) {\n F = Chi(B, C, D);\n g = i;\n s = [7, 12, 17, 22];\n }\n else if (i < 32) {\n F = Chi(D, B, C);\n g = (5 * i + 1) % 16;\n s = [5, 9, 14, 20];\n }\n else if (i < 48) {\n F = B ^ C ^ D;\n g = (3 * i + 5) % 16;\n s = [4, 11, 16, 23];\n }\n else {\n F = C ^ (B | ~D);\n g = (7 * i) % 16;\n s = [6, 10, 15, 21];\n }\n F = F + A + K[i] + MD5_W[g];\n A = D;\n D = C;\n C = B;\n B = B + rotl(F, s[i % 4]);\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n this.set(A, B, C, D);\n }\n roundClean() {\n clean(MD5_W);\n }\n destroy() {\n this.set(0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/**\n * MD5 (RFC 1321) legacy hash function. It was cryptographically broken.\n * MD5 architecture is similar to SHA1, with some differences:\n * - Reduced output length: 16 bytes (128 bit) instead of 20\n * - 64 rounds, instead of 80\n * - Little-endian: could be faster, but will require more code\n * - Non-linear index selection: huge speed-up for unroll\n * - Per round constants: more memory accesses, additional speed-up for unroll\n */\nexport const md5 = /* @__PURE__ */ createHasher(() => new _MD5());\n// RIPEMD-160\nconst Rho160 = /* @__PURE__ */ Uint8Array.from([\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n]);\nconst Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();\nconst Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();\nconst idxLR = /* @__PURE__ */ (() => {\n const L = [Id160];\n const R = [Pi160];\n const res = [L, R];\n for (let i = 0; i < 4; i++)\n for (let j of res)\n j.push(j[i].map((k) => Rho160[k]));\n return res;\n})();\nconst idxL = /* @__PURE__ */ (() => idxLR[0])();\nconst idxR = /* @__PURE__ */ (() => idxLR[1])();\n// const [idxL, idxR] = idxLR;\nconst shifts160 = /* @__PURE__ */ [\n [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],\n [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],\n [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],\n [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],\n [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],\n].map((i) => Uint8Array.from(i));\nconst shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst Kl160 = /* @__PURE__ */ Uint32Array.from([\n 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,\n]);\nconst Kr160 = /* @__PURE__ */ Uint32Array.from([\n 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,\n]);\n// It's called f() in spec.\nfunction ripemd_f(group, x, y, z) {\n if (group === 0)\n return x ^ y ^ z;\n if (group === 1)\n return (x & y) | (~x & z);\n if (group === 2)\n return (x | ~y) ^ z;\n if (group === 3)\n return (x & z) | (y & ~z);\n return x ^ (y | ~z);\n}\n// Reusable temporary buffer\nconst BUF_160 = /* @__PURE__ */ new Uint32Array(16);\nexport class _RIPEMD160 extends HashMD {\n h0 = 0x67452301 | 0;\n h1 = 0xefcdab89 | 0;\n h2 = 0x98badcfe | 0;\n h3 = 0x10325476 | 0;\n h4 = 0xc3d2e1f0 | 0;\n constructor() {\n super(64, 20, 8, true);\n }\n get() {\n const { h0, h1, h2, h3, h4 } = this;\n return [h0, h1, h2, h3, h4];\n }\n set(h0, h1, h2, h3, h4) {\n this.h0 = h0 | 0;\n this.h1 = h1 | 0;\n this.h2 = h2 | 0;\n this.h3 = h3 | 0;\n this.h4 = h4 | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n BUF_160[i] = view.getUint32(offset, true);\n // prettier-ignore\n let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;\n // Instead of iterating 0 to 80, we split it into 5 groups\n // And use the groups in constants, functions, etc. Much simpler\n for (let group = 0; group < 5; group++) {\n const rGroup = 4 - group;\n const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore\n const rl = idxL[group], rr = idxR[group]; // prettier-ignore\n const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore\n for (let i = 0; i < 16; i++) {\n const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0;\n al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore\n }\n // 2 loops are 10% faster\n for (let i = 0; i < 16; i++) {\n const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0;\n ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore\n }\n }\n // Add the compressed chunk to the current hash value\n this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);\n }\n roundClean() {\n clean(BUF_160);\n }\n destroy() {\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0);\n }\n}\n/**\n * RIPEMD-160 - a legacy hash function from 1990s.\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf\n */\nexport const ripemd160 = /* @__PURE__ */ createHasher(() => new _RIPEMD160());\n//# sourceMappingURL=legacy.js.map","/**\n * The single validator that mints {@link OnChainBtcPubkey}.\n *\n * Extracted from `ViemVaultRegistryReader.getVaultProviderGenesisBtcPubKey` so that\n * RFC-006 operation-key resolution can produce branded keys through exactly\n * the same checks, rather than casting past the brand. Every producer of an\n * `OnChainBtcPubkey` must go through here.\n */\n\nimport type { Hex } from \"viem\";\n\nimport type { OnChainBtcPubkey } from \"./types\";\n\n/** secp256k1's base-field prime, `2^256 - 2^32 - 977`. */\nconst SECP256K1_FIELD_PRIME =\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;\n\n/** secp256k1's curve coefficient `b`, from `y^2 = x^3 + b`. */\nconst SECP256K1_CURVE_B = 7n;\n\n/** Modular exponentiation without a crypto-library dependency. */\nfunction modPow(base: bigint, exponent: bigint, modulus: bigint): bigint {\n let result = 1n;\n let factor = base % modulus;\n let remaining = exponent;\n\n while (remaining > 0n) {\n if ((remaining & 1n) === 1n) {\n result = (result * factor) % modulus;\n }\n factor = (factor * factor) % modulus;\n remaining >>= 1n;\n }\n\n return result;\n}\n\n/**\n * secp256k1's field prime is congruent to 3 mod 4, so an x-coordinate is on\n * the curve iff `(x^3 + 7)^((p + 1) / 4)` squares back to `x^3 + 7` modulo\n * p. This is the same curve-membership condition used by x-only key parsers;\n * it deliberately does not merely validate length/range.\n * `x^3 + 7` cannot be zero because `-7` is not a cubic residue in this field,\n * so the zero square-root edge case is unreachable.\n */\nfunction isSecp256k1XCoordinate(value: string): boolean {\n const x = BigInt(`0x${value}`);\n if (x >= SECP256K1_FIELD_PRIME) return false;\n\n const xCubed =\n (((x * x) % SECP256K1_FIELD_PRIME) * x) % SECP256K1_FIELD_PRIME;\n const curveValue = (xCubed + SECP256K1_CURVE_B) % SECP256K1_FIELD_PRIME;\n const y = modPow(\n curveValue,\n (SECP256K1_FIELD_PRIME + 1n) >> 2n,\n SECP256K1_FIELD_PRIME,\n );\n\n return (y * y) % SECP256K1_FIELD_PRIME === curveValue;\n}\n\n/**\n * Validate a registry-returned `bytes32` as an x-only BTC pubkey and mint the\n * brand. Checks length, hex form, and secp256k1 curve membership. Returns\n * 64-char lowercase hex without the `0x` prefix.\n *\n * `label` identifies the read site in error messages (e.g.\n * `getOperationBtcKeyAtEpoch (vp=0x…, epoch=0)`), so a failure names which\n * participant and which getter produced it.\n *\n * A zero hash fails the curve check, so an unregistered operator or an epoch\n * with no bonded key surfaces as an error rather than a silent all-zero key.\n */\nexport function assertOnChainBtcPubkey(\n value: Hex,\n label: string,\n): OnChainBtcPubkey {\n const lowered = value.toLowerCase();\n if (!/^0x[0-9a-f]{64}$/.test(lowered)) {\n throw new Error(\n `${label} returned an unexpected value (length ${lowered.length}, prefix \"${lowered.slice(0, 2)}\")`,\n );\n }\n const stripped = lowered.slice(2);\n if (!isSecp256k1XCoordinate(stripped)) {\n throw new Error(\n `${label} returned a value that is not on the secp256k1 curve`,\n );\n }\n return stripped as OnChainBtcPubkey;\n}\n","import { schnorr, secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\nimport type { Hex } from \"viem\";\n\nimport { MAX_PAYOUT_SCRIPT_LEN } from \"../../primitives/psbt/constants\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\n\nconst P2TR_SCRIPT_PREFIX = \"5120\";\nconst P2WPKH_SCRIPT_PREFIX = \"0014\";\nconst HASH160_BYTES = 20;\nconst COMPRESSED_PUBKEY_BYTES = 33;\nconst UNCOMPRESSED_PUBKEY_BYTES = 65;\nconst SEC1_EVEN_Y_PREFIX = 0x02;\nconst SEC1_ODD_Y_PREFIX = 0x03;\nconst SEC1_UNCOMPRESSED_PREFIX = 0x04;\n\nfunction normalizeHex(value: string, label: string): Hex {\n const body =\n value.startsWith(\"0x\") || value.startsWith(\"0X\") ? value.slice(2) : value;\n if (!/^(?:[0-9a-fA-F]{2})+$/.test(body)) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n return `0x${body.toLowerCase()}`;\n}\n\n/**\n * The BIP-86 key-path P2TR scriptPubKey of an x-only key (bare lowercase\n * hex): the internal key tweaked with no script tree, matching Rust\n * `Bip86KeyConnector` (btc-vault `connectors/mod.rs:237-268` @ ac4954e7).\n *\n * @internal\n */\nexport function deriveP2trScript(xOnlyPubkey: string): Hex {\n const pubkeyBytes = hexToBytes(xOnlyPubkey);\n const internalKey = schnorr.utils.lift_x(BigInt(`0x${xOnlyPubkey}`));\n const tweak = schnorr.utils.bytesToNumberBE(\n schnorr.utils.taggedHash(\"TapTweak\", pubkeyBytes),\n );\n if (tweak >= secp256k1.CURVE.n) {\n throw new Error(\"Proof of possession BTC pubkey has an invalid TapTweak\");\n }\n const outputKey =\n tweak === 0n\n ? internalKey\n : internalKey.add(schnorr.Point.BASE.multiply(tweak));\n return `0x${P2TR_SCRIPT_PREFIX}${bytesToHex(\n schnorr.utils.pointToBytes(outputKey),\n )}`;\n}\n\nfunction normalizePayoutPubkey(value: string): {\n xOnlyPubkey: string;\n compressedPubkey?: Uint8Array;\n} {\n const normalized = normalizeHex(value, \"depositorBtcPubkeyRaw\");\n const pubkey = hexToBytes(normalized.slice(2));\n if (pubkey.length === 32) {\n return {\n xOnlyPubkey: assertOnChainBtcPubkey(normalized, \"Payout BTC pubkey\"),\n };\n }\n const isCompressed =\n pubkey.length === COMPRESSED_PUBKEY_BYTES &&\n (pubkey[0] === SEC1_EVEN_Y_PREFIX || pubkey[0] === SEC1_ODD_Y_PREFIX);\n const isUncompressed =\n pubkey.length === UNCOMPRESSED_PUBKEY_BYTES &&\n pubkey[0] === SEC1_UNCOMPRESSED_PREFIX;\n if (!isCompressed && !isUncompressed) {\n throw new Error(\n \"depositorBtcPubkeyRaw must be x-only, compressed, or uncompressed\",\n );\n }\n try {\n secp256k1.Point.fromBytes(pubkey);\n } catch {\n throw new Error(\"depositorBtcPubkeyRaw is not a valid BTC pubkey\");\n }\n return {\n xOnlyPubkey: bytesToHex(pubkey.subarray(1, COMPRESSED_PUBKEY_BYTES)),\n compressedPubkey: isCompressed ? pubkey : undefined,\n };\n}\n\nfunction deriveP2wpkhScript(pubkey: Uint8Array): Hex {\n return `0x${P2WPKH_SCRIPT_PREFIX}${bytesToHex(ripemd160(sha256(pubkey)))}`;\n}\n\n/** Verify the irreversible payout script at the final submission boundary. */\nexport function assertPayoutScriptMatchesPopKey(\n scriptPubKey: string,\n depositorBtcPubkey: string,\n depositorBtcPubkeyRaw: string,\n): Hex {\n const payoutScript = normalizeHex(\n scriptPubKey,\n \"depositorPayoutScriptPubKey\",\n );\n if ((payoutScript.length - 2) / 2 > MAX_PAYOUT_SCRIPT_LEN) {\n throw new Error(\n `depositorPayoutScriptPubKey exceeds ${MAX_PAYOUT_SCRIPT_LEN} bytes`,\n );\n }\n const keyBody =\n depositorBtcPubkey.startsWith(\"0x\") || depositorBtcPubkey.startsWith(\"0X\")\n ? depositorBtcPubkey.slice(2)\n : depositorBtcPubkey;\n const xOnlyPubkey = assertOnChainBtcPubkey(\n `0x${keyBody}` as Hex,\n \"Proof of possession BTC pubkey\",\n );\n const payoutPubkey = normalizePayoutPubkey(depositorBtcPubkeyRaw);\n if (payoutPubkey.xOnlyPubkey !== xOnlyPubkey) {\n throw new Error(\n \"depositorBtcPubkeyRaw does not match the proof of possession BTC pubkey\",\n );\n }\n\n if (payoutScript === deriveP2trScript(xOnlyPubkey)) {\n return payoutScript;\n }\n if (\n payoutScript.startsWith(`0x${P2WPKH_SCRIPT_PREFIX}`) &&\n payoutScript.length ===\n 2 + P2WPKH_SCRIPT_PREFIX.length + HASH160_BYTES * 2\n ) {\n if (!payoutPubkey.compressedPubkey) {\n throw new Error(\"A P2WPKH payout requires a compressed BTC pubkey\");\n }\n if (payoutScript === deriveP2wpkhScript(payoutPubkey.compressedPubkey)) {\n return payoutScript;\n }\n }\n throw new Error(\n \"depositorPayoutScriptPubKey does not match the proof of possession BTC pubkey\",\n );\n}\n","/**\n * Dependency-free Bitcoin txid and vault-ID helpers for Ethereum-only clients.\n * Transaction hex and vault-ID inputs accept an optional `0x` prefix.\n * Depositor addresses use strict EIP-55 validation.\n * Txids use a `0x` prefix. Vault IDs use no prefix. Both use lowercase hex.\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport {\n encodeAbiParameters,\n isAddress,\n keccak256,\n type Address,\n type Hex,\n} from \"viem\";\n\n/** Decode an optional-prefixed, even-length hex string. */\nfunction decodeHex(value: string, label: string): Uint8Array {\n const clean = value.startsWith(\"0x\") ? value.slice(2) : value;\n if (clean.length === 0 || clean.length % 2 !== 0) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n if (!/^[0-9a-fA-F]+$/.test(clean)) {\n throw new Error(`${label} contains non-hex characters`);\n }\n\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Encode bytes as lowercase hex without a prefix. */\nfunction encodeHex(bytes: Uint8Array): string {\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n}\n\n/** Concatenate byte chunks without a buffer dependency. */\nfunction concatBytes(chunks: readonly Uint8Array[]): Uint8Array {\n const result = new Uint8Array(\n chunks.reduce((length, chunk) => length + chunk.length, 0),\n );\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n}\n\n/**\n * Parse enough of Bitcoin's consensus transaction encoding to serialize the\n * no-witness form used for txid calculation. Every length is bounds-checked;\n * malformed/trailing data is rejected rather than hashed as an opaque blob.\n */\nfunction serializeWithoutWitness(transaction: Uint8Array): Uint8Array {\n let offset = 0;\n\n const take = (length: number, label: string): Uint8Array => {\n if (!Number.isSafeInteger(length) || length < 0) {\n throw new Error(`Invalid ${label} length ${length}`);\n }\n if (offset + length > transaction.length) {\n throw new Error(`Truncated Bitcoin transaction while reading ${label}`);\n }\n const value = transaction.slice(offset, offset + length);\n offset += length;\n return value;\n };\n\n const readLittleEndian = (length: number, label: string): bigint => {\n const bytes = take(length, label);\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]);\n }\n return value;\n };\n\n const readCompactSize = (\n label: string,\n ): { encoded: Uint8Array; value: number } => {\n const start = offset;\n const prefix = take(1, label)[0];\n let value: bigint;\n if (prefix < 0xfd) {\n value = BigInt(prefix);\n } else if (prefix === 0xfd) {\n value = readLittleEndian(2, label);\n if (value < 0xfdn) throw new Error(`Non-canonical ${label}`);\n } else if (prefix === 0xfe) {\n value = readLittleEndian(4, label);\n if (value <= 0xffffn) throw new Error(`Non-canonical ${label}`);\n } else {\n value = readLittleEndian(8, label);\n if (value <= 0xffffffffn) throw new Error(`Non-canonical ${label}`);\n }\n if (value > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(`${label} exceeds JavaScript's safe integer range`);\n }\n return {\n encoded: transaction.slice(start, offset),\n value: Number(value),\n };\n };\n\n const version = take(4, \"version\");\n const hasWitness =\n transaction[offset] === 0x00 && transaction[offset + 1] === 0x01;\n if (hasWitness) offset += 2;\n\n const inputCount = readCompactSize(\"input count\");\n const inputs: Uint8Array[] = [];\n for (let i = 0; i < inputCount.value; i++) {\n const start = offset;\n take(32, `input ${i} previous transaction hash`);\n take(4, `input ${i} previous output index`);\n const scriptLength = readCompactSize(`input ${i} script length`);\n take(scriptLength.value, `input ${i} script`);\n take(4, `input ${i} sequence`);\n inputs.push(transaction.slice(start, offset));\n }\n\n const outputCount = readCompactSize(\"output count\");\n const outputs: Uint8Array[] = [];\n for (let i = 0; i < outputCount.value; i++) {\n const start = offset;\n take(8, `output ${i} value`);\n const scriptLength = readCompactSize(`output ${i} script length`);\n take(scriptLength.value, `output ${i} script`);\n outputs.push(transaction.slice(start, offset));\n }\n\n if (hasWitness) {\n let hasWitnessData = false;\n for (let i = 0; i < inputCount.value; i++) {\n const itemCount = readCompactSize(`input ${i} witness item count`);\n hasWitnessData ||= itemCount.value > 0;\n for (let j = 0; j < itemCount.value; j++) {\n const itemLength = readCompactSize(\n `input ${i} witness item ${j} length`,\n );\n take(itemLength.value, `input ${i} witness item ${j}`);\n }\n }\n if (!hasWitnessData) {\n throw new Error(\"Bitcoin transaction has superfluous witness marker\");\n }\n }\n\n const locktime = take(4, \"locktime\");\n if (offset !== transaction.length) {\n throw new Error(\n `Bitcoin transaction has ${transaction.length - offset} trailing byte(s)`,\n );\n }\n\n return concatBytes([\n version,\n inputCount.encoded,\n ...inputs,\n outputCount.encoded,\n ...outputs,\n locktime,\n ]);\n}\n\n/** Calculate a Bitcoin txid without importing bitcoinjs-lib. */\nexport function calculateBtcTxHash(transactionHex: string): Hex {\n const serialized = serializeWithoutWitness(\n decodeHex(transactionHex, \"transactionHex\"),\n );\n const digest = sha256(sha256(serialized));\n digest.reverse();\n return `0x${encodeHex(digest)}`;\n}\n\n/**\n * Derive the Solidity vault ID without loading the Rust/WASM package.\n *\n * Inputs accept an optional `0x` prefix to match the current PeginManager\n * call sites. Address validation stays strict: lowercase and valid EIP-55\n * addresses pass, while uppercase and incorrectly checksummed mixed-case\n * addresses fail. The synchronous result is lowercase hex without a prefix,\n * matching the WASM helper that this function replaces.\n */\nexport function derivePeginVaultId(\n peginTxHash: string,\n depositor: string,\n): string {\n const normalizedPeginTxHash = peginTxHash.startsWith(\"0x\")\n ? peginTxHash\n : `0x${peginTxHash}`;\n if (!/^0x[0-9a-fA-F]{64}$/.test(normalizedPeginTxHash)) {\n throw new Error(\"peginTxHash must be a 32-byte hex value\");\n }\n const normalizedDepositor = depositor.startsWith(\"0x\")\n ? depositor\n : `0x${depositor}`;\n if (!isAddress(normalizedDepositor, { strict: true })) {\n throw new Error(`Invalid depositor Ethereum address: ${depositor}`);\n }\n return keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"address\" }],\n [normalizedPeginTxHash as Hex, normalizedDepositor as Address],\n ),\n ).slice(2);\n}\n","/**\n * Typed absence of a vault's `VaultClaimableBy` log for a claimer key.\n *\n * Distinct from a transport failure: the scan covered the whole range and\n * found nothing. That is what a not-yet-redeemed vault looks like, and it is\n * also what a load-balanced public node that lacks the block answers, so a\n * caller that knows the vault is redeemed may retry. Name-matchable across\n * module instances like `RegistrationLogsUnavailableError`.\n *\n * @module clients/eth/claimable-event-error\n */\n\nimport type { Hex } from \"viem\";\n\n/** The `name` this error carries, so a foreign module instance still matches. */\nexport const VAULT_CLAIMABLE_BY_NOT_FOUND_ERROR_NAME =\n \"VaultClaimableByNotFoundError\";\n\n/** @experimental */\nexport class VaultClaimableByNotFoundError extends Error {\n constructor(\n readonly vaultId: Hex,\n readonly claimerPk: Hex,\n readonly fromBlock: bigint,\n readonly toBlock: bigint,\n detail = \"the vault has not been redeemed for this key, or the node did not serve the block. Redeem first, or try again.\",\n options?: ErrorOptions,\n ) {\n super(\n `No VaultClaimableBy log for vault ${vaultId} and claimer ${claimerPk} in blocks ` +\n `${fromBlock}..${toBlock}: ${detail}`,\n options,\n );\n this.name = VAULT_CLAIMABLE_BY_NOT_FOUND_ERROR_NAME;\n }\n}\n\n/** Matches `instanceof` OR the documented `name` (dual module instances). @experimental */\nexport function isVaultClaimableByNotFoundError(\n err: unknown,\n): err is VaultClaimableByNotFoundError {\n if (err instanceof VaultClaimableByNotFoundError) return true;\n if (typeof err !== \"object\" || err === null) return false;\n return (\n (err as { name?: unknown }).name === VAULT_CLAIMABLE_BY_NOT_FOUND_ERROR_NAME\n );\n}\n","/**\n * Validation for protocol parameters fetched from the ProtocolParams contract.\n *\n * These values feed Bitcoin script construction and deposit validation.\n * Invalid params must be caught before they reach transaction-building code,\n * since errors after wallet signing prompts are unrecoverable.\n *\n * The {@link ViemProtocolParamsReader} runs these on every read; consumers\n * implementing their own reader against the same `ProtocolParamsReader`\n * interface should call them too.\n */\n\nimport { assertValidVaultCoreVersion } from \"../../primitives/vaultCoreVersion\";\n\nimport type {\n PegInConfiguration,\n TBVProtocolParams,\n VersionedOffchainParams,\n} from \"./types\";\n\n/**\n * Maximum value for a Solidity uint16. btc-vault carries the PegIn timelock as\n * a `NonZeroU16` (`transactions/pegin.rs:33` @ ac4954e7).\n */\nconst UINT16_MAX = 65535;\n\n/** Maximum valid value for basis points (100%) */\nconst MAX_BASIS_POINTS = 10000;\n\n/** Maximum value for a Solidity uint32. */\nconst UINT32_MAX = 4_294_967_295;\n\n/** Maximum valid value for a uint8 (e.g. maxHtlcOutputCount). */\nconst UINT8_MAX = 255;\n\n/**\n * Validate an `offchainParamsVersion` value sourced from a contract read.\n * `Number()` on a malformed payload yields `NaN` or a non-integer; both\n * silently break consumers that loop `1..version` or use the value as a\n * map key. Used by reader entry points that surface the version to JS.\n */\nexport function assertValidOffchainParamsVersion(version: number): void {\n if (\n !Number.isInteger(version) ||\n version < 0 ||\n version > UINT32_MAX\n ) {\n throw new Error(\n `Invalid offchainParamsVersion from contract: must be a uint32, got ${version}`,\n );\n }\n}\n\n/**\n * Validate offchain params consistency and bounds.\n * @throws Error on invalid values to prevent constructing invalid Bitcoin scripts.\n */\nexport function validateOffchainParams(params: VersionedOffchainParams): void {\n const errors: string[] = [];\n\n if (params.timelockAssert <= 0n) {\n errors.push(\n `timelockAssert must be positive, got ${params.timelockAssert}`,\n );\n }\n if (params.timelockAssert > BigInt(UINT16_MAX)) {\n errors.push(\n `timelockAssert ${params.timelockAssert} exceeds uint16 max (${UINT16_MAX})`,\n );\n }\n\n if (params.timelockChallengeAssert <= 0n) {\n errors.push(\n `timelockChallengeAssert must be positive, got ${params.timelockChallengeAssert}`,\n );\n }\n\n if (params.tRefund <= 0) {\n errors.push(`tRefund must be positive, got ${params.tRefund}`);\n }\n\n if (params.tStale <= 0) {\n errors.push(`tStale must be positive, got ${params.tStale}`);\n }\n\n if (params.securityCouncilKeys.length === 0) {\n errors.push(\"securityCouncilKeys must not be empty\");\n }\n\n if (params.councilQuorum <= 0) {\n errors.push(`councilQuorum must be positive, got ${params.councilQuorum}`);\n }\n if (params.councilQuorum > params.securityCouncilKeys.length) {\n errors.push(\n `councilQuorum (${params.councilQuorum}) exceeds securityCouncilKeys count (${params.securityCouncilKeys.length})`,\n );\n }\n\n if (params.feeRate <= 0n) {\n errors.push(`feeRate must be positive, got ${params.feeRate}`);\n }\n\n if (params.minPeginFeeRate <= 0n) {\n errors.push(\n `minPeginFeeRate must be positive, got ${params.minPeginFeeRate}`,\n );\n }\n\n if (\n !Number.isInteger(params.proverCircuitVersion) ||\n params.proverCircuitVersion < 0 ||\n params.proverCircuitVersion > UINT16_MAX\n ) {\n errors.push(\n `proverCircuitVersion must be a uint16, got ${params.proverCircuitVersion}`,\n );\n }\n\n if (\n !Number.isInteger(params.minPrepeginDepth) ||\n params.minPrepeginDepth <= 0 ||\n params.minPrepeginDepth > UINT32_MAX\n ) {\n errors.push(\n `minPrepeginDepth must be a uint32 in [1, ${UINT32_MAX}], got ${params.minPrepeginDepth}`,\n );\n }\n\n if (params.babeTotalInstances <= 0) {\n errors.push(\n `babeTotalInstances must be positive, got ${params.babeTotalInstances}`,\n );\n }\n if (params.babeInstancesToFinalize <= 0) {\n errors.push(\n `babeInstancesToFinalize must be positive, got ${params.babeInstancesToFinalize}`,\n );\n }\n if (params.babeInstancesToFinalize > params.babeTotalInstances) {\n errors.push(\n `babeInstancesToFinalize (${params.babeInstancesToFinalize}) exceeds babeTotalInstances (${params.babeTotalInstances})`,\n );\n }\n\n if (\n params.minVpCommissionBps < 0 ||\n params.minVpCommissionBps > MAX_BASIS_POINTS\n ) {\n errors.push(\n `minVpCommissionBps must be in [0, ${MAX_BASIS_POINTS}], got ${params.minVpCommissionBps}`,\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `Invalid offchain protocol parameters: ${errors.join(\"; \")}`,\n );\n }\n}\n\n/**\n * Validate TBV protocol params returned from the contract.\n * @throws Error on invalid amounts or out-of-range bounded fields.\n */\nexport function validateTBVProtocolParams(params: TBVProtocolParams): void {\n const errors: string[] = [];\n\n if (params.minimumPegInAmount <= 0n) {\n errors.push(\n `minimumPegInAmount must be positive, got ${params.minimumPegInAmount}`,\n );\n }\n\n if (params.maxPegInAmount < params.minimumPegInAmount) {\n errors.push(\n `maxPegInAmount (${params.maxPegInAmount}) must be >= minimumPegInAmount (${params.minimumPegInAmount})`,\n );\n }\n\n if (params.pegInAckTimeout <= 0n) {\n errors.push(\n `pegInAckTimeout must be positive, got ${params.pegInAckTimeout}`,\n );\n }\n\n if (params.pegInActivationTimeout <= 0n) {\n errors.push(\n `pegInActivationTimeout must be positive, got ${params.pegInActivationTimeout}`,\n );\n }\n\n if (\n !Number.isInteger(params.maxHtlcOutputCount) ||\n params.maxHtlcOutputCount <= 0 ||\n params.maxHtlcOutputCount > UINT8_MAX\n ) {\n errors.push(\n `maxHtlcOutputCount must be an integer in [1, ${UINT8_MAX}], got ${params.maxHtlcOutputCount}`,\n );\n }\n\n if (\n params.maxFundingInputCount !== null &&\n (!Number.isInteger(params.maxFundingInputCount) ||\n params.maxFundingInputCount <= 0 ||\n params.maxFundingInputCount > UINT8_MAX)\n ) {\n errors.push(\n `maxFundingInputCount must be an integer in [1, ${UINT8_MAX}], got ${params.maxFundingInputCount}`,\n );\n }\n\n if (\n typeof params.expiredPegInGraceBlocks !== \"bigint\" ||\n params.expiredPegInGraceBlocks <= 0n\n ) {\n errors.push(\n `expiredPegInGraceBlocks must be a positive bigint, got ${params.expiredPegInGraceBlocks}`,\n );\n }\n\n if (errors.length > 0) {\n throw new Error(`Invalid TBV protocol parameters: ${errors.join(\"; \")}`);\n }\n}\n\n/**\n * Validate the full peg-in configuration after assembly.\n * Checks both TBV params and offchain params consistency, and the\n * top-level `offchainParamsVersion` (which originates from a separate\n * multicall result and so must be range-checked alongside the params it\n * names).\n */\nexport function validatePegInConfiguration(config: PegInConfiguration): void {\n validateTBVProtocolParams(config);\n validateOffchainParams(config.offchainParams);\n\n if (\n !Number.isInteger(config.offchainParamsVersion) ||\n config.offchainParamsVersion < 0 ||\n config.offchainParamsVersion > UINT32_MAX\n ) {\n throw new Error(\n `Invalid peg-in configuration: offchainParamsVersion must be a uint32, got ${config.offchainParamsVersion}`,\n );\n }\n\n // The contract enforces ≥ 1 (setter rejects 0); a 0 here means a\n // mis-decoded read or a pre-vaultCoreVersion contract — fail closed.\n assertValidVaultCoreVersion(\n config.activeVaultCoreVersion,\n \"ProtocolParams.activeVaultCoreVersion()\",\n );\n}\n","/**\n * Transient failure of a registration-log read.\n *\n * Every registered vault has its `PegInSubmitted` log in its `createdAt`\n * block, so an Ethereum node answering that block's registration-log query\n * with no logs at all did not serve the block — load-balanced public RPCs\n * answer `[]` for a block a backend lacks instead of erroring, which viem's\n * transport retry cannot see (it retries errors only). Callers may retry.\n *\n * The same holds for an answer that is merely incomplete: the registry emits\n * `PegInSubmitted` and `PegInSubmittedV2` together on every submission\n * (vault-contracts-aave-v4 `PeginLogic.sol:144-147` @ c559f5c2), so a block\n * answer carrying only some of them is a partial answer as readily as it is\n * an old registry. Those shapes carry their own message.\n *\n * @module clients/eth/registration-logs-error\n */\n\n/** The `name` this error carries, so a foreign module instance still matches. */\nexport const REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME =\n \"RegistrationLogsUnavailableError\";\n\nexport class RegistrationLogsUnavailableError extends Error {\n readonly blockNumber: bigint;\n\n /**\n * `message` replaces the empty-answer wording for the partial-answer shapes\n * that are not \"no logs at all\"; the caller names which logs it did get.\n */\n constructor(blockNumber: bigint, message?: string) {\n super(\n message ??\n `The Ethereum node returned no registration logs for block ${blockNumber}, ` +\n `which holds a vault registration; the node may not have indexed that ` +\n `block yet. Try again.`,\n );\n this.name = REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME;\n this.blockNumber = blockNumber;\n }\n}\n\n/** Matches `instanceof` OR the documented `name` (dual module instances). */\nexport function isRegistrationLogsUnavailableError(\n err: unknown,\n): err is RegistrationLogsUnavailableError {\n if (err instanceof RegistrationLogsUnavailableError) return true;\n if (typeof err !== \"object\" || err === null) return false;\n return (\n (err as { name?: unknown }).name ===\n REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME\n );\n}\n","/**\n * Pure helpers over {@link PeginRegistrationRecord}.\n *\n * The reader decodes a whole block leniently; the strict per-record checks\n * live here and run only on the records a caller selects, so a stranger's\n * malformed registration in the same block cannot fail an unrelated read (the\n * vault app's deposit resume reads its commission ceiling through the same\n * block). That leniency stops at duplicates: a vault registers once, so two\n * logs for any vault id are an inconsistent node and the reader fails the\n * whole block's read closed by design.\n *\n * @module clients/eth/registration-records\n */\n\nimport type { Hex } from \"viem\";\n\nimport { MAX_PAYOUT_SCRIPT_LEN } from \"../../primitives/psbt/constants\";\nimport { calculateBtcTxHash } from \"./pegin-transaction\";\nimport { RegistrationLogsUnavailableError } from \"./registration-logs-error\";\nimport type { PeginRegistrationRecord } from \"./types\";\n\nconst HEX_PREFIX_LEN = 2;\n\n/**\n * The record of `vaultId` among a block's registrations.\n *\n * @throws {RegistrationLogsUnavailableError} (transient, retry) when the\n * block's registration logs do not include the vault: the registry emits a\n * `PegInSubmittedV2` on every submission, so an answer without the target's\n * is as readily a node's partial answer as a vault registered elsewhere.\n * @experimental\n */\nexport function findRegistrationRecord(\n records: readonly PeginRegistrationRecord[],\n vaultId: Hex,\n createdAt: bigint,\n): PeginRegistrationRecord {\n const wanted = vaultId.toLowerCase();\n const record = records.find((r) => r.vaultId === wanted);\n if (record === undefined) {\n // Both shapes are emitted together on every submission\n // (vault-contracts-aave-v4 `PeginLogic.sol:144-147` @ c559f5c2).\n throw new RegistrationLogsUnavailableError(\n createdAt,\n `Vault ${vaultId} has no PegInSubmittedV2 registration log at its on-chain registration ` +\n `block ${createdAt}: either the node served a partial answer for block ${createdAt} ` +\n `(retry, preferably another node) or the vault was not registered in this block`,\n );\n }\n return record;\n}\n\n/**\n * Txid of the record's `unsignedPrePeginTx`, `0x`-prefixed display order —\n * what the vault record stores as `prePeginTxHash`.\n *\n * @throws When the log's transaction does not parse.\n * @experimental\n */\nexport function registrationPrePeginTxHash(\n record: PeginRegistrationRecord,\n): Hex {\n return calculateBtcTxHash(record.unsignedPrePeginTx);\n}\n\n/**\n * The bound `assertPayoutScriptMatchesPopKey` enforces before a registration\n * is submitted (payout-script.ts); a log outside it is not a script the SDK\n * ever registered.\n *\n * @experimental\n */\nexport function assertRegisteredPayoutScriptBounds(\n record: PeginRegistrationRecord,\n): void {\n const bytes =\n (record.depositorPayoutScriptPubKey.length - HEX_PREFIX_LEN) / 2;\n if (bytes === 0 || bytes > MAX_PAYOUT_SCRIPT_LEN) {\n throw new Error(\n `PegInSubmittedV2 log for vault ${record.vaultId} carries a ${bytes}-byte ` +\n `depositorPayoutBtcAddress; expected 1..${MAX_PAYOUT_SCRIPT_LEN} bytes`,\n );\n }\n}\n"],"names":["Rho160","Id160","_","i","Pi160","idxLR","res","j","k","idxL","idxR","shifts160","shiftsL160","idx","shiftsR160","Kl160","Kr160","ripemd_f","group","x","y","z","BUF_160","_RIPEMD160","HashMD","__publicField","h0","h1","h2","h3","h4","view","offset","al","ar","bl","br","cl","cr","dl","dr","el","er","rGroup","hbl","hbr","rl","rr","sl","sr","tl","rotl","tr","clean","ripemd160","createHasher","SECP256K1_FIELD_PRIME","SECP256K1_CURVE_B","modPow","base","exponent","modulus","result","factor","remaining","isSecp256k1XCoordinate","value","curveValue","assertOnChainBtcPubkey","label","lowered","stripped","P2TR_SCRIPT_PREFIX","P2WPKH_SCRIPT_PREFIX","HASH160_BYTES","COMPRESSED_PUBKEY_BYTES","UNCOMPRESSED_PUBKEY_BYTES","SEC1_EVEN_Y_PREFIX","SEC1_ODD_Y_PREFIX","SEC1_UNCOMPRESSED_PREFIX","normalizeHex","body","deriveP2trScript","xOnlyPubkey","pubkeyBytes","hexToBytes","internalKey","schnorr","tweak","secp256k1","outputKey","bytesToHex","normalizePayoutPubkey","normalized","pubkey","isCompressed","isUncompressed","deriveP2wpkhScript","sha256","assertPayoutScriptMatchesPopKey","scriptPubKey","depositorBtcPubkey","depositorBtcPubkeyRaw","payoutScript","MAX_PAYOUT_SCRIPT_LEN","keyBody","payoutPubkey","decodeHex","bytes","encodeHex","byte","concatBytes","chunks","length","chunk","serializeWithoutWitness","transaction","take","readLittleEndian","readCompactSize","start","prefix","version","hasWitness","inputCount","inputs","scriptLength","outputCount","outputs","hasWitnessData","itemCount","itemLength","locktime","calculateBtcTxHash","transactionHex","serialized","digest","derivePeginVaultId","peginTxHash","depositor","normalizedPeginTxHash","normalizedDepositor","isAddress","keccak256","encodeAbiParameters","VAULT_CLAIMABLE_BY_NOT_FOUND_ERROR_NAME","VaultClaimableByNotFoundError","vaultId","claimerPk","fromBlock","toBlock","detail","options","isVaultClaimableByNotFoundError","err","UINT16_MAX","MAX_BASIS_POINTS","UINT32_MAX","UINT8_MAX","assertValidOffchainParamsVersion","validateOffchainParams","params","errors","validateTBVProtocolParams","validatePegInConfiguration","config","assertValidVaultCoreVersion","REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME","RegistrationLogsUnavailableError","blockNumber","message","isRegistrationLogsUnavailableError","HEX_PREFIX_LEN","findRegistrationRecord","records","createdAt","wanted","record","r","registrationPrePeginTxHash","assertRegisteredPayoutScriptBounds"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,2 +0,0 @@
1
- "use strict";var tt=Object.defineProperty;var et=(t,e,n)=>e in t?tt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var y=(t,e,n)=>et(t,typeof e!="symbol"?e+"":e,n);const p=require("./secp256k1-DDHQ1_za.cjs"),l=require("./sha2-Ce6KewYx.cjs"),w=require("./constants-CAm10Qwp.cjs"),T=require("viem"),nt=Uint8Array.from([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]),N=Uint8Array.from(new Array(16).fill(0).map((t,e)=>e)),ot=N.map(t=>(9*t+5)%16),F=(()=>{const n=[[N],[ot]];for(let o=0;o<4;o++)for(let i of n)i.push(i[o].map(u=>nt[u]));return n})(),U=F[0],L=F[1],O=[[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(t=>Uint8Array.from(t)),it=U.map((t,e)=>t.map(n=>O[e][n])),rt=L.map((t,e)=>t.map(n=>O[e][n])),st=Uint32Array.from([0,1518500249,1859775393,2400959708,2840853838]),ut=Uint32Array.from([1352829926,1548603684,1836072691,2053994217,0]);function _(t,e,n,o){return t===0?e^n^o:t===1?e&n|~e&o:t===2?(e|~n)^o:t===3?e&o|n&~o:e^(n|~o)}const I=new Uint32Array(16);class ct extends l.HashMD{constructor(){super(64,20,8,!0);y(this,"h0",1732584193);y(this,"h1",-271733879);y(this,"h2",-1732584194);y(this,"h3",271733878);y(this,"h4",-1009589776)}get(){const{h0:n,h1:o,h2:i,h3:u,h4:f}=this;return[n,o,i,u,f]}set(n,o,i,u,f){this.h0=n|0,this.h1=o|0,this.h2=i|0,this.h3=u|0,this.h4=f|0}process(n,o){for(let s=0;s<16;s++,o+=4)I[s]=n.getUint32(o,!0);let i=this.h0|0,u=i,f=this.h1|0,d=f,g=this.h2|0,b=g,m=this.h3|0,$=m,r=this.h4|0,c=r;for(let s=0;s<5;s++){const a=4-s,P=st[s],j=ut[s],q=U[s],Q=L[s],J=it[s],Z=rt[s];for(let h=0;h<16;h++){const C=l.rotl(i+_(s,f,g,m)+I[q[h]]+P,J[h])+r|0;i=r,r=m,m=l.rotl(g,10)|0,g=f,f=C}for(let h=0;h<16;h++){const C=l.rotl(u+_(a,d,b,$)+I[Q[h]]+j,Z[h])+c|0;u=c,c=$,$=l.rotl(b,10)|0,b=d,d=C}}this.set(this.h1+g+$|0,this.h2+m+c|0,this.h3+r+u|0,this.h4+i+d|0,this.h0+f+b|0)}roundClean(){l.clean(I)}destroy(){this.destroyed=!0,l.clean(this.buffer),this.set(0,0,0,0,0)}}const H=l.createHasher(()=>new ct),x=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,at=7n;function ft(t,e,n){let o=1n,i=t%n,u=e;for(;u>0n;)(u&1n)===1n&&(o=o*i%n),i=i*i%n,u>>=1n;return o}function lt(t){const e=BigInt(`0x${t}`);if(e>=x)return!1;const o=(e*e%x*e%x+at)%x,i=ft(o,x+1n>>2n,x);return i*i%x===o}function B(t,e){const n=t.toLowerCase();if(!/^0x[0-9a-f]{64}$/.test(n))throw new Error(`${e} returned an unexpected value (length ${n.length}, prefix "${n.slice(0,2)}")`);const o=n.slice(2);if(!lt(o))throw new Error(`${e} returned a value that is not on the secp256k1 curve`);return o}const ht="5120",k="0014",dt=20,S=33,gt=65,mt=2,pt=3,bt=4;function K(t,e){const n=t.startsWith("0x")||t.startsWith("0X")?t.slice(2):t;if(!/^(?:[0-9a-fA-F]{2})+$/.test(n))throw new Error(`${e} must be non-empty, even-length hex`);return`0x${n.toLowerCase()}`}function M(t){const e=l.hexToBytes(t),n=p.schnorr.utils.lift_x(BigInt(`0x${t}`)),o=p.schnorr.utils.bytesToNumberBE(p.schnorr.utils.taggedHash("TapTweak",e));if(o>=p.secp256k1.CURVE.n)throw new Error("Proof of possession BTC pubkey has an invalid TapTweak");const i=o===0n?n:n.add(p.schnorr.Point.BASE.multiply(o));return`0x${ht}${l.bytesToHex(p.schnorr.utils.pointToBytes(i))}`}function Pt(t){const e=K(t,"depositorBtcPubkeyRaw"),n=l.hexToBytes(e.slice(2));if(n.length===32)return{xOnlyPubkey:B(e,"Payout BTC pubkey")};const o=n.length===S&&(n[0]===mt||n[0]===pt),i=n.length===gt&&n[0]===bt;if(!o&&!i)throw new Error("depositorBtcPubkeyRaw must be x-only, compressed, or uncompressed");try{p.secp256k1.Point.fromBytes(n)}catch{throw new Error("depositorBtcPubkeyRaw is not a valid BTC pubkey")}return{xOnlyPubkey:l.bytesToHex(n.subarray(1,S)),compressedPubkey:o?n:void 0}}function yt(t){return`0x${k}${l.bytesToHex(H(l.sha256(t)))}`}function xt(t,e,n){const o=K(t,"depositorPayoutScriptPubKey");if((o.length-2)/2>w.MAX_PAYOUT_SCRIPT_LEN)throw new Error(`depositorPayoutScriptPubKey exceeds ${w.MAX_PAYOUT_SCRIPT_LEN} bytes`);const i=e.startsWith("0x")||e.startsWith("0X")?e.slice(2):e,u=B(`0x${i}`,"Proof of possession BTC pubkey"),f=Pt(n);if(f.xOnlyPubkey!==u)throw new Error("depositorBtcPubkeyRaw does not match the proof of possession BTC pubkey");if(o===M(u))return o;if(o.startsWith(`0x${k}`)&&o.length===2+k.length+dt*2){if(!f.compressedPubkey)throw new Error("A P2WPKH payout requires a compressed BTC pubkey");if(o===yt(f.compressedPubkey))return o}throw new Error("depositorPayoutScriptPubKey does not match the proof of possession BTC pubkey")}function $t(t,e){const n=t.startsWith("0x")?t.slice(2):t;if(n.length===0||n.length%2!==0)throw new Error(`${e} must be non-empty, even-length hex`);if(!/^[0-9a-fA-F]+$/.test(n))throw new Error(`${e} contains non-hex characters`);const o=new Uint8Array(n.length/2);for(let i=0;i<o.length;i++)o[i]=Number.parseInt(n.slice(i*2,i*2+2),16);return o}function It(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function Et(t){const e=new Uint8Array(t.reduce((o,i)=>o+i.length,0));let n=0;for(const o of t)e.set(o,n),n+=o.length;return e}function wt(t){let e=0;const n=(r,c)=>{if(!Number.isSafeInteger(r)||r<0)throw new Error(`Invalid ${c} length ${r}`);if(e+r>t.length)throw new Error(`Truncated Bitcoin transaction while reading ${c}`);const s=t.slice(e,e+r);return e+=r,s},o=(r,c)=>{const s=n(r,c);let a=0n;for(let P=s.length-1;P>=0;P--)a=a<<8n|BigInt(s[P]);return a},i=r=>{const c=e,s=n(1,r)[0];let a;if(s<253)a=BigInt(s);else if(s===253){if(a=o(2,r),a<0xfdn)throw new Error(`Non-canonical ${r}`)}else if(s===254){if(a=o(4,r),a<=0xffffn)throw new Error(`Non-canonical ${r}`)}else if(a=o(8,r),a<=0xffffffffn)throw new Error(`Non-canonical ${r}`);if(a>BigInt(Number.MAX_SAFE_INTEGER))throw new Error(`${r} exceeds JavaScript's safe integer range`);return{encoded:t.slice(c,e),value:Number(a)}},u=n(4,"version"),f=t[e]===0&&t[e+1]===1;f&&(e+=2);const d=i("input count"),g=[];for(let r=0;r<d.value;r++){const c=e;n(32,`input ${r} previous transaction hash`),n(4,`input ${r} previous output index`);const s=i(`input ${r} script length`);n(s.value,`input ${r} script`),n(4,`input ${r} sequence`),g.push(t.slice(c,e))}const b=i("output count"),m=[];for(let r=0;r<b.value;r++){const c=e;n(8,`output ${r} value`);const s=i(`output ${r} script length`);n(s.value,`output ${r} script`),m.push(t.slice(c,e))}if(f){let r=!1;for(let c=0;c<d.value;c++){const s=i(`input ${c} witness item count`);r||(r=s.value>0);for(let a=0;a<s.value;a++){const P=i(`input ${c} witness item ${a} length`);n(P.value,`input ${c} witness item ${a}`)}}if(!r)throw new Error("Bitcoin transaction has superfluous witness marker")}const $=n(4,"locktime");if(e!==t.length)throw new Error(`Bitcoin transaction has ${t.length-e} trailing byte(s)`);return Et([u,d.encoded,...g,b.encoded,...m,$])}function X(t){const e=wt($t(t,"transactionHex")),n=l.sha256(l.sha256(e));return n.reverse(),`0x${It(n)}`}function vt(t,e){const n=t.startsWith("0x")?t:`0x${t}`;if(!/^0x[0-9a-fA-F]{64}$/.test(n))throw new Error("peginTxHash must be a 32-byte hex value");const o=e.startsWith("0x")?e:`0x${e}`;if(!T.isAddress(o,{strict:!0}))throw new Error(`Invalid depositor Ethereum address: ${e}`);return T.keccak256(T.encodeAbiParameters([{type:"bytes32"},{type:"address"}],[n,o])).slice(2)}const D="VaultClaimableByNotFoundError";class W extends Error{constructor(e,n,o,i,u="the vault has not been redeemed for this key, or the node did not serve the block. Redeem first, or try again.",f){super(`No VaultClaimableBy log for vault ${e} and claimer ${n} in blocks ${o}..${i}: ${u}`,f),this.vaultId=e,this.claimerPk=n,this.fromBlock=o,this.toBlock=i,this.name=D}}function Ct(t){return t instanceof W?!0:typeof t!="object"||t===null?!1:t.name===D}const A=65535,V=1e4,v=4294967295,E=255;function Tt(t){if(!Number.isInteger(t)||t<0||t>v)throw new Error(`Invalid offchainParamsVersion from contract: must be a uint32, got ${t}`)}function Y(t){const e=[];if(t.timelockAssert<=0n&&e.push(`timelockAssert must be positive, got ${t.timelockAssert}`),t.timelockAssert>BigInt(A)&&e.push(`timelockAssert ${t.timelockAssert} exceeds uint16 max (${A})`),t.timelockChallengeAssert<=0n&&e.push(`timelockChallengeAssert must be positive, got ${t.timelockChallengeAssert}`),t.tRefund<=0&&e.push(`tRefund must be positive, got ${t.tRefund}`),t.tStale<=0&&e.push(`tStale must be positive, got ${t.tStale}`),t.securityCouncilKeys.length===0&&e.push("securityCouncilKeys must not be empty"),t.councilQuorum<=0&&e.push(`councilQuorum must be positive, got ${t.councilQuorum}`),t.councilQuorum>t.securityCouncilKeys.length&&e.push(`councilQuorum (${t.councilQuorum}) exceeds securityCouncilKeys count (${t.securityCouncilKeys.length})`),t.feeRate<=0n&&e.push(`feeRate must be positive, got ${t.feeRate}`),t.minPeginFeeRate<=0n&&e.push(`minPeginFeeRate must be positive, got ${t.minPeginFeeRate}`),(!Number.isInteger(t.proverCircuitVersion)||t.proverCircuitVersion<0||t.proverCircuitVersion>A)&&e.push(`proverCircuitVersion must be a uint16, got ${t.proverCircuitVersion}`),(!Number.isInteger(t.minPrepeginDepth)||t.minPrepeginDepth<=0||t.minPrepeginDepth>v)&&e.push(`minPrepeginDepth must be a uint32 in [1, ${v}], got ${t.minPrepeginDepth}`),t.babeTotalInstances<=0&&e.push(`babeTotalInstances must be positive, got ${t.babeTotalInstances}`),t.babeInstancesToFinalize<=0&&e.push(`babeInstancesToFinalize must be positive, got ${t.babeInstancesToFinalize}`),t.babeInstancesToFinalize>t.babeTotalInstances&&e.push(`babeInstancesToFinalize (${t.babeInstancesToFinalize}) exceeds babeTotalInstances (${t.babeTotalInstances})`),(t.minVpCommissionBps<0||t.minVpCommissionBps>V)&&e.push(`minVpCommissionBps must be in [0, ${V}], got ${t.minVpCommissionBps}`),e.length>0)throw new Error(`Invalid offchain protocol parameters: ${e.join("; ")}`)}function z(t){const e=[];if(t.minimumPegInAmount<=0n&&e.push(`minimumPegInAmount must be positive, got ${t.minimumPegInAmount}`),t.maxPegInAmount<t.minimumPegInAmount&&e.push(`maxPegInAmount (${t.maxPegInAmount}) must be >= minimumPegInAmount (${t.minimumPegInAmount})`),t.pegInAckTimeout<=0n&&e.push(`pegInAckTimeout must be positive, got ${t.pegInAckTimeout}`),t.pegInActivationTimeout<=0n&&e.push(`pegInActivationTimeout must be positive, got ${t.pegInActivationTimeout}`),(!Number.isInteger(t.maxHtlcOutputCount)||t.maxHtlcOutputCount<=0||t.maxHtlcOutputCount>E)&&e.push(`maxHtlcOutputCount must be an integer in [1, ${E}], got ${t.maxHtlcOutputCount}`),t.maxFundingInputCount!==null&&(!Number.isInteger(t.maxFundingInputCount)||t.maxFundingInputCount<=0||t.maxFundingInputCount>E)&&e.push(`maxFundingInputCount must be an integer in [1, ${E}], got ${t.maxFundingInputCount}`),(typeof t.expiredPegInGraceBlocks!="bigint"||t.expiredPegInGraceBlocks<=0n)&&e.push(`expiredPegInGraceBlocks must be a positive bigint, got ${t.expiredPegInGraceBlocks}`),e.length>0)throw new Error(`Invalid TBV protocol parameters: ${e.join("; ")}`)}function At(t){if(z(t),Y(t.offchainParams),!Number.isInteger(t.offchainParamsVersion)||t.offchainParamsVersion<0||t.offchainParamsVersion>v)throw new Error(`Invalid peg-in configuration: offchainParamsVersion must be a uint32, got ${t.offchainParamsVersion}`);p.assertValidVaultCoreVersion(t.activeVaultCoreVersion,"ProtocolParams.activeVaultCoreVersion()")}const G="RegistrationLogsUnavailableError";class R extends Error{constructor(n,o){super(o??`The Ethereum node returned no registration logs for block ${n}, which holds a vault registration; the node may not have indexed that block yet. Try again.`);y(this,"blockNumber");this.name=G,this.blockNumber=n}}function kt(t){return t instanceof R?!0:typeof t!="object"||t===null?!1:t.name===G}const Bt=2;function Rt(t,e,n){const o=e.toLowerCase(),i=t.find(u=>u.vaultId===o);if(i===void 0)throw new R(n,`Vault ${e} has no PegInSubmittedV2 registration log at its on-chain registration block ${n}: either the node served a partial answer for block ${n} (retry, preferably another node) or the vault was not registered in this block`);return i}function _t(t){return X(t.unsignedPrePeginTx)}function St(t){const e=(t.depositorPayoutScriptPubKey.length-Bt)/2;if(e===0||e>w.MAX_PAYOUT_SCRIPT_LEN)throw new Error(`PegInSubmittedV2 log for vault ${t.vaultId} carries a ${e}-byte depositorPayoutBtcAddress; expected 1..${w.MAX_PAYOUT_SCRIPT_LEN} bytes`)}exports.RegistrationLogsUnavailableError=R;exports.VaultClaimableByNotFoundError=W;exports.assertOnChainBtcPubkey=B;exports.assertPayoutScriptMatchesPopKey=xt;exports.assertRegisteredPayoutScriptBounds=St;exports.assertValidOffchainParamsVersion=Tt;exports.calculateBtcTxHash=X;exports.deriveP2trScript=M;exports.derivePeginVaultId=vt;exports.findRegistrationRecord=Rt;exports.isRegistrationLogsUnavailableError=kt;exports.isVaultClaimableByNotFoundError=Ct;exports.registrationPrePeginTxHash=_t;exports.ripemd160=H;exports.validateOffchainParams=Y;exports.validatePegInConfiguration=At;exports.validateTBVProtocolParams=z;
2
- //# sourceMappingURL=registration-records-XQMIKjGV.cjs.map