@babylonlabs-io/ts-sdk 0.44.0 → 0.45.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 (74) hide show
  1. package/README.md +0 -1
  2. package/dist/{BTCVaultRegistry.abi-Cq9-JlqT.js → BTCVaultRegistry.abi-Chs4AFBj.js} +125 -2
  3. package/dist/BTCVaultRegistry.abi-Chs4AFBj.js.map +1 -0
  4. package/dist/{BTCVaultRegistry.abi-CHFGevwa.cjs → BTCVaultRegistry.abi-JdeqLz4x.cjs} +2 -2
  5. package/dist/BTCVaultRegistry.abi-JdeqLz4x.cjs.map +1 -0
  6. package/dist/{PeginManager-BezsAEDe.js → PeginManager-CFGjwYtC.js} +4 -4
  7. package/dist/{PeginManager-BezsAEDe.js.map → PeginManager-CFGjwYtC.js.map} +1 -1
  8. package/dist/{PeginManager-D-8vmqzq.cjs → PeginManager-CL1Esl1c.cjs} +2 -2
  9. package/dist/{PeginManager-D-8vmqzq.cjs.map → PeginManager-CL1Esl1c.cjs.map} +1 -1
  10. package/dist/{buildAndBroadcastRefund-37Bs7-V1.js → buildAndBroadcastRefund-CZj2z7PJ.js} +2 -2
  11. package/dist/{buildAndBroadcastRefund-37Bs7-V1.js.map → buildAndBroadcastRefund-CZj2z7PJ.js.map} +1 -1
  12. package/dist/{buildAndBroadcastRefund-DbcNEsOv.cjs → buildAndBroadcastRefund-Ux587SFf.cjs} +2 -2
  13. package/dist/{buildAndBroadcastRefund-DbcNEsOv.cjs.map → buildAndBroadcastRefund-Ux587SFf.cjs.map} +1 -1
  14. package/dist/{errors-CznAK5NB.js → errors-Blc-JWnI.js} +71 -46
  15. package/dist/errors-Blc-JWnI.js.map +1 -0
  16. package/dist/errors-CGcNP0rV.cjs +2 -0
  17. package/dist/errors-CGcNP0rV.cjs.map +1 -0
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.js +106 -107
  20. package/dist/{mempoolApi-CknccHKg.cjs → mempoolApi-DcHws8jJ.cjs} +2 -2
  21. package/dist/{mempoolApi-CknccHKg.cjs.map → mempoolApi-DcHws8jJ.cjs.map} +1 -1
  22. package/dist/{mempoolApi-DI9HISqi.js → mempoolApi-DnP7d084.js} +2 -2
  23. package/dist/{mempoolApi-DI9HISqi.js.map → mempoolApi-DnP7d084.js.map} +1 -1
  24. package/dist/primeVpAuth-BihAGyNf.cjs +2 -0
  25. package/dist/{primeVpAuth-Duds3vAO.cjs.map → primeVpAuth-BihAGyNf.cjs.map} +1 -1
  26. package/dist/{primeVpAuth-qEC9TTO_.js → primeVpAuth-DXl9wGBR.js} +361 -341
  27. package/dist/{primeVpAuth-qEC9TTO_.js.map → primeVpAuth-DXl9wGBR.js.map} +1 -1
  28. package/dist/reservation-BxvKbQH2.js +107 -0
  29. package/dist/reservation-BxvKbQH2.js.map +1 -0
  30. package/dist/reservation-xTL2a9Q-.cjs +2 -0
  31. package/dist/reservation-xTL2a9Q-.cjs.map +1 -0
  32. package/dist/tbv/core/clients/index.cjs +1 -1
  33. package/dist/tbv/core/clients/index.js +2 -2
  34. package/dist/tbv/core/clients/vault-provider/auth/gatedMethods.d.ts +12 -0
  35. package/dist/tbv/core/clients/vault-provider/auth/gatedMethods.d.ts.map +1 -1
  36. package/dist/tbv/core/clients/vault-provider/auth/innerTokenClient.d.ts +8 -0
  37. package/dist/tbv/core/clients/vault-provider/auth/innerTokenClient.d.ts.map +1 -1
  38. package/dist/tbv/core/clients/vault-provider/auth/tokenProvider.d.ts +42 -13
  39. package/dist/tbv/core/clients/vault-provider/auth/tokenProvider.d.ts.map +1 -1
  40. package/dist/tbv/core/clients/vault-provider/auth/tokenRegistry.d.ts.map +1 -1
  41. package/dist/tbv/core/contracts/__tests__/errors.test.d.ts +2 -0
  42. package/dist/tbv/core/contracts/__tests__/errors.test.d.ts.map +1 -0
  43. package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts +292 -0
  44. package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts.map +1 -1
  45. package/dist/tbv/core/contracts/errors.d.ts.map +1 -1
  46. package/dist/tbv/core/contracts/index.cjs +1 -1
  47. package/dist/tbv/core/contracts/index.js +2 -2
  48. package/dist/tbv/core/index.cjs +1 -1
  49. package/dist/tbv/core/index.js +102 -103
  50. package/dist/tbv/core/managers/index.cjs +1 -1
  51. package/dist/tbv/core/managers/index.js +1 -1
  52. package/dist/tbv/core/services/index.cjs +1 -1
  53. package/dist/tbv/core/services/index.js +1 -1
  54. package/dist/tbv/core/utils/index.cjs +1 -1
  55. package/dist/tbv/core/utils/index.js +32 -33
  56. package/dist/tbv/core/utils/utxo/__tests__/reservation.test.d.ts +0 -1
  57. package/dist/tbv/core/utils/utxo/__tests__/reservation.test.d.ts.map +1 -1
  58. package/dist/tbv/core/utils/utxo/availability.d.ts +22 -1
  59. package/dist/tbv/core/utils/utxo/availability.d.ts.map +1 -1
  60. package/dist/tbv/core/utils/utxo/reservation.d.ts +11 -86
  61. package/dist/tbv/core/utils/utxo/reservation.d.ts.map +1 -1
  62. package/dist/tbv/index.cjs +1 -1
  63. package/dist/tbv/index.js +102 -103
  64. package/package.json +1 -1
  65. package/dist/BTCVaultRegistry.abi-CHFGevwa.cjs.map +0 -1
  66. package/dist/BTCVaultRegistry.abi-Cq9-JlqT.js.map +0 -1
  67. package/dist/errors-BP73_stm.cjs +0 -2
  68. package/dist/errors-BP73_stm.cjs.map +0 -1
  69. package/dist/errors-CznAK5NB.js.map +0 -1
  70. package/dist/primeVpAuth-Duds3vAO.cjs +0 -2
  71. package/dist/reservation-Cwf2u4vu.cjs +0 -2
  72. package/dist/reservation-Cwf2u4vu.cjs.map +0 -1
  73. package/dist/reservation-DNOGLBt4.js +0 -143
  74. package/dist/reservation-DNOGLBt4.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-CznAK5NB.js","sources":["../src/tbv/core/contracts/errors.ts"],"sourcesContent":["/**\n * Contract Error Handling Utilities\n *\n * Provides utilities for extracting and handling contract revert errors.\n * Maps known error selectors to user-friendly messages.\n *\n * @module contracts/errors\n */\n\n/**\n * Known contract error signatures mapped to user-friendly messages.\n *\n * Error selectors are the first 4 bytes of keccak256(error signature).\n * Example: keccak256(\"VaultAlreadyExists()\") = 0x04aabf33...\n */\nexport const CONTRACT_ERRORS: Record<string, string> = {\n // VaultAlreadyExists()\n \"0x04aabf33\":\n \"Vault already exists: This Bitcoin transaction has already been registered. \" +\n \"Please select different UTXOs or use a different amount to create a unique transaction.\",\n // ScriptPubKeyMismatch() - taproot output doesn't match expected script\n \"0x4fec082d\":\n \"Script mismatch: The Bitcoin transaction's taproot output does not match the expected vault script. \" +\n \"This may be caused by incorrect vault participants or key configuration.\",\n // InvalidBTCProofOfPossession()\n \"0x6cc363a5\":\n \"Invalid BTC proof of possession: The signature could not be verified. \" +\n \"Please ensure you're signing with the correct Bitcoin wallet.\",\n // InvalidBTCPublicKey()\n \"0x6c3f2bf6\":\n \"Invalid BTC public key: The Bitcoin public key format is invalid.\",\n // InvalidAmount()\n \"0x2c5211c6\":\n \"Invalid amount: The deposit amount is invalid or below the minimum required.\",\n // ApplicationNotRegistered()\n \"0x0405f772\":\n \"Application not registered: The application controller is not registered in the system.\",\n // InvalidProviderStatus()\n \"0x24e165cc\":\n \"Invalid provider status: The vault provider is not in a valid state to accept deposits.\",\n // ZeroAddress()\n \"0xd92e233d\":\n \"Zero address: One of the required addresses is the zero address.\",\n // BtcKeyMismatch()\n \"0x65aa7007\":\n \"BTC key mismatch: The Bitcoin public key does not match the expected key.\",\n // Unauthorized()\n \"0x82b42900\":\n \"Unauthorized: You must be the depositor or vault provider to submit this transaction.\",\n // InvalidSignature() - common signature verification error\n \"0x8baa579f\":\n \"Invalid signature: The BTC proof of possession signature could not be verified.\",\n // InvalidBtcTransaction()\n \"0x2f9d01e9\":\n \"Invalid BTC transaction: The Bitcoin transaction format is invalid.\",\n // VaultProviderNotRegistered()\n \"0x5a3c6b3e\":\n \"Vault provider not registered: The selected vault provider is not registered.\",\n // InvalidPeginFee(uint256,uint256)\n \"0x979f4518\":\n \"Invalid pegin fee: The ETH fee sent does not match the required amount. \" +\n \"This may indicate a fee rate change during the transaction.\",\n // PrePeginOutputAlreadyUsed()\n \"0x5fad9694\":\n \"This pre-pegin output has already been used to activate another vault.\",\n // PeginTransactionAlreadyUsed()\n \"0x7ed061c9\":\n \"This pegin transaction has already been used to activate another vault.\",\n};\n\n/**\n * Extract error data from various error formats.\n *\n * Viem and wallet providers wrap errors in multiple levels. This function\n * searches through the error chain to find the revert data.\n *\n * @param error - The error object to extract data from\n * @returns The error data (e.g., \"0x04aabf33\") or undefined\n */\nexport function extractErrorData(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n\n const err = error as Record<string, unknown>;\n\n // Check direct properties first\n if (typeof err.data === \"string\" && err.data.startsWith(\"0x\")) {\n return err.data;\n }\n if (typeof err.details === \"string\" && err.details.startsWith(\"0x\")) {\n return err.details;\n }\n\n // Walk the cause chain (viem wraps errors multiple levels deep)\n let current: unknown = err.cause;\n let depth = 0;\n const maxDepth = 5;\n\n while (current && typeof current === \"object\" && depth < maxDepth) {\n const cause = current as Record<string, unknown>;\n if (typeof cause.data === \"string\" && cause.data.startsWith(\"0x\")) {\n return cause.data;\n }\n current = cause.cause;\n depth++;\n }\n\n // Check error message for embedded hex error selector\n const message = typeof err.message === \"string\" ? err.message : \"\";\n const hexMatch = message.match(/\\b(0x[a-fA-F0-9]{8})\\b/);\n if (hexMatch) {\n return hexMatch[1];\n }\n\n return undefined;\n}\n\n/**\n * Get a user-friendly error message for a contract error.\n *\n * @param error - The error object from a contract call\n * @returns A user-friendly error message, or undefined if error is not recognized\n */\nexport function getContractErrorMessage(error: unknown): string | undefined {\n const errorData = extractErrorData(error);\n if (errorData) {\n // Check exact match first, then match by 4-byte selector prefix.\n // Parametric errors (e.g. InvalidPeginFee(uint256,uint256)) return\n // the selector + ABI-encoded args, so the full string won't match.\n const selector = errorData.substring(0, 10); // \"0x\" + 4 bytes\n return CONTRACT_ERRORS[errorData] ?? CONTRACT_ERRORS[selector];\n }\n return undefined;\n}\n\n/**\n * Check if an error is a known contract error.\n *\n * @param error - The error object to check\n * @returns True if the error is a known contract error\n */\nexport function isKnownContractError(error: unknown): boolean {\n const errorData = extractErrorData(error);\n if (errorData === undefined) return false;\n const selector = errorData.substring(0, 10);\n return errorData in CONTRACT_ERRORS || selector in CONTRACT_ERRORS;\n}\n\n/**\n * Handle a contract error by throwing a user-friendly error.\n *\n * This function extracts error data, maps it to a user-friendly message,\n * and throws an appropriate error. Use this in catch blocks after contract calls.\n *\n * @param error - The error from a contract call\n * @throws Always throws an error with a descriptive message\n */\nexport function handleContractError(error: unknown): never {\n // Log full error for debugging\n console.error(\"[Contract Error] Raw error:\", error);\n\n // Extract error data from the error chain\n const errorData = extractErrorData(error);\n console.error(\"[Contract Error] Extracted error data:\", errorData);\n\n // Check for known contract error signatures (exact match or 4-byte selector prefix)\n if (errorData) {\n const selector = errorData.substring(0, 10);\n const knownError = CONTRACT_ERRORS[errorData] ?? CONTRACT_ERRORS[selector];\n if (knownError) {\n console.error(\"[Contract Error] Known error:\", knownError);\n throw new Error(knownError);\n }\n }\n\n // Check for gas estimation errors or internal JSON-RPC errors\n const errorMsg = (error as Error)?.message || \"\";\n if (\n errorMsg.includes(\"gas limit too high\") ||\n errorMsg.includes(\"21000000\") ||\n errorMsg.includes(\"Internal JSON-RPC error\")\n ) {\n // If we found error data but it's not in our known list, include it\n const errorHint = errorData ? ` (error code: ${errorData})` : \"\";\n console.error(\n \"[Contract Error] Transaction rejected. Error code:\",\n errorData,\n \"Message:\",\n errorMsg,\n );\n throw new Error(\n `Transaction failed: The contract rejected this transaction${errorHint}. ` +\n \"Possible causes: (1) Vault already exists for this transaction, \" +\n \"(2) Invalid signature, (3) Unauthorized caller. \" +\n \"Please check your transaction parameters and try again.\",\n );\n }\n\n // Default: re-throw original error with better context\n if (error instanceof Error) {\n console.error(\"[Contract Error] Unhandled error:\", error.message);\n throw error;\n }\n throw new Error(`Contract call failed: ${String(error)}`);\n}\n"],"names":["CONTRACT_ERRORS","extractErrorData","error","err","current","depth","maxDepth","cause","hexMatch","getContractErrorMessage","errorData","selector","isKnownContractError","handleContractError","knownError","errorMsg","errorHint"],"mappings":"AAeO,MAAMA,IAA0C;AAAA;AAAA,EAErD,cACE;AAAA;AAAA,EAGF,cACE;AAAA;AAAA,EAGF,cACE;AAAA;AAAA,EAGF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAEF,cACE;AAAA;AAAA,EAGF,cACE;AAAA;AAAA,EAEF,cACE;AACJ;AAWO,SAASC,EAAiBC,GAAoC;AACnE,MAAI,CAACA,KAAS,OAAOA,KAAU,SAAU;AAEzC,QAAMC,IAAMD;AAGZ,MAAI,OAAOC,EAAI,QAAS,YAAYA,EAAI,KAAK,WAAW,IAAI;AAC1D,WAAOA,EAAI;AAEb,MAAI,OAAOA,EAAI,WAAY,YAAYA,EAAI,QAAQ,WAAW,IAAI;AAChE,WAAOA,EAAI;AAIb,MAAIC,IAAmBD,EAAI,OACvBE,IAAQ;AACZ,QAAMC,IAAW;AAEjB,SAAOF,KAAW,OAAOA,KAAY,YAAYC,IAAQC,KAAU;AACjE,UAAMC,IAAQH;AACd,QAAI,OAAOG,EAAM,QAAS,YAAYA,EAAM,KAAK,WAAW,IAAI;AAC9D,aAAOA,EAAM;AAEf,IAAAH,IAAUG,EAAM,OAChBF;AAAA,EACF;AAIA,QAAMG,KADU,OAAOL,EAAI,WAAY,WAAWA,EAAI,UAAU,IACvC,MAAM,wBAAwB;AACvD,MAAIK;AACF,WAAOA,EAAS,CAAC;AAIrB;AAQO,SAASC,EAAwBP,GAAoC;AAC1E,QAAMQ,IAAYT,EAAiBC,CAAK;AACxC,MAAIQ,GAAW;AAIb,UAAMC,IAAWD,EAAU,UAAU,GAAG,EAAE;AAC1C,WAAOV,EAAgBU,CAAS,KAAKV,EAAgBW,CAAQ;AAAA,EAC/D;AAEF;AAQO,SAASC,EAAqBV,GAAyB;AAC5D,QAAMQ,IAAYT,EAAiBC,CAAK;AACxC,MAAIQ,MAAc,OAAW,QAAO;AACpC,QAAMC,IAAWD,EAAU,UAAU,GAAG,EAAE;AAC1C,SAAOA,KAAaV,KAAmBW,KAAYX;AACrD;AAWO,SAASa,EAAoBX,GAAuB;AAEzD,UAAQ,MAAM,+BAA+BA,CAAK;AAGlD,QAAMQ,IAAYT,EAAiBC,CAAK;AAIxC,MAHA,QAAQ,MAAM,0CAA0CQ,CAAS,GAG7DA,GAAW;AACb,UAAMC,IAAWD,EAAU,UAAU,GAAG,EAAE,GACpCI,IAAad,EAAgBU,CAAS,KAAKV,EAAgBW,CAAQ;AACzE,QAAIG;AACF,oBAAQ,MAAM,iCAAiCA,CAAU,GACnD,IAAI,MAAMA,CAAU;AAAA,EAE9B;AAGA,QAAMC,KAAYb,KAAA,gBAAAA,EAAiB,YAAW;AAC9C,MACEa,EAAS,SAAS,oBAAoB,KACtCA,EAAS,SAAS,UAAU,KAC5BA,EAAS,SAAS,yBAAyB,GAC3C;AAEA,UAAMC,IAAYN,IAAY,iBAAiBA,CAAS,MAAM;AAC9D,kBAAQ;AAAA,MACN;AAAA,MACAA;AAAA,MACA;AAAA,MACAK;AAAA,IAAA,GAEI,IAAI;AAAA,MACR,6DAA6DC,CAAS;AAAA,IAAA;AAAA,EAK1E;AAGA,QAAId,aAAiB,SACnB,QAAQ,MAAM,qCAAqCA,EAAM,OAAO,GAC1DA,KAEF,IAAI,MAAM,yBAAyB,OAAOA,CAAK,CAAC,EAAE;AAC1D;"}
@@ -1,2 +0,0 @@
1
- "use strict";var de=Object.defineProperty;var pe=(r,e,t)=>e in r?de(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var f=(r,e,t)=>pe(r,typeof e!="symbol"?e+"":e,t);const X=require("./BTCVaultRegistry.abi-CHFGevwa.cjs"),g=require("./ApplicationRegistry.abi-BAPhJch3.cjs"),E=require("./mempoolApi-CknccHKg.cjs"),H=require("./types-eYlq0p1o.cjs"),m=require("./bitcoin-CHfKAhcI.cjs"),$=require("./validation-u8W7Lp2x.cjs"),he=require("@bitcoin-js/tiny-secp256k1-asmjs"),I=require("bitcoinjs-lib"),V=require("buffer"),G=require("./sha2-DsrLC4NM.cjs");function ge(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const t in r)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>r[t]})}}return e.default=r,Object.freeze(e)}const U=ge(he);async function fe(r,e){const[t,n]=await r.multicall({contracts:[{address:e,abi:X.BTCVaultRegistryABI,functionName:"protocolParams"},{address:e,abi:X.BTCVaultRegistryABI,functionName:"applicationRegistry"}],allowFailure:!1});return{protocolParams:t,applicationRegistry:n}}const F=65535;function C(r){return{timelockAssert:r.timelockAssert,timelockChallengeAssert:r.timelockChallengeAssert,securityCouncilKeys:[...r.securityCouncilKeys],councilQuorum:r.councilQuorum,feeRate:r.feeRate,babeTotalInstances:r.babeTotalInstances,babeInstancesToFinalize:r.babeInstancesToFinalize,minVpCommissionBps:r.minVpCommissionBps,tRefund:r.tRefund,tStale:r.tStale,minPeginFeeRate:r.minPeginFeeRate,proverCircuitVersion:r.proverCircuitVersion,minPrepeginDepth:r.minPrepeginDepth}}function q(r){return{minimumPegInAmount:r.minimumPegInAmount,maxPegInAmount:r.maxPegInAmount,pegInAckTimeout:r.pegInAckTimeout,pegInActivationTimeout:r.pegInActivationTimeout,maxHtlcOutputCount:r.maxHtlcOutputCount,expiredPegInGraceBlocks:r.expiredPegInGraceBlocks}}function Y(r){if(r>BigInt(F))throw new Error(`timelockAssert value ${r} exceeds uint16 max (${F})`);return Number(r)}class _e{constructor(e,t){this.publicClient=e,this.contractAddress=t}async getTBVProtocolParams(){const e=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getTBVProtocolParams"}),t=q(e);return E.validateTBVProtocolParams(t),t}async getLatestOffchainParams(){const e=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getLatestOffchainParams"}),t=C(e);return E.validateOffchainParams(t),t}async getOffchainParamsByVersion(e){const t=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getOffchainParamsByVersion",args:[e]}),n=C(t);return E.validateOffchainParams(n),n}async getLatestOffchainParamsVersion(){const e=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"latestOffchainParamsVersion"}),t=Number(e);return E.assertValidOffchainParamsVersion(t),t}async getTimelockPeginByVersion(e){const t=await this.getOffchainParamsByVersion(e);return Y(t.timelockAssert)}async getPegInConfiguration(){const e=await this.publicClient.multicall({contracts:[{address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getTBVProtocolParams"},{address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getLatestOffchainParams"},{address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"latestOffchainParamsVersion"}],allowFailure:!1}),t=q(e[0]),n=C(e[1]),i=Number(e[2]),a={minimumPegInAmount:t.minimumPegInAmount,maxPegInAmount:t.maxPegInAmount,pegInAckTimeout:t.pegInAckTimeout,pegInActivationTimeout:t.pegInActivationTimeout,maxHtlcOutputCount:t.maxHtlcOutputCount,expiredPegInGraceBlocks:t.expiredPegInGraceBlocks,timelockPegin:Y(n.timelockAssert),timelockRefund:n.tRefund,minVpCommissionBps:n.minVpCommissionBps,offchainParams:n,offchainParamsVersion:i};return E.validatePegInConfiguration(a),a}async fetchAllOffchainParams(e){const t=await this.getLatestOffchainParamsVersion();if(t===0)return{byVersion:new Map,latestVersion:0};const n=Array.from({length:t},(c,u)=>u+1),i=n.map(c=>({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getOffchainParamsByVersion",args:[c]})),a=await this.publicClient.multicall({contracts:i,allowFailure:!1}),o=new Map;for(let c=0;c<n.length;c++){const u=C(a[c]);try{E.validateOffchainParams(u),o.set(n[c],u)}catch(d){e==null||e(n[c],d instanceof Error?d:new Error(String(d)))}}return{byVersion:o,latestVersion:t}}}function N(r){return r.map(e=>({ethAddress:e.ethAddress,btcPubKey:e.btcPubKey}))}class me{constructor(e,t){this.publicClient=e,this.contractAddress=t}async getVaultKeepersByVersion(e,t){const n=await this.publicClient.readContract({address:this.contractAddress,abi:g.ApplicationRegistryABI,functionName:"getVaultKeepersByVersion",args:[e,t]});return N(n)}async getCurrentVaultKeepers(e){const t=await this.publicClient.readContract({address:this.contractAddress,abi:g.ApplicationRegistryABI,functionName:"getCurrentVaultKeepers",args:[e]});return N(t)}async getCurrentVaultKeepersVersion(e){return await this.publicClient.readContract({address:this.contractAddress,abi:g.ApplicationRegistryABI,functionName:"getCurrentVaultKeepersVersion",args:[e]})}}class be{constructor(e,t){this.publicClient=e,this.contractAddress=t}async getUniversalChallengersByVersion(e){const t=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getUniversalChallengersByVersion",args:[e]});return N(t)}async getCurrentUniversalChallengers(){const e=await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"getCurrentUniversalChallengers"});return N(e)}async getLatestUniversalChallengersVersion(){return await this.publicClient.readContract({address:this.contractAddress,abi:g.ProtocolParamsABI,functionName:"latestUniversalChallengersVersion"})}}var Z=(r=>(r[r.PENDING=0]="PENDING",r[r.VERIFIED=1]="VERIFIED",r[r.ACTIVE=2]="ACTIVE",r[r.REDEEMED=3]="REDEEMED",r[r.EXPIRED=4]="EXPIRED",r))(Z||{});const z=new Set(Object.values(H.DaemonStatus)),ye=200;function l(r){var e;return((e=JSON.stringify(r))==null?void 0:e.slice(0,ye))??"undefined"}const Pe="The vault provider returned an unexpected response. Please try again or contact support.";class s extends Error{constructor(t){super(Pe);f(this,"detail");this.name="VpResponseValidationError",this.detail=t}}const k=64;function v(r){return typeof r=="string"&&r.length>0&&$.HEX_RE.test(r)}function Q(r){return typeof r=="string"&&r.length>0}function ee(r,e){if(!v(r))throw new s(`VP response validation failed: "${e}" must be a non-empty hex string, got ${l(r)}`)}function b(r,e){if(!Q(r))throw new s(`VP response validation failed: "${e}" must be a non-empty string, got ${l(r)}`)}function L(r,e){if(!v(r)||r.length!==m.X_ONLY_PUBKEY_HEX_LEN&&r.length!==m.COMPRESSED_PUBKEY_HEX_LEN)throw new s(`VP response validation failed: "${e}" must be a ${m.X_ONLY_PUBKEY_HEX_LEN} or ${m.COMPRESSED_PUBKEY_HEX_LEN}-char hex string (BTC pubkey), got ${l(r)}`)}function we(r){const e=r.presigning;if(e==null)return;if(typeof e!="object"||Array.isArray(e))throw new s('VP response validation failed: "progress.presigning" must be an object if present');const t=e;if(t.depositor_graph_created!==void 0&&typeof t.depositor_graph_created!="boolean")throw new s(`VP response validation failed: "progress.presigning.depositor_graph_created" must be a boolean if present, got ${l(t.depositor_graph_created)}`);if(t.vk_challenger_presigning_completed!==void 0&&typeof t.vk_challenger_presigning_completed!="number")throw new s(`VP response validation failed: "progress.presigning.vk_challenger_presigning_completed" must be a number if present, got ${l(t.vk_challenger_presigning_completed)}`);if(t.vk_challenger_presigning_total!==void 0&&typeof t.vk_challenger_presigning_total!="number")throw new s(`VP response validation failed: "progress.presigning.vk_challenger_presigning_total" must be a number if present, got ${l(t.vk_challenger_presigning_total)}`)}function te(r){if(r===null||typeof r!="object")throw new s("VP response validation failed: getPeginStatus response is not an object");const e=r;if(!v(e.pegin_txid)||e.pegin_txid.length!==k)throw new s(`VP response validation failed: "pegin_txid" must be a ${k}-char hex string (txid), got ${l(e.pegin_txid)}`);if(typeof e.status!="string")throw new s('VP response validation failed: "status" must be a string');if(!z.has(e.status))throw new s(`VP response validation failed: unrecognized status "${e.status}". Expected one of: ${[...z].join(", ")}`);if(e.progress===null||typeof e.progress!="object"||Array.isArray(e.progress))throw new s('VP response validation failed: "progress" must be an object');if(we(e.progress),typeof e.health_info!="string")throw new s('VP response validation failed: "health_info" must be a string');if(e.last_error!==void 0&&typeof e.last_error!="string")throw new s(`VP response validation failed: "last_error" must be a string if present, got ${l(e.last_error)}`)}function ve(r){if(r===null||typeof r!="object")throw new s("VP response validation failed: requestDepositorPresignTransactions response is not an object");const e=r;if(!Array.isArray(e.txs))throw new s('VP response validation failed: "txs" must be an array');for(let t=0;t<e.txs.length;t++)xe(e.txs[t],`txs[${t}]`);if(e.depositor_graph===null||typeof e.depositor_graph!="object")throw new s('VP response validation failed: "depositor_graph" must be an object');Ie(e.depositor_graph)}function P(r,e){if(r===null||typeof r!="object")throw new s(`VP response validation failed: "${e}" must be an object`);ee(r.tx_hex,`${e}.tx_hex`)}function xe(r,e){if(r===null||typeof r!="object")throw new s(`VP response validation failed: "${e}" must be an object`);const t=r;L(t.claimer_pubkey,`${e}.claimer_pubkey`),P(t.claim_tx,`${e}.claim_tx`),P(t.assert_tx,`${e}.assert_tx`),P(t.payout_tx,`${e}.payout_tx`),b(t.payout_psbt,`${e}.payout_psbt`)}function Ae(r,e){if(r===null||typeof r!="object")throw new s(`VP response validation failed: "${e}" must be an object`);const t=r;b(t.wots_pks_json,`${e}.wots_pks_json`),b(t.gc_wots_keys_json,`${e}.gc_wots_keys_json`)}function Ee(r,e){if(r===null||typeof r!="object")throw new s(`VP response validation failed: "${e}" must be an object`);const t=r;if(L(t.challenger_pubkey,`${e}.challenger_pubkey`),P(t.challenge_assert_x_tx,`${e}.challenge_assert_x_tx`),P(t.challenge_assert_y_tx,`${e}.challenge_assert_y_tx`),P(t.nopayout_tx,`${e}.nopayout_tx`),b(t.nopayout_psbt,`${e}.nopayout_psbt`),!Array.isArray(t.challenge_assert_connectors))throw new s(`VP response validation failed: "${e}.challenge_assert_connectors" must be an array`);for(let n=0;n<t.challenge_assert_connectors.length;n++)Ae(t.challenge_assert_connectors[n],`${e}.challenge_assert_connectors[${n}]`);if(!Array.isArray(t.output_label_hashes))throw new s(`VP response validation failed: "${e}.output_label_hashes" must be an array`);for(let n=0;n<t.output_label_hashes.length;n++)ee(t.output_label_hashes[n],`${e}.output_label_hashes[${n}]`)}function re(r){if(r===null||typeof r!="object")throw new s("VP response validation failed: requestDepositorClaimerArtifacts response is not an object");const e=r;if(!Q(e.tx_graph_json))throw new s(`VP response validation failed: "tx_graph_json" must be a non-empty string, got ${l(e.tx_graph_json)}`);if(!v(e.verifying_key_hex))throw new s(`VP response validation failed: "verifying_key_hex" must be a non-empty hex string, got ${l(e.verifying_key_hex)}`);if(e.babe_sessions===null||typeof e.babe_sessions!="object"||Array.isArray(e.babe_sessions))throw new s('VP response validation failed: "babe_sessions" must be an object');const t=Object.entries(e.babe_sessions);if(t.length===0)throw new s('VP response validation failed: "babe_sessions" must contain at least one challenger entry');for(const[n,i]of t){if(L(n,`babe_sessions["${n}"]`),i===null||typeof i!="object")throw new s(`VP response validation failed: "babe_sessions.${n}" must be an object`);const a=i;if(!v(a.decryptor_artifacts_hex))throw new s(`VP response validation failed: "babe_sessions.${n}.decryptor_artifacts_hex" must be a non-empty hex string, got ${l(a.decryptor_artifacts_hex)}`)}}function Ve(r){if(r===null||typeof r!="object")throw new s("VP response validation failed: pegout status payload is not an object");const e=r;if(!v(e.pegin_txid)||e.pegin_txid.length!==k)throw new s(`VP response validation failed: "pegin_txid" must be a ${k}-char hex string (txid), got ${l(e.pegin_txid)}`);if(typeof e.found!="boolean")throw new s(`VP response validation failed: "found" must be a boolean, got ${l(e.found)}`);if(e.claimer!==null){if(typeof e.claimer!="object")throw new s(`VP response validation failed: "claimer" must be an object or null, got ${l(e.claimer)}`);ke(e.claimer)}if(!Array.isArray(e.challengers))throw new s(`VP response validation failed: "challengers" must be an array, got ${l(e.challengers)}`);for(let t=0;t<e.challengers.length;t++)$e(e.challengers[t],t)}function ke(r){if(b(r.status,"claimer.status"),typeof r.failed!="boolean")throw new s(`VP response validation failed: "claimer.failed" must be a boolean, got ${l(r.failed)}`);if(b(r.claim_txid,"claimer.claim_txid"),b(r.claimer_pubkey,"claimer.claimer_pubkey"),b(r.assert_txid,"claimer.assert_txid"),typeof r.created_at!="number")throw new s(`VP response validation failed: "claimer.created_at" must be a number, got ${l(r.created_at)}`);if(typeof r.updated_at!="number")throw new s(`VP response validation failed: "claimer.updated_at" must be a number, got ${l(r.updated_at)}`)}function $e(r,e){if(r===null||typeof r!="object")throw new s(`VP response validation failed: "challengers[${e}]" must be an object, got ${l(r)}`);const t=r;if(b(t.status,`challengers[${e}].status`),b(t.claim_txid,`challengers[${e}].claim_txid`),b(t.claimer_pubkey,`challengers[${e}].claimer_pubkey`),R(t.assert_txid,`challengers[${e}].assert_txid`),R(t.challenge_assert_x_txid,`challengers[${e}].challenge_assert_x_txid`),R(t.challenge_assert_y_txid,`challengers[${e}].challenge_assert_y_txid`),R(t.nopayout_txid,`challengers[${e}].nopayout_txid`),typeof t.created_at!="number")throw new s(`VP response validation failed: "challengers[${e}].created_at" must be a number, got ${l(t.created_at)}`);if(typeof t.updated_at!="number")throw new s(`VP response validation failed: "challengers[${e}].updated_at" must be a number, got ${l(t.updated_at)}`)}function R(r,e){if(r!==null&&typeof r!="string")throw new s(`VP response validation failed: "${e}" must be a string or null, got ${l(r)}`)}function Se(r){ne(r,"batchGetPeginStatus",e=>{e.result!==null&&te(e.result)})}function Te(r){ne(r,"batchGetPegoutStatus",e=>{e.result!==null&&Ve(e.result)})}function ne(r,e,t){if(r===null||typeof r!="object")throw new s(`VP response validation failed: ${e} response is not an object`);const n=r;if(!Array.isArray(n.results))throw new s(`VP response validation failed: "${e}.results" must be an array, got ${l(n.results)}`);for(let i=0;i<n.results.length;i++){const a=n.results[i];if(a===null||typeof a!="object")throw new s(`VP response validation failed: "${e}.results[${i}]" must be an object, got ${l(a)}`);const o=a;if(!v(o.pegin_txid)||o.pegin_txid.length!==k)throw new s(`VP response validation failed: "${e}.results[${i}].pegin_txid" must be a ${k}-char hex string, got ${l(o.pegin_txid)}`);if(o.error!==null&&typeof o.error!="string")throw new s(`VP response validation failed: "${e}.results[${i}].error" must be a string or null, got ${l(o.error)}`);if(o.result===null&&o.error===null)throw new s(`VP response validation failed: "${e}.results[${i}]" has neither "result" nor "error" populated`);if(o.result!==null&&o.error!==null)throw new s(`VP response validation failed: "${e}.results[${i}]" has both "result" and "error" populated`);t(o,i)}}function Ie(r){if(P(r.claim_tx,"depositor_graph.claim_tx"),P(r.assert_tx,"depositor_graph.assert_tx"),P(r.payout_tx,"depositor_graph.payout_tx"),b(r.payout_psbt,"depositor_graph.payout_psbt"),!Array.isArray(r.challenger_presign_data))throw new s('VP response validation failed: "depositor_graph.challenger_presign_data" must be an array');for(let e=0;e<r.challenger_presign_data.length;e++)Ee(r.challenger_presign_data[e],`depositor_graph.challenger_presign_data[${e}]`);if(typeof r.offchain_params_version!="number")throw new s('VP response validation failed: "depositor_graph.offchain_params_version" must be a number')}const Ce=6e4;class se{constructor(e,t){f(this,"client");const n={baseUrl:e,timeout:(t==null?void 0:t.timeout)??Ce,retries:t==null?void 0:t.retries,retryDelay:t==null?void 0:t.retryDelay,retryableFor:t==null?void 0:t.retryableFor,headers:t==null?void 0:t.headers,tokenProvider:t==null?void 0:t.tokenProvider,maxResponseBytes:t==null?void 0:t.maxResponseBytes};this.client=new H.JsonRpcClient(n)}async requestDepositorPresignTransactions(e,t){const n=await this.client.call("vaultProvider_requestDepositorPresignTransactions",e,t);return ve(n),n}async submitDepositorPresignatures(e,t){return this.client.call("vaultProvider_submitDepositorPresignatures",e,t)}async submitDepositorWotsKey(e,t){return this.client.call("vaultProvider_submitDepositorWotsKey",e,t)}async requestDepositorClaimerArtifacts(e,t){const n=await this.client.call("vaultProvider_requestDepositorClaimerArtifacts",e,t);return re(n),n}async getPeginStatus(e,t){const n=await this.client.call("vaultProvider_getPeginStatus",e,t);return te(n),n}async batchGetPeginStatus(e,t){const n=await this.client.call("vaultProvider_batchGetPeginStatus",e,t);return Se(n),n}async batchGetPegoutStatus(e,t){const n=await this.client.call("vaultProvider_batchGetPegoutStatus",e,t);return Te(n),n}}function Re(r,e){const t=new Set;for(const u of r)t.add(u.toLowerCase());const n=new Map,i=new Set,a=[],o=[];for(const u of e){const d=u.pegin_txid.toLowerCase();if(!t.has(d)){o.push(d);continue}if(i.has(d)){a.push(d);continue}i.add(d),n.set(d,{result:u.result,error:u.error})}const c=[];for(const u of t)i.has(u)||c.push(u);return{byTxid:n,missing:c,unexpected:o,duplicate:a}}async function Be(r){const{items:e,getTxid:t,batchCall:n,onItem:i,onMissing:a,onDuplicate:o,onDuplicateBatch:c,onWholeBatchError:u,onUnexpected:d,batchSize:_=H.VP_BATCH_MAX_SIZE}=r;if(!Number.isInteger(_)||_<=0)throw new Error(`batchPollByProvider: batchSize must be a positive integer, got ${_}`);for(let w=0;w<e.length;w+=_){const x=e.slice(w,w+_),S=new Map,O=[];for(const p of x){const y=t(p).toLowerCase();S.set(y,p),O.push(y)}let A;try{const p=await n(O);A=Re(O,p.results)}catch(p){u(x,p);continue}d&&A.unexpected.length>0&&d(A.unexpected);const T=new Set(A.duplicate);for(const p of T){const y=S.get(p);y&&o(y)}c&&T.size>0&&c(T.size);for(const p of A.missing){const y=S.get(p);y&&a(y)}for(const[p,y]of A.byTxid){if(T.has(p))continue;const K=S.get(p);K&&i(K,{pegin_txid:p,result:y.result,error:y.error})}}}const Ne="BIP0322-signed-message",De="TapTweak",ie=32,He=64;function ae(r,e){const t=new TextEncoder().encode(r),n=G.sha256(t),i=new Uint8Array(n.length*2+e.length);return i.set(n,0),i.set(n,n.length),i.set(e,n.length*2),G.sha256(i)}function Oe(r){if(r.length!==ie)return null;const e=ae(De,r),t=U.xOnlyPointAddTweak(r,e);return t?t.xOnlyPubkey:null}function je(r,e,t){if(e.length!==ie||t.length!==He)return!1;try{const n=ae(Ne,r),i=I.payments.p2tr({internalPubkey:V.Buffer.from(e)});if(!i.output)return!1;const a=i.output,o=0,c=new I.Transaction;c.version=0,c.locktime=0;const u=V.Buffer.concat([V.Buffer.from([0,32]),V.Buffer.from(n)]);c.addInput(V.Buffer.alloc(32,0),4294967295,0,u),c.addOutput(a,o);const d=new I.Transaction;d.version=0,d.locktime=0;const _=c.getHash();d.addInput(_,0,0),d.addOutput(V.Buffer.from([106]),o);const w=d.hashForWitnessV1(0,[a],[o],I.Transaction.SIGHASH_DEFAULT),x=Oe(e);return x?U.verifySchnorr(w,x,t):!1}catch{return!1}}function D(r,e){const t=(r&7)<<5,n=typeof e=="bigint"?e:BigInt(e);if(n<0n)throw new Error("cborHead: negative argument");if(n<24n)return new Uint8Array([t|Number(n)]);if(n<0x100n)return new Uint8Array([t|24,Number(n)]);if(n<0x10000n){const a=Number(n);return new Uint8Array([t|25,a>>>8&255,a&255])}if(n<0x100000000n){const a=Number(n);return new Uint8Array([t|26,a>>>24&255,a>>>16&255,a>>>8&255,a&255])}const i=new Uint8Array(9);i[0]=t|27;for(let a=7;a>=0;a--)i[1+a]=Number(n>>BigInt((7-a)*8))&255;return i}function oe(...r){const e=r.reduce((i,a)=>i+a.length,0),t=new Uint8Array(e);let n=0;for(const i of r)t.set(i,n),n+=i.length;return t}function W(r){const t=[D(4,r.length)];for(const n of r)t.push(D(0,n));return oe(...t)}function Ue(r,e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error(`encodeServerIdentityPayload: expires_at must be a non-negative safe integer, got ${t}`);const n=D(4,3),i=W(r),a=W(e),o=D(0,t);return oe(n,i,a,o)}const Le=new TextEncoder().encode("btc-auth.server-identity.v1"),Me=2*3600;class h extends Error{constructor(e,t){super(e),this.reason=t,this.name="ServerIdentityError"}}function B(r){const e=new Uint8Array(r.length/2);for(let t=0;t<e.length;t++)e[t]=parseInt(r.slice(t*2,t*2+2),16);return e}function ce(r){const{proof:e,pinnedServerPubkey:t,now:n}=r,i=r.maxLifetimeSecs??Me,a=m.stripHexPrefix(t).toLowerCase();if(a.length!==m.X_ONLY_PUBKEY_HEX_LEN||!$.HEX_RE.test(a))throw new h(`pinnedServerPubkey must be 32-byte hex; got ${a.length} chars`,"invalid_pubkey_encoding");const o=m.stripHexPrefix(e.server_pubkey).toLowerCase();if(o.length!==m.X_ONLY_PUBKEY_HEX_LEN||!$.HEX_RE.test(o))throw new h(`server_pubkey must be 32-byte hex; got ${o.length} chars`,"invalid_pubkey_encoding");if(o!==a)throw new h(`server_pubkey does not match pinned value: expected ${a}, got ${o}`,"pinned_pubkey_mismatch");if(!Number.isSafeInteger(e.expires_at))throw new h(`expires_at must be a finite integer; got ${JSON.stringify(e.expires_at)}`,"invalid_expires_at");if(!Number.isSafeInteger(n))throw new h(`now must be a finite integer; got ${JSON.stringify(n)}`,"invalid_expires_at");if(e.expires_at<=n)throw new h(`server identity proof expired at ${e.expires_at}, now ${n}`,"expired");if(!Number.isSafeInteger(i)||i<=0)throw new h(`maxLifetimeSecs must be a positive safe integer; got ${JSON.stringify(i)}`,"invalid_max_lifetime");if(e.expires_at-n>i)throw new h(`server identity proof expires too far in the future: expires_at=${e.expires_at}, now=${n}, max lifetime=${i}s`,"expires_too_far");const c=m.stripHexPrefix(e.ephemeral_pubkey).toLowerCase();if(c.length!==m.COMPRESSED_PUBKEY_HEX_LEN||!$.HEX_RE.test(c))throw new h(`ephemeral_pubkey must be 33-byte compressed hex; got ${c.length} chars`,"invalid_ephemeral_pubkey");const u=c.slice(0,2);if(u!=="02"&&u!=="03")throw new h(`ephemeral_pubkey must be compressed (prefix 02/03); got ${u}`,"invalid_ephemeral_pubkey");const d=B(c);if(!U.isPoint(d))throw new h("ephemeral_pubkey is not a valid secp256k1 point","invalid_ephemeral_pubkey");const _=m.stripHexPrefix(e.signature).toLowerCase();if(_.length!==m.SCHNORR_SIG_HEX_LEN||!$.HEX_RE.test(_))throw new h(`signature must be 64-byte Schnorr hex; got ${_.length} chars`,"invalid_signature_encoding");const w=Ue(Le,B(c),e.expires_at);if(!je(w,B(o),B(_)))throw new h("BIP-322 signature verification failed — ephemeral key is not attested by pinned server pubkey","signature_verification_failed")}const Ke=new Set(["vaultProvider_submitDepositorWotsKey","vaultProvider_submitDepositorPresignatures","vaultProvider_requestDepositorPresignTransactions","vaultProvider_requestDepositorClaimerArtifacts"]),Xe=6e4,j="auth_createDepositorToken";function le(r,e){return new H.JsonRpcClient({baseUrl:r,timeout:Xe,headers:e,retryableFor:t=>t===j})}const J=4102444800,Ge=30;class Fe{constructor(e){f(this,"client");f(this,"peginTxid");f(this,"authAnchorHex");f(this,"pinnedServerPubkey");f(this,"authGatedMethods");f(this,"refreshSkewSecs");f(this,"now");f(this,"cached",null);f(this,"inFlight",null);this.client=e.client,this.peginTxid=e.peginTxid,this.authAnchorHex=e.authAnchorHex,this.pinnedServerPubkey=e.pinnedServerPubkey,this.authGatedMethods=e.authGatedMethods,this.refreshSkewSecs=e.refreshSkewSecs??Ge,this.now=e.now??(()=>Math.floor(Date.now()/1e3))}async getToken(e){if(e===j||!this.authGatedMethods.has(e))return null;const t=this.cached;return t&&this.now()+this.refreshSkewSecs<t.expiresAt?t.token:(await this.acquireSingleFlight()).token}invalidate(){this.cached=null}setClient(e){this.client=e}acquireSingleFlight(){const e=this.inFlight;if(e)return e;const t=(async()=>{try{const n=await this.client.call(j,{pegin_txid:this.peginTxid,auth_anchor:this.authAnchorHex});if(ce({proof:n.server_identity,pinnedServerPubkey:this.pinnedServerPubkey,now:this.now()}),typeof n.token!="string"||n.token.length===0)throw new Error(`VpTokenProvider: invalid token in acquire response (expected non-empty string, got ${typeof n.token})`);const i=this.now();if(!Number.isSafeInteger(n.expires_at)||n.expires_at<=i||n.expires_at>J)throw new Error(`VpTokenProvider: invalid expires_at in acquire response (got ${JSON.stringify(n.expires_at)}; must be a safe integer in (${i}, ${J}])`);const a={token:n.token,expiresAt:n.expires_at};return this.cached=a,a}finally{this.inFlight=null}})();return this.inFlight=t,t}}class ue{constructor(){f(this,"entries",new Map)}getOrCreate(e){const t=this.entries.get(e.peginTxid);if(t){if(t.authAnchorHex!==e.authAnchorHex)throw new Error(`VpTokenRegistry: peginTxid ${e.peginTxid} already bound to authAnchorHex ${t.authAnchorHex.slice(0,8)}…; got ${e.authAnchorHex.slice(0,8)}…`);if(t.pinnedServerPubkey!==e.pinnedServerPubkey)throw new Error(`VpTokenRegistry: peginTxid ${e.peginTxid} already bound to pinnedServerPubkey ${t.pinnedServerPubkey.slice(0,8)}…; got ${e.pinnedServerPubkey.slice(0,8)}…`);return t.provider.setClient(e.client),t.provider}const n=new Fe({client:e.client,peginTxid:e.peginTxid,authAnchorHex:e.authAnchorHex,pinnedServerPubkey:e.pinnedServerPubkey,authGatedMethods:Ke});return this.entries.set(e.peginTxid,{provider:n,authAnchorHex:e.authAnchorHex,pinnedServerPubkey:e.pinnedServerPubkey}),n}peek(e){var t;return(t=this.entries.get(e))==null?void 0:t.provider}release(e){this.entries.delete(e)}clear(){this.entries.clear()}get size(){return this.entries.size}}const M=new ue;function qe(r){var n;const e=le(r.baseUrl,(n=r.options)==null?void 0:n.headers),t=M.getOrCreate({client:e,peginTxid:r.peginTxid,authAnchorHex:r.authAnchorHex,pinnedServerPubkey:r.pinnedServerPubkey});return new se(r.baseUrl,{...r.options,tokenProvider:t})}function Ye(r){M.getOrCreate({client:le(r.baseUrl,r.headers),peginTxid:r.peginTxid,authAnchorHex:r.authAnchorHex,pinnedServerPubkey:r.pinnedServerPubkey})}exports.OnChainBtcVaultStatus=Z;exports.ServerIdentityError=h;exports.VaultProviderRpcClient=se;exports.ViemProtocolParamsReader=_e;exports.ViemUniversalChallengerReader=be;exports.ViemVaultKeeperReader=me;exports.VpResponseValidationError=s;exports.VpTokenRegistry=ue;exports.batchPollByProvider=Be;exports.createAuthenticatedVpClient=qe;exports.primeVpTokenRegistry=Ye;exports.resolveProtocolAddresses=fe;exports.validateRequestDepositorClaimerArtifactsResponse=re;exports.verifyServerIdentity=ce;exports.vpTokenRegistry=M;
2
- //# sourceMappingURL=primeVpAuth-Duds3vAO.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";var m=Object.defineProperty;var T=(n,t,e)=>t in n?m(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var l=(n,t,e)=>T(n,typeof t!="symbol"?t+"":t,e);const x=require("bitcoinjs-lib"),v=require("buffer"),w=require("./bitcoin-CHfKAhcI.cjs"),f=require("./peginState-BijNNT15.cjs"),c=require("./fundPeginTransaction-C8qsXxNV.cjs");class h extends Error{constructor(e){const r=e.length,a=r===1?"The UTXO for this peg-in is no longer available. It may have been spent in another transaction. Please create a new peg-in request with a different UTXO.":`${r} UTXOs for this peg-in are no longer available. They may have been spent. Please create a new peg-in request with different UTXOs.`;super(a);l(this,"missingUtxos");this.name="UtxoNotAvailableError",this.missingUtxos=e}}function p(n){const t=n.startsWith("0x")?n.slice(2):n;let e;try{e=x.Transaction.fromHex(t)}catch(r){throw new Error(`Failed to parse BTC transaction: ${r instanceof Error?r.message:String(r)}`)}return e.ins.map(r=>({txid:v.Buffer.from(r.hash).reverse().toString("hex"),vout:r.index}))}function g(n,t){const e=p(n);if(e.length===0)throw new Error("Transaction has no inputs");const r=new Set;for(const o of e){const s=`${o.txid.toLowerCase()}:${o.vout}`;if(r.has(s))throw new Error(`Transaction contains duplicate input ${o.txid}:${o.vout}. This would produce an invalid Bitcoin transaction.`);r.add(s)}const a=new Set(t.map(o=>`${o.txid.toLowerCase()}:${o.vout}`)),i=[];for(const o of e){const s=`${o.txid.toLowerCase()}:${o.vout}`;a.has(s)||i.push({txid:o.txid,vout:o.vout})}return{allAvailable:i.length===0,missingUtxos:i,totalInputs:e.length}}function E(n,t){const e=g(n,t);if(!e.allAvailable)throw new h(e.missingUtxos)}function d(n){try{return x.Transaction.fromHex(w.stripHexPrefix(n)).ins.map(e=>({txid:v.Buffer.from(e.hash).reverse().toString("hex"),vout:e.index}))}catch(t){return console.warn("[utxoReservation] Failed to parse transaction hex; skipping inputs",{category:"utxoReservation",error:t instanceof Error?t.message:String(t)}),[]}}function S(n,t){const e=n.txid.toLowerCase();return t.some(r=>r.txid.toLowerCase()===e&&r.vout===n.vout)}function b(n){const e=2*c.P2TR_INPUT_SIZE+c.MAX_NON_LEGACY_OUTPUT_SIZE+c.MAX_NON_LEGACY_OUTPUT_SIZE+c.TX_BUFFER_SIZE_OVERHEAD,r=Math.ceil(e*n*c.FEE_SAFETY_MARGIN);return BigInt(r)}function A(n){const t=[],{vaults:e=[],pendingPegins:r=[],utxoReservations:a=[]}=n,i=new Set(e.map(o=>{var s;return(s=o.id)==null?void 0:s.toLowerCase()}).filter(o=>o!==void 0));for(const o of r)o.id&&i.has(o.id.toLowerCase())||o.unsignedTxHex&&t.push(...d(o.unsignedTxHex));for(const o of e)o.status!==f.ContractStatus.PENDING&&o.status!==f.ContractStatus.VERIFIED||t.push(...d(o.unsignedPrePeginTx));for(const o of a)for(const s of o.outpoints)t.push({txid:s.txid,vout:s.vout});return t}function I(n){const{availableUtxos:t,reservedUtxoRefs:e,requiredAmount:r,feeRate:a}=n;if(!t||t.length===0)return[];if(e.length===0)return t;const i=t.filter(u=>!S(u,e));if(i.length===0)throw new Error("All available UTXOs are reserved by pending deposits. Wait for pending deposits to confirm or cancel them before starting a new deposit.");const o=b(a),s=r+o;if(i.reduce((u,U)=>u+BigInt(U.value),0n)<s)throw new Error("Insufficient unreserved UTXOs for this deposit amount. Wait for pending deposits to confirm or cancel them.");return i}exports.UtxoNotAvailableError=h;exports.assertUtxosAvailable=E;exports.collectReservedUtxoRefs=A;exports.extractInputsFromTransaction=p;exports.selectUtxosForDeposit=I;exports.validateUtxosAvailable=g;
2
- //# sourceMappingURL=reservation-Cwf2u4vu.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reservation-Cwf2u4vu.cjs","sources":["../src/tbv/core/utils/utxo/availability.ts","../src/tbv/core/utils/utxo/reservation.ts"],"sourcesContent":["/**\n * UTXO Availability Validation\n *\n * Validates that UTXOs referenced in a pre-pegin transaction are still unspent\n * BEFORE asking the user to sign. This prevents wasted signing effort when\n * UTXOs have already been spent by unrelated transactions.\n *\n * These functions are pure — they accept pre-fetched UTXOs and perform no I/O.\n * The vault service wrapper is responsible for fetching UTXOs from the mempool.\n */\n\nimport { Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport type { UtxoRef } from \"./reservation\";\n\n/**\n * Information about a missing/spent UTXO.\n */\nexport interface MissingUtxoInfo {\n /** Transaction ID of the missing UTXO */\n txid: string;\n /** Output index of the missing UTXO */\n vout: number;\n}\n\n/**\n * Result of UTXO validation.\n */\nexport interface UtxoValidationResult {\n /** Whether all UTXOs are still available */\n allAvailable: boolean;\n /** List of missing UTXOs (if any) */\n missingUtxos: MissingUtxoInfo[];\n /** Total number of inputs checked */\n totalInputs: number;\n}\n\n/**\n * Error thrown when UTXOs are not available.\n */\nexport class UtxoNotAvailableError extends Error {\n public readonly missingUtxos: MissingUtxoInfo[];\n\n constructor(missingUtxos: MissingUtxoInfo[]) {\n const count = missingUtxos.length;\n const message =\n count === 1\n ? \"The UTXO for this peg-in is no longer available. It may have been spent in another transaction. Please create a new peg-in request with a different UTXO.\"\n : `${count} UTXOs for this peg-in are no longer available. They may have been spent. Please create a new peg-in request with different UTXOs.`;\n\n super(message);\n this.name = \"UtxoNotAvailableError\";\n this.missingUtxos = missingUtxos;\n }\n}\n\n/**\n * Extract input references (txid:vout) from an unsigned transaction.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @returns Array of input references\n */\nexport function extractInputsFromTransaction(\n unsignedTxHex: string,\n): Array<{ txid: string; vout: number }> {\n const cleanHex = unsignedTxHex.startsWith(\"0x\")\n ? unsignedTxHex.slice(2)\n : unsignedTxHex;\n\n let tx: Transaction;\n try {\n tx = Transaction.fromHex(cleanHex);\n } catch (error) {\n throw new Error(\n `Failed to parse BTC transaction: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n return tx.ins.map((input) => ({\n // Bitcoin stores txid in reverse byte order\n txid: Buffer.from(input.hash).reverse().toString(\"hex\"),\n vout: input.index,\n }));\n}\n\n/**\n * Validate that all UTXOs in a transaction are still available.\n *\n * Pure function — accepts pre-fetched UTXOs instead of making network calls.\n * This should be called BEFORE signing to avoid wasting user effort\n * signing a transaction that will fail to broadcast.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @param availableUtxos - Pre-fetched list of available UTXOs for the depositor\n * @returns Validation result with missing UTXO details\n */\nexport function validateUtxosAvailable(\n unsignedTxHex: string,\n availableUtxos: UtxoRef[],\n): UtxoValidationResult {\n const inputs = extractInputsFromTransaction(unsignedTxHex);\n\n if (inputs.length === 0) {\n throw new Error(\"Transaction has no inputs\");\n }\n\n // Detect duplicate inputs (same txid:vout referenced more than once).\n // This would produce an invalid Bitcoin transaction.\n const inputKeys = new Set<string>();\n for (const input of inputs) {\n const key = `${input.txid.toLowerCase()}:${input.vout}`;\n if (inputKeys.has(key)) {\n throw new Error(\n `Transaction contains duplicate input ${input.txid}:${input.vout}. ` +\n `This would produce an invalid Bitcoin transaction.`,\n );\n }\n inputKeys.add(key);\n }\n\n // Create a set of available UTXOs for O(1) lookup (lowercase for consistency with reservation.ts)\n const availableSet = new Set(\n availableUtxos.map((utxo) => `${utxo.txid.toLowerCase()}:${utxo.vout}`),\n );\n\n // Check which inputs are missing\n const missingUtxos: MissingUtxoInfo[] = [];\n for (const input of inputs) {\n const key = `${input.txid.toLowerCase()}:${input.vout}`;\n if (!availableSet.has(key)) {\n missingUtxos.push({\n txid: input.txid,\n vout: input.vout,\n });\n }\n }\n\n return {\n allAvailable: missingUtxos.length === 0,\n missingUtxos,\n totalInputs: inputs.length,\n };\n}\n\n/**\n * Validate UTXOs and throw if any are not available.\n *\n * Pure convenience function that combines validation and error throwing.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @param availableUtxos - Pre-fetched list of available UTXOs for the depositor\n * @throws UtxoNotAvailableError if any UTXOs are not available\n * @throws Error if validation fails\n */\nexport function assertUtxosAvailable(\n unsignedTxHex: string,\n availableUtxos: UtxoRef[],\n): void {\n const result = validateUtxosAvailable(unsignedTxHex, availableUtxos);\n\n if (!result.allAvailable) {\n throw new UtxoNotAvailableError(result.missingUtxos);\n }\n}\n","/**\n * UTXO reservation utilities for vault deposits.\n *\n * Handles tracking which UTXOs are already in use by pending deposits\n * and selecting available UTXOs with smart fallback logic.\n */\n\nimport { Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\nimport { ContractStatus } from \"../../services/deposit/peginState\";\nimport {\n FEE_SAFETY_MARGIN,\n MAX_NON_LEGACY_OUTPUT_SIZE,\n P2TR_INPUT_SIZE,\n TX_BUFFER_SIZE_OVERHEAD,\n} from \"../fee/constants\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A txid:vout pair uniquely identifying a UTXO (outpoint). */\nexport interface UtxoRef {\n txid: string;\n vout: number;\n}\n\n/** Narrow structural type for pending pegin data. */\nexport interface PendingPeginLike {\n /**\n * Optional vault id. When present, used to skip pending pegins that are\n * already indexed on-chain so the canonical vault copy wins over a\n * tamperable off-chain entry.\n */\n id?: string;\n selectedUTXOs?: Array<{ txid: string; vout: number }>;\n unsignedTxHex?: string;\n}\n\n/** Narrow structural type for vault data. */\nexport interface VaultLike {\n /**\n * Optional vault id. When present, enables on-chain correlation with\n * pending pegins sharing the same id.\n */\n id?: string;\n status: number;\n unsignedPrePeginTx: string;\n}\n\nexport interface SelectUtxosForDepositParams<\n T extends { txid: string; vout: number; value: number },\n> {\n /** All available UTXOs from the wallet. */\n availableUtxos: T[];\n /** UTXOs that are reserved/in-flight and should be avoided if possible. */\n reservedUtxoRefs: UtxoRef[];\n /** Required deposit amount in satoshis (excluding fees). */\n requiredAmount: bigint;\n /** Fee rate in sat/vB. Used to estimate fee buffer for sufficiency check. */\n feeRate: number;\n}\n\n/** Narrow structural type for early UTXO reservations (pre-ETH-registration). */\nexport interface UtxoReservationLike {\n outpoints: ReadonlyArray<{ txid: string; vout: number }>;\n}\n\nexport interface CollectReservedUtxoRefsParams {\n vaults?: VaultLike[];\n pendingPegins?: PendingPeginLike[];\n utxoReservations?: UtxoReservationLike[];\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Parse a transaction hex and return the UTXO references of all inputs.\n *\n * Parse failures are logged and yield no refs. A malformed hex from an\n * untrusted source (e.g. off-chain storage) must not silently collapse the\n * reservation set — logging makes tampering visible in telemetry instead\n * of swallowing the error.\n */\nfunction extractInputUtxoRefs(txHex: string): UtxoRef[] {\n try {\n const tx = Transaction.fromHex(stripHexPrefix(txHex));\n return tx.ins.map((input) => {\n const txid = Buffer.from(input.hash).reverse().toString(\"hex\");\n return { txid, vout: input.index };\n });\n } catch (error) {\n console.warn(\n \"[utxoReservation] Failed to parse transaction hex; skipping inputs\",\n {\n category: \"utxoReservation\",\n error: error instanceof Error ? error.message : String(error),\n },\n );\n return [];\n }\n}\n\n/** Check if a UTXO matches any reserved ref (case-insensitive txid comparison). */\nfunction isUtxoReserved(\n utxo: { txid: string; vout: number },\n reservedRefs: UtxoRef[],\n): boolean {\n const txidLower = utxo.txid.toLowerCase();\n return reservedRefs.some(\n (ref) => ref.txid.toLowerCase() === txidLower && ref.vout === utxo.vout,\n );\n}\n\n/**\n * Estimate minimum fee buffer for UTXO pre-selection.\n *\n * WARNING: This is a ROUGH ESTIMATE used only to check if unreserved UTXOs\n * are likely sufficient BEFORE the actual signing flow begins. The actual\n * fee calculation happens in the SDK's `selectUtxosForPegin` during signing.\n *\n * Assumptions:\n * - 2 inputs (conservative estimate for most deposits)\n * - 1 vault output (P2TR, 43 vBytes)\n * - 1 change output (P2TR, 43 vBytes)\n * - Transaction overhead (11 vBytes)\n * - 10% safety margin\n */\nfunction estimateMinimumFeeBuffer(feeRate: number): bigint {\n const ASSUMED_INPUTS = 2;\n\n const estimatedTxSize =\n ASSUMED_INPUTS * P2TR_INPUT_SIZE +\n MAX_NON_LEGACY_OUTPUT_SIZE + // vault output\n MAX_NON_LEGACY_OUTPUT_SIZE + // change output\n TX_BUFFER_SIZE_OVERHEAD;\n\n const estimatedFee = Math.ceil(estimatedTxSize * feeRate * FEE_SAFETY_MARGIN);\n return BigInt(estimatedFee);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Collect UTXO refs from in-flight deposits (PENDING/VERIFIED vaults and\n * pending pegins).\n *\n * On-chain vault data is canonical: for any pending pegin whose `id` matches\n * an indexed on-chain vault, the pending-pegin copy is ignored entirely —\n * the `vaults` branch below extracts refs from the indexer-supplied\n * `unsignedPrePeginTx` so tampered off-chain data cannot poison the\n * reservation set once the vault is indexed.\n *\n * For pegins not yet indexed, refs are derived from the stored\n * `unsignedTxHex` only. The `selectedUTXOs` sidecar is NOT used for\n * reservation: if it disagreed with the transaction's inputs (e.g. because\n * the off-chain source was tampered), trusting it would poison the reserved\n * set. The transaction hex must be validated at the source boundary before\n * being handed to this function; parsing and using its inputs is the single\n * source of truth here.\n */\nexport function collectReservedUtxoRefs(\n params: CollectReservedUtxoRefsParams,\n): UtxoRef[] {\n const reserved: UtxoRef[] = [];\n const {\n vaults = [],\n pendingPegins = [],\n utxoReservations = [],\n } = params;\n\n const onChainVaultIds = new Set(\n vaults\n .map((v) => v.id?.toLowerCase())\n .filter((id): id is string => id !== undefined),\n );\n\n for (const pending of pendingPegins) {\n if (pending.id && onChainVaultIds.has(pending.id.toLowerCase())) {\n continue;\n }\n if (pending.unsignedTxHex) {\n reserved.push(...extractInputUtxoRefs(pending.unsignedTxHex));\n }\n }\n\n for (const vault of vaults) {\n if (\n vault.status !== ContractStatus.PENDING &&\n vault.status !== ContractStatus.VERIFIED\n ) {\n continue;\n }\n reserved.push(...extractInputUtxoRefs(vault.unsignedPrePeginTx));\n }\n\n // Early reservations written before ETH registration to prevent cross-tab\n // UTXO conflicts. These are cleaned up when the deposit completes or fails.\n for (const reservation of utxoReservations) {\n for (const op of reservation.outpoints) {\n reserved.push({ txid: op.txid, vout: op.vout });\n }\n }\n\n return reserved;\n}\n\n/**\n * Select UTXOs for a deposit, filtering out reserved ones.\n *\n * Logic:\n * 1. Filter out reserved UTXOs from the available pool\n * 2. If unreserved UTXOs are sufficient for the required amount + estimated fee, return them\n * 3. Otherwise, throw — never silently reuse reserved UTXOs, as this risks double-spend\n * failures that strand registered-but-unbroadcastable vaults\n *\n * @param params - Selection parameters\n * @returns Array of unreserved UTXOs to use for the deposit\n * @throws When all UTXOs are reserved or unreserved UTXOs are insufficient\n */\nexport function selectUtxosForDeposit<\n T extends { txid: string; vout: number; value: number },\n>(params: SelectUtxosForDepositParams<T>): T[] {\n const { availableUtxos, reservedUtxoRefs, requiredAmount, feeRate } = params;\n\n // Edge case: no UTXOs available\n if (!availableUtxos || availableUtxos.length === 0) {\n return [];\n }\n\n // Edge case: no reservations, return all\n if (reservedUtxoRefs.length === 0) {\n return availableUtxos;\n }\n\n // Filter out reserved UTXOs\n const unreserved = availableUtxos.filter(\n (utxo) => !isUtxoReserved(utxo, reservedUtxoRefs),\n );\n\n if (unreserved.length === 0) {\n throw new Error(\n \"All available UTXOs are reserved by pending deposits. \" +\n \"Wait for pending deposits to confirm or cancel them before starting a new deposit.\",\n );\n }\n\n const feeBuffer = estimateMinimumFeeBuffer(feeRate);\n const totalRequired = requiredAmount + feeBuffer;\n const unreservedTotal = unreserved.reduce(\n (sum, u) => sum + BigInt(u.value),\n 0n,\n );\n if (unreservedTotal < totalRequired) {\n throw new Error(\n \"Insufficient unreserved UTXOs for this deposit amount. \" +\n \"Wait for pending deposits to confirm or cancel them.\",\n );\n }\n\n return unreserved;\n}\n"],"names":["UtxoNotAvailableError","missingUtxos","count","message","__publicField","extractInputsFromTransaction","unsignedTxHex","cleanHex","tx","Transaction","error","input","Buffer","validateUtxosAvailable","availableUtxos","inputs","inputKeys","key","availableSet","utxo","assertUtxosAvailable","result","extractInputUtxoRefs","txHex","stripHexPrefix","isUtxoReserved","reservedRefs","txidLower","ref","estimateMinimumFeeBuffer","feeRate","estimatedTxSize","P2TR_INPUT_SIZE","MAX_NON_LEGACY_OUTPUT_SIZE","TX_BUFFER_SIZE_OVERHEAD","estimatedFee","FEE_SAFETY_MARGIN","collectReservedUtxoRefs","params","reserved","vaults","pendingPegins","utxoReservations","onChainVaultIds","v","_a","id","pending","vault","ContractStatus","reservation","op","selectUtxosForDeposit","reservedUtxoRefs","requiredAmount","unreserved","feeBuffer","totalRequired","sum","u"],"mappings":"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"}
@@ -1,143 +0,0 @@
1
- var v = Object.defineProperty;
2
- var m = (n, t, e) => t in n ? v(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
- var u = (n, t, e) => m(n, typeof t != "symbol" ? t + "" : t, e);
4
- import { Transaction as p } from "bitcoinjs-lib";
5
- import { Buffer as h } from "buffer";
6
- import { s as g } from "./bitcoin-B5aNKtsk.js";
7
- import { C as f } from "./peginState-CBAlxgXk.js";
8
- import { F as w, P as U, M as l, T } from "./fundPeginTransaction-C11tYf6I.js";
9
- class E extends Error {
10
- constructor(e) {
11
- const r = e.length, a = r === 1 ? "The UTXO for this peg-in is no longer available. It may have been spent in another transaction. Please create a new peg-in request with a different UTXO." : `${r} UTXOs for this peg-in are no longer available. They may have been spent. Please create a new peg-in request with different UTXOs.`;
12
- super(a);
13
- u(this, "missingUtxos");
14
- this.name = "UtxoNotAvailableError", this.missingUtxos = e;
15
- }
16
- }
17
- function S(n) {
18
- const t = n.startsWith("0x") ? n.slice(2) : n;
19
- let e;
20
- try {
21
- e = p.fromHex(t);
22
- } catch (r) {
23
- throw new Error(
24
- `Failed to parse BTC transaction: ${r instanceof Error ? r.message : String(r)}`
25
- );
26
- }
27
- return e.ins.map((r) => ({
28
- // Bitcoin stores txid in reverse byte order
29
- txid: h.from(r.hash).reverse().toString("hex"),
30
- vout: r.index
31
- }));
32
- }
33
- function I(n, t) {
34
- const e = S(n);
35
- if (e.length === 0)
36
- throw new Error("Transaction has no inputs");
37
- const r = /* @__PURE__ */ new Set();
38
- for (const o of e) {
39
- const s = `${o.txid.toLowerCase()}:${o.vout}`;
40
- if (r.has(s))
41
- throw new Error(
42
- `Transaction contains duplicate input ${o.txid}:${o.vout}. This would produce an invalid Bitcoin transaction.`
43
- );
44
- r.add(s);
45
- }
46
- const a = new Set(
47
- t.map((o) => `${o.txid.toLowerCase()}:${o.vout}`)
48
- ), i = [];
49
- for (const o of e) {
50
- const s = `${o.txid.toLowerCase()}:${o.vout}`;
51
- a.has(s) || i.push({
52
- txid: o.txid,
53
- vout: o.vout
54
- });
55
- }
56
- return {
57
- allAvailable: i.length === 0,
58
- missingUtxos: i,
59
- totalInputs: e.length
60
- };
61
- }
62
- function $(n, t) {
63
- const e = I(n, t);
64
- if (!e.allAvailable)
65
- throw new E(e.missingUtxos);
66
- }
67
- function d(n) {
68
- try {
69
- return p.fromHex(g(n)).ins.map((e) => ({ txid: h.from(e.hash).reverse().toString("hex"), vout: e.index }));
70
- } catch (t) {
71
- return console.warn(
72
- "[utxoReservation] Failed to parse transaction hex; skipping inputs",
73
- {
74
- category: "utxoReservation",
75
- error: t instanceof Error ? t.message : String(t)
76
- }
77
- ), [];
78
- }
79
- }
80
- function b(n, t) {
81
- const e = n.txid.toLowerCase();
82
- return t.some(
83
- (r) => r.txid.toLowerCase() === e && r.vout === n.vout
84
- );
85
- }
86
- function A(n) {
87
- const e = 2 * U + l + // vault output
88
- l + // change output
89
- T, r = Math.ceil(e * n * w);
90
- return BigInt(r);
91
- }
92
- function L(n) {
93
- const t = [], {
94
- vaults: e = [],
95
- pendingPegins: r = [],
96
- utxoReservations: a = []
97
- } = n, i = new Set(
98
- e.map((o) => {
99
- var s;
100
- return (s = o.id) == null ? void 0 : s.toLowerCase();
101
- }).filter((o) => o !== void 0)
102
- );
103
- for (const o of r)
104
- o.id && i.has(o.id.toLowerCase()) || o.unsignedTxHex && t.push(...d(o.unsignedTxHex));
105
- for (const o of e)
106
- o.status !== f.PENDING && o.status !== f.VERIFIED || t.push(...d(o.unsignedPrePeginTx));
107
- for (const o of a)
108
- for (const s of o.outpoints)
109
- t.push({ txid: s.txid, vout: s.vout });
110
- return t;
111
- }
112
- function O(n) {
113
- const { availableUtxos: t, reservedUtxoRefs: e, requiredAmount: r, feeRate: a } = n;
114
- if (!t || t.length === 0)
115
- return [];
116
- if (e.length === 0)
117
- return t;
118
- const i = t.filter(
119
- (c) => !b(c, e)
120
- );
121
- if (i.length === 0)
122
- throw new Error(
123
- "All available UTXOs are reserved by pending deposits. Wait for pending deposits to confirm or cancel them before starting a new deposit."
124
- );
125
- const o = A(a), s = r + o;
126
- if (i.reduce(
127
- (c, x) => c + BigInt(x.value),
128
- 0n
129
- ) < s)
130
- throw new Error(
131
- "Insufficient unreserved UTXOs for this deposit amount. Wait for pending deposits to confirm or cancel them."
132
- );
133
- return i;
134
- }
135
- export {
136
- E as U,
137
- $ as a,
138
- L as c,
139
- S as e,
140
- O as s,
141
- I as v
142
- };
143
- //# sourceMappingURL=reservation-DNOGLBt4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reservation-DNOGLBt4.js","sources":["../src/tbv/core/utils/utxo/availability.ts","../src/tbv/core/utils/utxo/reservation.ts"],"sourcesContent":["/**\n * UTXO Availability Validation\n *\n * Validates that UTXOs referenced in a pre-pegin transaction are still unspent\n * BEFORE asking the user to sign. This prevents wasted signing effort when\n * UTXOs have already been spent by unrelated transactions.\n *\n * These functions are pure — they accept pre-fetched UTXOs and perform no I/O.\n * The vault service wrapper is responsible for fetching UTXOs from the mempool.\n */\n\nimport { Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport type { UtxoRef } from \"./reservation\";\n\n/**\n * Information about a missing/spent UTXO.\n */\nexport interface MissingUtxoInfo {\n /** Transaction ID of the missing UTXO */\n txid: string;\n /** Output index of the missing UTXO */\n vout: number;\n}\n\n/**\n * Result of UTXO validation.\n */\nexport interface UtxoValidationResult {\n /** Whether all UTXOs are still available */\n allAvailable: boolean;\n /** List of missing UTXOs (if any) */\n missingUtxos: MissingUtxoInfo[];\n /** Total number of inputs checked */\n totalInputs: number;\n}\n\n/**\n * Error thrown when UTXOs are not available.\n */\nexport class UtxoNotAvailableError extends Error {\n public readonly missingUtxos: MissingUtxoInfo[];\n\n constructor(missingUtxos: MissingUtxoInfo[]) {\n const count = missingUtxos.length;\n const message =\n count === 1\n ? \"The UTXO for this peg-in is no longer available. It may have been spent in another transaction. Please create a new peg-in request with a different UTXO.\"\n : `${count} UTXOs for this peg-in are no longer available. They may have been spent. Please create a new peg-in request with different UTXOs.`;\n\n super(message);\n this.name = \"UtxoNotAvailableError\";\n this.missingUtxos = missingUtxos;\n }\n}\n\n/**\n * Extract input references (txid:vout) from an unsigned transaction.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @returns Array of input references\n */\nexport function extractInputsFromTransaction(\n unsignedTxHex: string,\n): Array<{ txid: string; vout: number }> {\n const cleanHex = unsignedTxHex.startsWith(\"0x\")\n ? unsignedTxHex.slice(2)\n : unsignedTxHex;\n\n let tx: Transaction;\n try {\n tx = Transaction.fromHex(cleanHex);\n } catch (error) {\n throw new Error(\n `Failed to parse BTC transaction: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n return tx.ins.map((input) => ({\n // Bitcoin stores txid in reverse byte order\n txid: Buffer.from(input.hash).reverse().toString(\"hex\"),\n vout: input.index,\n }));\n}\n\n/**\n * Validate that all UTXOs in a transaction are still available.\n *\n * Pure function — accepts pre-fetched UTXOs instead of making network calls.\n * This should be called BEFORE signing to avoid wasting user effort\n * signing a transaction that will fail to broadcast.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @param availableUtxos - Pre-fetched list of available UTXOs for the depositor\n * @returns Validation result with missing UTXO details\n */\nexport function validateUtxosAvailable(\n unsignedTxHex: string,\n availableUtxos: UtxoRef[],\n): UtxoValidationResult {\n const inputs = extractInputsFromTransaction(unsignedTxHex);\n\n if (inputs.length === 0) {\n throw new Error(\"Transaction has no inputs\");\n }\n\n // Detect duplicate inputs (same txid:vout referenced more than once).\n // This would produce an invalid Bitcoin transaction.\n const inputKeys = new Set<string>();\n for (const input of inputs) {\n const key = `${input.txid.toLowerCase()}:${input.vout}`;\n if (inputKeys.has(key)) {\n throw new Error(\n `Transaction contains duplicate input ${input.txid}:${input.vout}. ` +\n `This would produce an invalid Bitcoin transaction.`,\n );\n }\n inputKeys.add(key);\n }\n\n // Create a set of available UTXOs for O(1) lookup (lowercase for consistency with reservation.ts)\n const availableSet = new Set(\n availableUtxos.map((utxo) => `${utxo.txid.toLowerCase()}:${utxo.vout}`),\n );\n\n // Check which inputs are missing\n const missingUtxos: MissingUtxoInfo[] = [];\n for (const input of inputs) {\n const key = `${input.txid.toLowerCase()}:${input.vout}`;\n if (!availableSet.has(key)) {\n missingUtxos.push({\n txid: input.txid,\n vout: input.vout,\n });\n }\n }\n\n return {\n allAvailable: missingUtxos.length === 0,\n missingUtxos,\n totalInputs: inputs.length,\n };\n}\n\n/**\n * Validate UTXOs and throw if any are not available.\n *\n * Pure convenience function that combines validation and error throwing.\n *\n * @param unsignedTxHex - Unsigned transaction hex\n * @param availableUtxos - Pre-fetched list of available UTXOs for the depositor\n * @throws UtxoNotAvailableError if any UTXOs are not available\n * @throws Error if validation fails\n */\nexport function assertUtxosAvailable(\n unsignedTxHex: string,\n availableUtxos: UtxoRef[],\n): void {\n const result = validateUtxosAvailable(unsignedTxHex, availableUtxos);\n\n if (!result.allAvailable) {\n throw new UtxoNotAvailableError(result.missingUtxos);\n }\n}\n","/**\n * UTXO reservation utilities for vault deposits.\n *\n * Handles tracking which UTXOs are already in use by pending deposits\n * and selecting available UTXOs with smart fallback logic.\n */\n\nimport { Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\nimport { ContractStatus } from \"../../services/deposit/peginState\";\nimport {\n FEE_SAFETY_MARGIN,\n MAX_NON_LEGACY_OUTPUT_SIZE,\n P2TR_INPUT_SIZE,\n TX_BUFFER_SIZE_OVERHEAD,\n} from \"../fee/constants\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A txid:vout pair uniquely identifying a UTXO (outpoint). */\nexport interface UtxoRef {\n txid: string;\n vout: number;\n}\n\n/** Narrow structural type for pending pegin data. */\nexport interface PendingPeginLike {\n /**\n * Optional vault id. When present, used to skip pending pegins that are\n * already indexed on-chain so the canonical vault copy wins over a\n * tamperable off-chain entry.\n */\n id?: string;\n selectedUTXOs?: Array<{ txid: string; vout: number }>;\n unsignedTxHex?: string;\n}\n\n/** Narrow structural type for vault data. */\nexport interface VaultLike {\n /**\n * Optional vault id. When present, enables on-chain correlation with\n * pending pegins sharing the same id.\n */\n id?: string;\n status: number;\n unsignedPrePeginTx: string;\n}\n\nexport interface SelectUtxosForDepositParams<\n T extends { txid: string; vout: number; value: number },\n> {\n /** All available UTXOs from the wallet. */\n availableUtxos: T[];\n /** UTXOs that are reserved/in-flight and should be avoided if possible. */\n reservedUtxoRefs: UtxoRef[];\n /** Required deposit amount in satoshis (excluding fees). */\n requiredAmount: bigint;\n /** Fee rate in sat/vB. Used to estimate fee buffer for sufficiency check. */\n feeRate: number;\n}\n\n/** Narrow structural type for early UTXO reservations (pre-ETH-registration). */\nexport interface UtxoReservationLike {\n outpoints: ReadonlyArray<{ txid: string; vout: number }>;\n}\n\nexport interface CollectReservedUtxoRefsParams {\n vaults?: VaultLike[];\n pendingPegins?: PendingPeginLike[];\n utxoReservations?: UtxoReservationLike[];\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Parse a transaction hex and return the UTXO references of all inputs.\n *\n * Parse failures are logged and yield no refs. A malformed hex from an\n * untrusted source (e.g. off-chain storage) must not silently collapse the\n * reservation set — logging makes tampering visible in telemetry instead\n * of swallowing the error.\n */\nfunction extractInputUtxoRefs(txHex: string): UtxoRef[] {\n try {\n const tx = Transaction.fromHex(stripHexPrefix(txHex));\n return tx.ins.map((input) => {\n const txid = Buffer.from(input.hash).reverse().toString(\"hex\");\n return { txid, vout: input.index };\n });\n } catch (error) {\n console.warn(\n \"[utxoReservation] Failed to parse transaction hex; skipping inputs\",\n {\n category: \"utxoReservation\",\n error: error instanceof Error ? error.message : String(error),\n },\n );\n return [];\n }\n}\n\n/** Check if a UTXO matches any reserved ref (case-insensitive txid comparison). */\nfunction isUtxoReserved(\n utxo: { txid: string; vout: number },\n reservedRefs: UtxoRef[],\n): boolean {\n const txidLower = utxo.txid.toLowerCase();\n return reservedRefs.some(\n (ref) => ref.txid.toLowerCase() === txidLower && ref.vout === utxo.vout,\n );\n}\n\n/**\n * Estimate minimum fee buffer for UTXO pre-selection.\n *\n * WARNING: This is a ROUGH ESTIMATE used only to check if unreserved UTXOs\n * are likely sufficient BEFORE the actual signing flow begins. The actual\n * fee calculation happens in the SDK's `selectUtxosForPegin` during signing.\n *\n * Assumptions:\n * - 2 inputs (conservative estimate for most deposits)\n * - 1 vault output (P2TR, 43 vBytes)\n * - 1 change output (P2TR, 43 vBytes)\n * - Transaction overhead (11 vBytes)\n * - 10% safety margin\n */\nfunction estimateMinimumFeeBuffer(feeRate: number): bigint {\n const ASSUMED_INPUTS = 2;\n\n const estimatedTxSize =\n ASSUMED_INPUTS * P2TR_INPUT_SIZE +\n MAX_NON_LEGACY_OUTPUT_SIZE + // vault output\n MAX_NON_LEGACY_OUTPUT_SIZE + // change output\n TX_BUFFER_SIZE_OVERHEAD;\n\n const estimatedFee = Math.ceil(estimatedTxSize * feeRate * FEE_SAFETY_MARGIN);\n return BigInt(estimatedFee);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Collect UTXO refs from in-flight deposits (PENDING/VERIFIED vaults and\n * pending pegins).\n *\n * On-chain vault data is canonical: for any pending pegin whose `id` matches\n * an indexed on-chain vault, the pending-pegin copy is ignored entirely —\n * the `vaults` branch below extracts refs from the indexer-supplied\n * `unsignedPrePeginTx` so tampered off-chain data cannot poison the\n * reservation set once the vault is indexed.\n *\n * For pegins not yet indexed, refs are derived from the stored\n * `unsignedTxHex` only. The `selectedUTXOs` sidecar is NOT used for\n * reservation: if it disagreed with the transaction's inputs (e.g. because\n * the off-chain source was tampered), trusting it would poison the reserved\n * set. The transaction hex must be validated at the source boundary before\n * being handed to this function; parsing and using its inputs is the single\n * source of truth here.\n */\nexport function collectReservedUtxoRefs(\n params: CollectReservedUtxoRefsParams,\n): UtxoRef[] {\n const reserved: UtxoRef[] = [];\n const {\n vaults = [],\n pendingPegins = [],\n utxoReservations = [],\n } = params;\n\n const onChainVaultIds = new Set(\n vaults\n .map((v) => v.id?.toLowerCase())\n .filter((id): id is string => id !== undefined),\n );\n\n for (const pending of pendingPegins) {\n if (pending.id && onChainVaultIds.has(pending.id.toLowerCase())) {\n continue;\n }\n if (pending.unsignedTxHex) {\n reserved.push(...extractInputUtxoRefs(pending.unsignedTxHex));\n }\n }\n\n for (const vault of vaults) {\n if (\n vault.status !== ContractStatus.PENDING &&\n vault.status !== ContractStatus.VERIFIED\n ) {\n continue;\n }\n reserved.push(...extractInputUtxoRefs(vault.unsignedPrePeginTx));\n }\n\n // Early reservations written before ETH registration to prevent cross-tab\n // UTXO conflicts. These are cleaned up when the deposit completes or fails.\n for (const reservation of utxoReservations) {\n for (const op of reservation.outpoints) {\n reserved.push({ txid: op.txid, vout: op.vout });\n }\n }\n\n return reserved;\n}\n\n/**\n * Select UTXOs for a deposit, filtering out reserved ones.\n *\n * Logic:\n * 1. Filter out reserved UTXOs from the available pool\n * 2. If unreserved UTXOs are sufficient for the required amount + estimated fee, return them\n * 3. Otherwise, throw — never silently reuse reserved UTXOs, as this risks double-spend\n * failures that strand registered-but-unbroadcastable vaults\n *\n * @param params - Selection parameters\n * @returns Array of unreserved UTXOs to use for the deposit\n * @throws When all UTXOs are reserved or unreserved UTXOs are insufficient\n */\nexport function selectUtxosForDeposit<\n T extends { txid: string; vout: number; value: number },\n>(params: SelectUtxosForDepositParams<T>): T[] {\n const { availableUtxos, reservedUtxoRefs, requiredAmount, feeRate } = params;\n\n // Edge case: no UTXOs available\n if (!availableUtxos || availableUtxos.length === 0) {\n return [];\n }\n\n // Edge case: no reservations, return all\n if (reservedUtxoRefs.length === 0) {\n return availableUtxos;\n }\n\n // Filter out reserved UTXOs\n const unreserved = availableUtxos.filter(\n (utxo) => !isUtxoReserved(utxo, reservedUtxoRefs),\n );\n\n if (unreserved.length === 0) {\n throw new Error(\n \"All available UTXOs are reserved by pending deposits. \" +\n \"Wait for pending deposits to confirm or cancel them before starting a new deposit.\",\n );\n }\n\n const feeBuffer = estimateMinimumFeeBuffer(feeRate);\n const totalRequired = requiredAmount + feeBuffer;\n const unreservedTotal = unreserved.reduce(\n (sum, u) => sum + BigInt(u.value),\n 0n,\n );\n if (unreservedTotal < totalRequired) {\n throw new Error(\n \"Insufficient unreserved UTXOs for this deposit amount. \" +\n \"Wait for pending deposits to confirm or cancel them.\",\n );\n }\n\n return unreserved;\n}\n"],"names":["UtxoNotAvailableError","missingUtxos","count","message","__publicField","extractInputsFromTransaction","unsignedTxHex","cleanHex","tx","Transaction","error","input","Buffer","validateUtxosAvailable","availableUtxos","inputs","inputKeys","key","availableSet","utxo","assertUtxosAvailable","result","extractInputUtxoRefs","txHex","stripHexPrefix","isUtxoReserved","reservedRefs","txidLower","ref","estimateMinimumFeeBuffer","feeRate","estimatedTxSize","P2TR_INPUT_SIZE","MAX_NON_LEGACY_OUTPUT_SIZE","TX_BUFFER_SIZE_OVERHEAD","estimatedFee","FEE_SAFETY_MARGIN","collectReservedUtxoRefs","params","reserved","vaults","pendingPegins","utxoReservations","onChainVaultIds","v","_a","id","pending","vault","ContractStatus","reservation","op","selectUtxosForDeposit","reservedUtxoRefs","requiredAmount","unreserved","feeBuffer","totalRequired","sum","u"],"mappings":"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"}