@payai/x402-evm 2.4.1 → 2.4.3

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 (143) hide show
  1. package/dist/cjs/batch-settlement/client/file-storage.d.ts +47 -0
  2. package/dist/cjs/batch-settlement/client/file-storage.js +116 -0
  3. package/dist/cjs/batch-settlement/client/file-storage.js.map +1 -0
  4. package/dist/cjs/batch-settlement/client/index.d.ts +111 -0
  5. package/dist/cjs/batch-settlement/client/index.js +1565 -0
  6. package/dist/cjs/batch-settlement/client/index.js.map +1 -0
  7. package/dist/cjs/batch-settlement/facilitator/index.d.ts +71 -0
  8. package/dist/cjs/batch-settlement/facilitator/index.js +2032 -0
  9. package/dist/cjs/batch-settlement/facilitator/index.js.map +1 -0
  10. package/dist/cjs/batch-settlement/server/file-storage.d.ts +53 -0
  11. package/dist/cjs/batch-settlement/server/file-storage.js +181 -0
  12. package/dist/cjs/batch-settlement/server/file-storage.js.map +1 -0
  13. package/dist/cjs/batch-settlement/server/index.d.ts +491 -0
  14. package/dist/cjs/batch-settlement/server/index.js +1960 -0
  15. package/dist/cjs/batch-settlement/server/index.js.map +1 -0
  16. package/dist/cjs/batch-settlement/server/redis-storage.d.ts +87 -0
  17. package/dist/cjs/batch-settlement/server/redis-storage.js +181 -0
  18. package/dist/cjs/batch-settlement/server/redis-storage.js.map +1 -0
  19. package/dist/cjs/exact/client/index.d.ts +6 -4
  20. package/dist/cjs/exact/client/index.js +7 -5
  21. package/dist/cjs/exact/client/index.js.map +1 -1
  22. package/dist/cjs/exact/facilitator/index.d.ts +16 -9
  23. package/dist/cjs/exact/facilitator/index.js +35 -7
  24. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  25. package/dist/cjs/exact/server/index.js +40 -1
  26. package/dist/cjs/exact/server/index.js.map +1 -1
  27. package/dist/cjs/exact/v1/client/index.d.ts +2 -1
  28. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  29. package/dist/cjs/exact/v1/facilitator/index.d.ts +11 -5
  30. package/dist/cjs/exact/v1/facilitator/index.js +16 -2
  31. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  32. package/dist/cjs/index.d.ts +113 -7
  33. package/dist/cjs/index.js +1353 -5
  34. package/dist/cjs/index.js.map +1 -1
  35. package/dist/{esm/permit2-CyZxwngN.d.mts → cjs/permit2-DhJRUcgY.d.ts} +1 -13
  36. package/dist/cjs/rpc-DULZzRne.d.ts +13 -0
  37. package/dist/cjs/scheme-CvkPJXBD.d.ts +307 -0
  38. package/dist/{esm/scheme-DCR7hsa3.d.mts → cjs/scheme-DTQFE9xp.d.ts} +2 -2
  39. package/dist/{esm/signer-D912R4mq.d.mts → cjs/signer-tYS6Y46X.d.ts} +3 -0
  40. package/dist/cjs/storage-6W5MO46W.d.ts +50 -0
  41. package/dist/cjs/storage-Bl6aD0Xg.d.ts +81 -0
  42. package/dist/cjs/types-CF8P2-NM.d.ts +180 -0
  43. package/dist/cjs/upto/client/index.d.ts +5 -3
  44. package/dist/cjs/upto/client/index.js +7 -5
  45. package/dist/cjs/upto/client/index.js.map +1 -1
  46. package/dist/cjs/upto/facilitator/index.d.ts +2 -1
  47. package/dist/cjs/upto/facilitator/index.js +2 -1
  48. package/dist/cjs/upto/facilitator/index.js.map +1 -1
  49. package/dist/cjs/upto/server/index.js +40 -1
  50. package/dist/cjs/upto/server/index.js.map +1 -1
  51. package/dist/cjs/v1/index.d.ts +2 -1
  52. package/dist/cjs/v1/index.js.map +1 -1
  53. package/dist/esm/batch-settlement/client/file-storage.d.mts +47 -0
  54. package/dist/esm/batch-settlement/client/file-storage.mjs +63 -0
  55. package/dist/esm/batch-settlement/client/file-storage.mjs.map +1 -0
  56. package/dist/esm/batch-settlement/client/index.d.mts +111 -0
  57. package/dist/esm/batch-settlement/client/index.mjs +59 -0
  58. package/dist/esm/batch-settlement/client/index.mjs.map +1 -0
  59. package/dist/esm/batch-settlement/facilitator/index.d.mts +71 -0
  60. package/dist/esm/batch-settlement/facilitator/index.mjs +1235 -0
  61. package/dist/esm/batch-settlement/facilitator/index.mjs.map +1 -0
  62. package/dist/esm/batch-settlement/server/file-storage.d.mts +53 -0
  63. package/dist/esm/batch-settlement/server/file-storage.mjs +128 -0
  64. package/dist/esm/batch-settlement/server/file-storage.mjs.map +1 -0
  65. package/dist/esm/batch-settlement/server/index.d.mts +491 -0
  66. package/dist/esm/batch-settlement/server/index.mjs +1645 -0
  67. package/dist/esm/batch-settlement/server/index.mjs.map +1 -0
  68. package/dist/esm/batch-settlement/server/redis-storage.d.mts +87 -0
  69. package/dist/esm/batch-settlement/server/redis-storage.mjs +156 -0
  70. package/dist/esm/batch-settlement/server/redis-storage.mjs.map +1 -0
  71. package/dist/esm/chunk-2EUQTNJO.mjs +38 -0
  72. package/dist/esm/chunk-2EUQTNJO.mjs.map +1 -0
  73. package/dist/esm/chunk-53USC5VE.mjs +47 -0
  74. package/dist/esm/chunk-53USC5VE.mjs.map +1 -0
  75. package/dist/esm/{chunk-GJ57SZGI.mjs → chunk-6WQOGWBE.mjs} +7 -5
  76. package/dist/esm/{chunk-GJ57SZGI.mjs.map → chunk-6WQOGWBE.mjs.map} +1 -1
  77. package/dist/esm/{chunk-F3OOHBAW.mjs → chunk-BTYNCDNS.mjs} +42 -2
  78. package/dist/esm/{chunk-F3OOHBAW.mjs.map → chunk-BTYNCDNS.mjs.map} +1 -1
  79. package/dist/esm/{chunk-ERK2ZPOY.mjs → chunk-CSQS7ZON.mjs} +27 -7
  80. package/dist/esm/chunk-CSQS7ZON.mjs.map +1 -0
  81. package/dist/esm/chunk-GD4MKCN7.mjs +57 -0
  82. package/dist/esm/chunk-GD4MKCN7.mjs.map +1 -0
  83. package/dist/esm/chunk-HYABYUBD.mjs +432 -0
  84. package/dist/esm/chunk-HYABYUBD.mjs.map +1 -0
  85. package/dist/esm/chunk-IN5YIT5C.mjs +159 -0
  86. package/dist/esm/chunk-IN5YIT5C.mjs.map +1 -0
  87. package/dist/esm/{chunk-JII456TS.mjs → chunk-JK7SLLF7.mjs} +1 -1
  88. package/dist/esm/chunk-JK7SLLF7.mjs.map +1 -0
  89. package/dist/esm/{chunk-C4ZQMS77.mjs → chunk-MACPBXCT.mjs} +2 -216
  90. package/dist/esm/chunk-MACPBXCT.mjs.map +1 -0
  91. package/dist/esm/chunk-NKYVYGRA.mjs +911 -0
  92. package/dist/esm/chunk-NKYVYGRA.mjs.map +1 -0
  93. package/dist/esm/{chunk-FQJR4RCF.mjs → chunk-R7I3RZFF.mjs} +10 -6
  94. package/dist/esm/{chunk-FQJR4RCF.mjs.map → chunk-R7I3RZFF.mjs.map} +1 -1
  95. package/dist/esm/{chunk-CRT6YNY5.mjs → chunk-RWLVVO3B.mjs} +21 -61
  96. package/dist/esm/chunk-RWLVVO3B.mjs.map +1 -0
  97. package/dist/esm/chunk-TGFAVNUD.mjs +111 -0
  98. package/dist/esm/chunk-TGFAVNUD.mjs.map +1 -0
  99. package/dist/esm/chunk-TW7Z65AO.mjs +34 -0
  100. package/dist/esm/chunk-TW7Z65AO.mjs.map +1 -0
  101. package/dist/esm/chunk-U4HCGTLU.mjs +35 -0
  102. package/dist/esm/chunk-U4HCGTLU.mjs.map +1 -0
  103. package/dist/esm/chunk-VS3RYAYE.mjs +80 -0
  104. package/dist/esm/chunk-VS3RYAYE.mjs.map +1 -0
  105. package/dist/esm/chunk-W6ON4LG2.mjs +39 -0
  106. package/dist/esm/chunk-W6ON4LG2.mjs.map +1 -0
  107. package/dist/esm/{chunk-WKBC5YMI.mjs → chunk-YMQCTKDU.mjs} +23 -55
  108. package/dist/esm/chunk-YMQCTKDU.mjs.map +1 -0
  109. package/dist/esm/exact/client/index.d.mts +6 -4
  110. package/dist/esm/exact/client/index.mjs +10 -5
  111. package/dist/esm/exact/facilitator/index.d.mts +16 -9
  112. package/dist/esm/exact/facilitator/index.mjs +36 -14
  113. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  114. package/dist/esm/exact/server/index.mjs +1 -1
  115. package/dist/esm/exact/v1/client/index.d.mts +2 -1
  116. package/dist/esm/exact/v1/client/index.mjs +5 -2
  117. package/dist/esm/exact/v1/facilitator/index.d.mts +11 -5
  118. package/dist/esm/exact/v1/facilitator/index.mjs +5 -2
  119. package/dist/esm/index.d.mts +113 -7
  120. package/dist/esm/index.mjs +53 -7
  121. package/dist/esm/index.mjs.map +1 -1
  122. package/dist/esm/permit2-DhJRUcgY.d.mts +729 -0
  123. package/dist/esm/rpc-DULZzRne.d.mts +13 -0
  124. package/dist/esm/scheme-DtbSS4Fk.d.mts +307 -0
  125. package/dist/esm/scheme-gtqAIYPJ.d.mts +47 -0
  126. package/dist/esm/signer-tYS6Y46X.d.mts +170 -0
  127. package/dist/esm/storage-6W5MO46W.d.mts +50 -0
  128. package/dist/esm/storage-sZ1CDS4P.d.mts +81 -0
  129. package/dist/esm/types-CF8P2-NM.d.mts +180 -0
  130. package/dist/esm/upto/client/index.d.mts +5 -3
  131. package/dist/esm/upto/client/index.mjs +9 -4
  132. package/dist/esm/upto/facilitator/index.d.mts +2 -1
  133. package/dist/esm/upto/facilitator/index.mjs +17 -9
  134. package/dist/esm/upto/facilitator/index.mjs.map +1 -1
  135. package/dist/esm/upto/server/index.mjs +1 -1
  136. package/dist/esm/v1/index.d.mts +2 -1
  137. package/dist/esm/v1/index.mjs +5 -2
  138. package/package.json +5 -5
  139. package/dist/esm/chunk-C4ZQMS77.mjs.map +0 -1
  140. package/dist/esm/chunk-CRT6YNY5.mjs.map +0 -1
  141. package/dist/esm/chunk-ERK2ZPOY.mjs.map +0 -1
  142. package/dist/esm/chunk-JII456TS.mjs.map +0 -1
  143. package/dist/esm/chunk-WKBC5YMI.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/batch-settlement/facilitator/deposit.ts","../../../../src/batch-settlement/facilitator/deposit-eip3009.ts","../../../../src/batch-settlement/facilitator/deposit-permit2.ts","../../../../src/batch-settlement/facilitator/voucher.ts","../../../../src/batch-settlement/facilitator/claim.ts","../../../../src/batch-settlement/facilitator/settle.ts","../../../../src/batch-settlement/facilitator/refund.ts","../../../../src/batch-settlement/facilitator/scheme.ts"],"sourcesContent":["import {\n FacilitatorContext,\n PaymentPayload,\n PaymentRequirements,\n VerifyResponse,\n SettleResponse,\n} from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport type { TransactionRequest } from \"../../exact/extensions\";\nimport { BatchSettlementAssetTransferMethod, BatchSettlementDepositPayload } from \"../types\";\nimport { batchSettlementABI, erc20BalanceOfABI } from \"../abi\";\nimport { BATCH_SETTLEMENT_ADDRESS } from \"../constants\";\nimport { getEvmChainId } from \"../../utils\";\nimport { multicall } from \"../../multicall\";\nimport * as Errors from \"../errors\";\nimport {\n readChannelState,\n toContractChannelConfig,\n validateChannelConfig,\n verifyBatchSettlementVoucherTypedData,\n} from \"./utils\";\nimport {\n buildEip3009DepositCollectorData,\n getEip3009DepositCollectorAddress,\n verifyEip3009DepositAuthorization,\n} from \"./deposit-eip3009\";\nimport {\n buildDepositTransaction,\n getPermit2DepositCollectorAddress,\n resolvePermit2DepositBranch,\n verifyPermit2DepositAuthorization,\n} from \"./deposit-permit2\";\n\n/**\n * Verifies a deposit payload (authorization + voucher) without executing any\n * onchain transaction.\n *\n * Performs the following validations:\n * - Token in channelConfig matches the payment requirements asset.\n * - Deposit authorization is valid for the selected transfer method.\n * - Accompanying voucher signature is valid (ECDSA or ERC-1271).\n * - Payer has sufficient token balance for the deposit.\n * - Resulting `maxClaimableAmount` does not exceed effective balance (existing + deposit).\n *\n * @param signer - Facilitator signer for onchain reads and signature verification.\n * @param payment - Full payment envelope containing optional extensions.\n * @param payload - The full deposit payload including channelConfig, amount, authorization, and voucher.\n * @param requirements - Server payment requirements (asset, EIP-712 domain info, timeout, etc.).\n * @param context - Optional facilitator extension context.\n * @returns A {@link VerifyResponse} with channel state in `extra` on success.\n */\nexport async function verifyDeposit(\n signer: FacilitatorEvmSigner,\n payment: PaymentPayload,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n): Promise<VerifyResponse> {\n const payer = payload.channelConfig.payer;\n const chainId = getEvmChainId(requirements.network);\n const configErr = validateChannelConfig(\n payload.channelConfig,\n payload.voucher.channelId,\n requirements,\n );\n if (configErr) {\n return { isValid: false, invalidReason: configErr, payer };\n }\n\n const transferMethod = resolveDepositTransferMethod(payload, requirements);\n if (transferMethod === \"permit2\" && !payload.deposit.authorization.permit2Authorization) {\n return { isValid: false, invalidReason: Errors.ErrInvalidPayloadType, payer };\n }\n\n const methodErr =\n transferMethod === \"permit2\"\n ? await verifyPermit2DepositAuthorization(\n signer,\n payment,\n payload,\n requirements,\n chainId,\n context,\n )\n : await verifyEip3009DepositAuthorization(signer, payload, requirements, chainId);\n\n if (methodErr) {\n return methodErr;\n }\n\n const shared = await verifySharedDepositState(signer, payload, requirements);\n if (!shared.ok) {\n return shared.response;\n }\n\n const { depositAmount, chBalance, chTotalClaimed, wdInitiatedAt, refundNonceVal } = shared;\n\n const execution = await resolveDepositExecution(signer, payment, payload, requirements, context);\n if (\"isValid\" in execution) {\n return execution;\n }\n\n if (!execution.skipDirectSimulation) {\n try {\n await signer.readContract({\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"deposit\",\n args: [\n toContractChannelConfig(payload.channelConfig),\n depositAmount,\n execution.collector,\n execution.collectorData,\n ],\n });\n } catch (e) {\n return {\n isValid: false,\n invalidReason: Errors.ErrDepositSimulationFailed,\n invalidMessage: e instanceof Error ? e.message : String(e),\n payer,\n };\n }\n }\n\n return {\n isValid: true,\n payer,\n extra: {\n channelId: payload.voucher.channelId,\n balance: chBalance.toString(),\n totalClaimed: chTotalClaimed.toString(),\n withdrawRequestedAt: Number(wdInitiatedAt),\n refundNonce: refundNonceVal.toString(),\n },\n };\n}\n\n/**\n * Verifies channel, voucher, balance, and cumulative amount invariants.\n *\n * @param signer - Facilitator signer for reads and voucher verification.\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for the request.\n * @returns Shared channel state on success, or a verification failure.\n */\nasync function verifySharedDepositState(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n): Promise<\n | {\n ok: true;\n chainId: number;\n depositAmount: bigint;\n payer: `0x${string}`;\n chBalance: bigint;\n chTotalClaimed: bigint;\n wdInitiatedAt: bigint;\n refundNonceVal: bigint;\n }\n | { ok: false; response: VerifyResponse }\n> {\n const { deposit, voucher } = payload;\n const config = payload.channelConfig;\n const payer = config.payer;\n const chainId = getEvmChainId(requirements.network);\n\n const configErr = validateChannelConfig(config, voucher.channelId, requirements);\n if (configErr) {\n return { ok: false, response: { isValid: false, invalidReason: configErr, payer } };\n }\n\n const voucherOk = await verifyBatchSettlementVoucherTypedData(\n signer,\n {\n channelId: voucher.channelId,\n maxClaimableAmount: voucher.maxClaimableAmount,\n payerAuthorizer: config.payerAuthorizer,\n payer: config.payer,\n signature: voucher.signature,\n },\n chainId,\n );\n if (!voucherOk) {\n return {\n ok: false,\n response: { isValid: false, invalidReason: Errors.ErrInvalidVoucherSignature, payer },\n };\n }\n\n const mcResults = await multicall(signer.readContract.bind(signer), [\n {\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"channels\",\n args: [voucher.channelId],\n },\n {\n address: getAddress(requirements.asset),\n abi: erc20BalanceOfABI,\n functionName: \"balanceOf\",\n args: [getAddress(payer)],\n },\n {\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"pendingWithdrawals\",\n args: [voucher.channelId],\n },\n {\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"refundNonce\",\n args: [voucher.channelId],\n },\n ]);\n\n const [chRes, balRes, wdRes, rnRes] = mcResults;\n if (\n chRes.status === \"failure\" ||\n balRes.status === \"failure\" ||\n wdRes.status === \"failure\" ||\n rnRes.status === \"failure\"\n ) {\n return {\n ok: false,\n response: { isValid: false, invalidReason: Errors.ErrRpcReadFailed, payer },\n };\n }\n\n const [chBalance, chTotalClaimed] = chRes.result as [bigint, bigint];\n const payerBalance = balRes.result as bigint;\n const [, wdInitiatedAt] = wdRes.result as [bigint, bigint];\n const refundNonceVal = rnRes.result as bigint;\n const depositAmount = BigInt(deposit.amount);\n\n if (payerBalance < depositAmount) {\n return {\n ok: false,\n response: { isValid: false, invalidReason: Errors.ErrInsufficientBalance, payer },\n };\n }\n\n const effectiveBalance = chBalance + depositAmount;\n const maxClaimableAmount = BigInt(voucher.maxClaimableAmount);\n\n if (maxClaimableAmount > effectiveBalance) {\n return {\n ok: false,\n response: { isValid: false, invalidReason: Errors.ErrCumulativeExceedsBalance, payer },\n };\n }\n\n if (maxClaimableAmount <= chTotalClaimed) {\n return {\n ok: false,\n response: { isValid: false, invalidReason: Errors.ErrCumulativeAmountBelowClaimed, payer },\n };\n }\n\n return {\n ok: true,\n chainId,\n depositAmount,\n payer,\n chBalance,\n chTotalClaimed,\n wdInitiatedAt,\n refundNonceVal,\n };\n}\n\n/**\n * Executes a deposit onchain through the collector for the selected transfer method.\n *\n * The deposit is first verified via {@link verifyDeposit}; if invalid the returned\n * {@link SettleResponse} will have `success: false` with the verification reason.\n *\n * @param signer - Facilitator signer used to submit the onchain transaction.\n * @param payment - Full payment envelope containing optional extensions.\n * @param payload - The deposit payload (channelConfig, amount, authorization, voucher).\n * @param requirements - Server payment requirements.\n * @param context - Optional facilitator extension context.\n * @returns A {@link SettleResponse} with the transaction hash and updated channel state in `extra`.\n */\nexport async function settleDeposit(\n signer: FacilitatorEvmSigner,\n payment: PaymentPayload,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n): Promise<SettleResponse> {\n const { deposit, voucher } = payload;\n const config = payload.channelConfig;\n const payer = config.payer;\n\n const verified = await verifyDeposit(signer, payment, payload, requirements, context);\n if (!verified.isValid) {\n const reason = verified.invalidReason ?? Errors.ErrInvalidPayloadType;\n return {\n success: false,\n errorReason: reason,\n errorMessage: verified.invalidMessage ?? reason,\n transaction: \"\",\n network: requirements.network,\n payer: verified.payer,\n };\n }\n\n try {\n const execution = await resolveDepositExecution(\n signer,\n payment,\n payload,\n requirements,\n context,\n );\n if (\"isValid\" in execution) {\n const reason = execution.invalidReason ?? Errors.ErrInvalidPayloadType;\n return {\n success: false,\n errorReason: reason,\n errorMessage: execution.invalidMessage ?? reason,\n transaction: \"\",\n network: requirements.network,\n payer: execution.payer,\n };\n }\n\n const depositTx = buildDepositTransaction(payload, execution.collectorData);\n const tx =\n execution.kind === \"erc20Approval\"\n ? (\n await execution.extensionSigner.sendTransactions([\n execution.signedTransaction,\n depositTx,\n ])\n )[1]\n : await signer.writeContract({\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"deposit\",\n args: [\n toContractChannelConfig(config),\n BigInt(deposit.amount),\n execution.collector,\n execution.collectorData,\n ],\n });\n\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrDepositTransactionFailed,\n errorMessage: `transaction reverted (receipt status ${receipt.status})`,\n transaction: tx,\n network: requirements.network,\n payer,\n };\n }\n\n const optimisticExtra = {\n channelState: {\n channelId: voucher.channelId,\n balance: (\n BigInt(String(verified.extra?.balance ?? \"0\")) + BigInt(deposit.amount)\n ).toString(),\n totalClaimed: String(verified.extra?.totalClaimed ?? \"0\"),\n withdrawRequestedAt: Number(verified.extra?.withdrawRequestedAt ?? 0),\n refundNonce: String(verified.extra?.refundNonce ?? \"0\"),\n },\n };\n\n // Poll the RPC until it reflects the just-confirmed deposit, so subsequent verify reads are guaranteed to see this balance\n const expectedMinBalance = BigInt(optimisticExtra.channelState.balance);\n const rpcDeadline = Date.now() + 2_000;\n let postState = await readChannelState(signer, voucher.channelId);\n while (postState.balance < expectedMinBalance && Date.now() < rpcDeadline) {\n await new Promise(resolve => setTimeout(resolve, 150));\n postState = await readChannelState(signer, voucher.channelId);\n }\n\n const rpcCaughtUp = postState.balance >= expectedMinBalance;\n\n return {\n success: true,\n transaction: tx,\n network: requirements.network,\n payer,\n amount: deposit.amount,\n extra: rpcCaughtUp\n ? {\n ...optimisticExtra,\n channelState: {\n channelId: voucher.channelId,\n balance: postState.balance.toString(),\n totalClaimed: postState.totalClaimed.toString(),\n withdrawRequestedAt: postState.withdrawRequestedAt,\n refundNonce: postState.refundNonce.toString(),\n },\n }\n : optimisticExtra,\n };\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrDepositTransactionFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network: requirements.network,\n payer,\n };\n }\n}\n\ntype DepositExecution =\n | {\n kind: \"direct\";\n collector: `0x${string}`;\n collectorData: `0x${string}`;\n skipDirectSimulation?: false;\n }\n | {\n kind: \"erc20Approval\";\n collector: `0x${string}`;\n collectorData: `0x${string}`;\n signedTransaction: `0x${string}`;\n extensionSigner: {\n sendTransactions(transactions: TransactionRequest[]): Promise<`0x${string}`[]>;\n };\n skipDirectSimulation: true;\n };\n\n/**\n * Resolves the collector address and collector data for a deposit payload.\n *\n * @param signer - Facilitator signer for Permit2 allowance reads.\n * @param payment - Full payment envelope containing optional extensions.\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for the request.\n * @param context - Optional facilitator extension context.\n * @returns Execution details, or a verification failure response.\n */\nasync function resolveDepositExecution(\n signer: FacilitatorEvmSigner,\n payment: PaymentPayload,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n): Promise<DepositExecution | VerifyResponse> {\n const transferMethod = resolveDepositTransferMethod(payload, requirements);\n if (transferMethod === \"eip3009\") {\n return {\n kind: \"direct\",\n collector: getEip3009DepositCollectorAddress(),\n collectorData: buildEip3009DepositCollectorData(payload),\n };\n }\n\n const branch = await resolvePermit2DepositBranch(signer, payment, payload, requirements, context);\n if (\"isValid\" in branch) {\n return branch;\n }\n\n if (branch.kind === \"erc20Approval\") {\n return {\n kind: \"erc20Approval\",\n collector: getPermit2DepositCollectorAddress(),\n collectorData: branch.collectorData,\n signedTransaction: branch.signedTransaction,\n extensionSigner: branch.extensionSigner,\n skipDirectSimulation: true,\n };\n }\n\n return {\n kind: \"direct\",\n collector: getPermit2DepositCollectorAddress(),\n collectorData: branch.collectorData,\n };\n}\n\n/**\n * Selects the transfer method from requirements, falling back to payload shape.\n *\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for the request.\n * @returns Selected batch-settlement transfer method.\n */\nfunction resolveDepositTransferMethod(\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n): BatchSettlementAssetTransferMethod {\n const hinted = (\n requirements.extra as { assetTransferMethod?: BatchSettlementAssetTransferMethod }\n )?.assetTransferMethod;\n if (hinted) {\n return hinted;\n }\n return payload.deposit.authorization.permit2Authorization ? \"permit2\" : \"eip3009\";\n}\n","import { PaymentRequirements, VerifyResponse } from \"@payai/x402/types\";\nimport { getAddress, parseErc6492Signature } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { BatchSettlementDepositPayload } from \"../types\";\nimport { ERC3009_DEPOSIT_COLLECTOR_ADDRESS, receiveAuthorizationTypes } from \"../constants\";\nimport { buildErc3009CollectorData, buildErc3009DepositNonce } from \"../encoding\";\nimport * as Errors from \"../errors\";\nimport { erc3009AuthorizationTimeInvalidReason } from \"./utils\";\n\n/**\n * Returns the collector contract used for EIP-3009 deposits.\n *\n * @returns ERC-3009 deposit collector address.\n */\nexport function getEip3009DepositCollectorAddress(): `0x${string}` {\n return getAddress(ERC3009_DEPOSIT_COLLECTOR_ADDRESS);\n}\n\n/**\n * Encodes collector data for an EIP-3009 deposit payload.\n *\n * @param payload - Deposit payload containing the ERC-3009 authorization.\n * @returns ABI-encoded collector data.\n */\nexport function buildEip3009DepositCollectorData(\n payload: BatchSettlementDepositPayload,\n): `0x${string}` {\n const auth = payload.deposit.authorization.erc3009Authorization;\n if (!auth) {\n throw new Error(Errors.ErrErc3009AuthorizationRequired);\n }\n\n const { signature } = parseErc6492Signature(auth.signature);\n return buildErc3009CollectorData(auth.validAfter, auth.validBefore, auth.salt, signature);\n}\n\n/**\n * Verifies the ERC-3009 authorization fields and typed-data signature.\n *\n * @param signer - Facilitator signer for typed-data verification.\n * @param payload - Deposit payload to verify.\n * @param requirements - Payment requirements containing token domain metadata.\n * @param chainId - EVM chain id.\n * @returns A failure response, or `null` when valid.\n */\nexport async function verifyEip3009DepositAuthorization(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n chainId: number,\n): Promise<VerifyResponse | null> {\n const { deposit, voucher } = payload;\n const payer = payload.channelConfig.payer;\n const auth = deposit.authorization.erc3009Authorization;\n\n if (!auth) {\n return { isValid: false, invalidReason: Errors.ErrErc3009AuthorizationRequired, payer };\n }\n\n const extra = requirements.extra as { name?: string; version?: string } | undefined;\n if (!extra?.name || !extra?.version) {\n return { isValid: false, invalidReason: Errors.ErrMissingEip712Domain, payer };\n }\n\n const validAfter = BigInt(auth.validAfter);\n const validBefore = BigInt(auth.validBefore);\n const timeInvalid = erc3009AuthorizationTimeInvalidReason(validAfter, validBefore);\n if (timeInvalid) {\n return { isValid: false, invalidReason: timeInvalid, payer };\n }\n\n const erc3009Nonce = buildErc3009DepositNonce(voucher.channelId, auth.salt);\n const receiveAuthOk = await verifyReceiveAuth(signer, {\n payer,\n asset: requirements.asset,\n name: extra.name,\n version: extra.version,\n chainId,\n amount: deposit.amount,\n validAfter,\n validBefore,\n nonce: erc3009Nonce,\n signature: auth.signature,\n });\n\n if (!receiveAuthOk) {\n return { isValid: false, invalidReason: Errors.ErrInvalidReceiveAuthorizationSignature, payer };\n }\n\n return null;\n}\n\n/**\n * Verifies a `ReceiveWithAuthorization` signature.\n *\n * @param signer - Facilitator signer used for typed-data verification.\n * @param params - Authorization fields and signature.\n * @param params.payer - Expected authorization signer.\n * @param params.asset - ERC-20 verifying contract.\n * @param params.name - ERC-20 EIP-712 domain name.\n * @param params.version - ERC-20 EIP-712 domain version.\n * @param params.chainId - EVM chain id.\n * @param params.amount - Authorized token amount.\n * @param params.validAfter - Earliest valid timestamp.\n * @param params.validBefore - Expiration timestamp.\n * @param params.nonce - ERC-3009 nonce.\n * @param params.signature - Receive authorization signature.\n * @returns True when the signature matches the expected payer.\n */\nasync function verifyReceiveAuth(\n signer: FacilitatorEvmSigner,\n params: {\n payer: `0x${string}`;\n asset: string;\n name: string;\n version: string;\n chainId: number;\n amount: string;\n validAfter: bigint;\n validBefore: bigint;\n nonce: `0x${string}`;\n signature: `0x${string}`;\n },\n): Promise<boolean> {\n try {\n return await signer.verifyTypedData({\n address: getAddress(params.payer),\n domain: {\n name: params.name,\n version: params.version,\n chainId: params.chainId,\n verifyingContract: getAddress(params.asset),\n },\n types: receiveAuthorizationTypes,\n primaryType: \"ReceiveWithAuthorization\",\n message: {\n from: getAddress(params.payer),\n to: getAddress(ERC3009_DEPOSIT_COLLECTOR_ADDRESS),\n value: BigInt(params.amount),\n validAfter: params.validAfter,\n validBefore: params.validBefore,\n nonce: params.nonce,\n },\n signature: params.signature,\n });\n } catch {\n return false;\n }\n}\n","import {\n FacilitatorContext,\n PaymentPayload,\n PaymentRequirements,\n VerifyResponse,\n} from \"@payai/x402/types\";\nimport { encodeFunctionData, getAddress, parseErc6492Signature } from \"viem\";\nimport {\n extractEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n resolveErc20ApprovalExtensionSigner,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../../exact/extensions\";\nimport { validateErc20ApprovalForPayment } from \"../../shared/erc20approval\";\nimport { validateEip2612PermitForPayment, splitEip2612Signature } from \"../../shared/permit2\";\nimport { PERMIT2_ADDRESS, erc20AllowanceAbi } from \"../../constants\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { batchSettlementABI } from \"../abi\";\nimport {\n BATCH_SETTLEMENT_ADDRESS,\n PERMIT2_DEPOSIT_COLLECTOR_ADDRESS,\n batchPermit2WitnessTypes,\n} from \"../constants\";\nimport { buildEip2612PermitData, buildPermit2CollectorData } from \"../encoding\";\nimport { BatchSettlementDepositPayload } from \"../types\";\nimport { toContractChannelConfig } from \"./utils\";\nimport * as Errors from \"../errors\";\n\nexport type Permit2DepositBranch =\n | {\n kind: \"standard\";\n collectorData: `0x${string}`;\n }\n | {\n kind: \"eip2612\";\n collectorData: `0x${string}`;\n }\n | {\n kind: \"erc20Approval\";\n collectorData: `0x${string}`;\n signedTransaction: `0x${string}`;\n extensionSigner: Erc20ApprovalGasSponsoringSigner;\n };\n\n/**\n * Returns the collector contract used for Permit2 deposits.\n *\n * @returns Permit2 deposit collector address.\n */\nexport function getPermit2DepositCollectorAddress(): `0x${string}` {\n return getAddress(PERMIT2_DEPOSIT_COLLECTOR_ADDRESS);\n}\n\n/**\n * Encodes collector data for a Permit2 deposit payload.\n *\n * @param payload - Deposit payload containing the Permit2 authorization.\n * @param eip2612PermitData - Optional encoded EIP-2612 permit segment.\n * @returns ABI-encoded collector data.\n */\nexport function buildPermit2DepositCollectorData(\n payload: BatchSettlementDepositPayload,\n eip2612PermitData: `0x${string}` = \"0x\",\n): `0x${string}` {\n const auth = payload.deposit.authorization.permit2Authorization;\n if (!auth) {\n throw new Error(Errors.ErrPermit2AuthorizationRequired);\n }\n\n const { signature } = parseErc6492Signature(auth.signature);\n return buildPermit2CollectorData(auth.nonce, auth.deadline, signature, eip2612PermitData);\n}\n\n/**\n * Verifies Permit2 authorization fields, setup branch, and approval-bundle simulation.\n *\n * @param signer - Facilitator signer for reads and signature verification.\n * @param payment - Full payment envelope containing optional extensions.\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for the request.\n * @param chainId - EVM chain id.\n * @param context - Optional facilitator extension context.\n * @returns A failure response, or `null` when valid.\n */\nexport async function verifyPermit2DepositAuthorization(\n signer: FacilitatorEvmSigner,\n payment: PaymentPayload,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n chainId: number,\n context?: FacilitatorContext,\n): Promise<VerifyResponse | null> {\n const authResult = await verifyPermit2TypedData(signer, payload, requirements, chainId);\n if (authResult) {\n return authResult;\n }\n\n const branchResult = await resolvePermit2DepositBranch(\n signer,\n payment,\n payload,\n requirements,\n context,\n );\n if (\"isValid\" in branchResult) {\n return branchResult;\n }\n\n if (branchResult.kind !== \"erc20Approval\" || !branchResult.extensionSigner.simulateTransactions) {\n return null;\n }\n\n const ok = await branchResult.extensionSigner.simulateTransactions([\n branchResult.signedTransaction,\n buildDepositTransaction(payload, branchResult.collectorData),\n ]);\n if (!ok) {\n return {\n isValid: false,\n invalidReason: Errors.ErrDepositSimulationFailed,\n payer: payload.channelConfig.payer,\n };\n }\n\n return null;\n}\n\n/**\n * Resolves the Permit2 setup branch and collector data for verification or settlement.\n *\n * @param signer - Facilitator signer for allowance reads.\n * @param payment - Full payment envelope containing optional extensions.\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for the request.\n * @param context - Optional facilitator extension context.\n * @returns Resolved branch, or a verification failure response.\n */\nexport async function resolvePermit2DepositBranch(\n signer: FacilitatorEvmSigner,\n payment: PaymentPayload,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n): Promise<Permit2DepositBranch | VerifyResponse> {\n const payer = payload.channelConfig.payer;\n const tokenAddress = getAddress(requirements.asset);\n const eip2612Info = extractEip2612GasSponsoringInfo(payment);\n if (eip2612Info) {\n const result = validateBatchEip2612Permit(\n eip2612Info,\n payer,\n tokenAddress,\n payload.deposit.amount,\n );\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason, payer };\n }\n\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n return {\n kind: \"eip2612\",\n collectorData: buildPermit2DepositCollectorData(\n payload,\n buildEip2612PermitData({\n value: eip2612Info.amount,\n deadline: eip2612Info.deadline,\n v,\n r,\n s,\n }),\n ),\n };\n }\n\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payment);\n if (erc20Info) {\n const extensionSigner = resolveErc20ApprovalExtensionSigner(\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n ),\n requirements.network,\n );\n if (!extensionSigner) {\n return { isValid: false, invalidReason: Errors.ErrErc20ApprovalUnavailable, payer };\n }\n\n const result = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!result.isValid) {\n return {\n isValid: false,\n invalidReason: result.invalidReason,\n invalidMessage: result.invalidMessage,\n payer,\n };\n }\n\n return {\n kind: \"erc20Approval\",\n collectorData: buildPermit2DepositCollectorData(payload),\n signedTransaction: erc20Info.signedTransaction,\n extensionSigner,\n };\n }\n\n try {\n const allowance = (await signer.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [payer, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance < BigInt(payload.deposit.amount)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2AllowanceRequired, payer };\n }\n } catch {\n return { isValid: false, invalidReason: Errors.ErrPermit2AllowanceRequired, payer };\n }\n\n return {\n kind: \"standard\",\n collectorData: buildPermit2DepositCollectorData(payload),\n };\n}\n\n/**\n * Builds the unsigned batch `deposit` transaction used after a sponsored approval.\n *\n * @param payload - Batch deposit payload.\n * @param collectorData - Encoded Permit2 collector data.\n * @returns Transaction request for the extension signer.\n */\nexport function buildDepositTransaction(\n payload: BatchSettlementDepositPayload,\n collectorData: `0x${string}`,\n): { to: `0x${string}`; data: `0x${string}`; gas: bigint } {\n return {\n to: getAddress(BATCH_SETTLEMENT_ADDRESS),\n data: encodeFunctionData({\n abi: batchSettlementABI,\n functionName: \"deposit\",\n args: [\n toContractChannelConfig(payload.channelConfig),\n BigInt(payload.deposit.amount),\n getPermit2DepositCollectorAddress(),\n collectorData,\n ],\n }),\n gas: 300_000n,\n };\n}\n\n/**\n * Verifies the channel-bound Permit2 typed-data authorization.\n *\n * @param signer - Facilitator signer for typed-data verification.\n * @param payload - Batch deposit payload.\n * @param requirements - Payment requirements for token matching.\n * @param chainId - EVM chain id.\n * @returns A failure response, or `null` when valid.\n */\nasync function verifyPermit2TypedData(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementDepositPayload,\n requirements: PaymentRequirements,\n chainId: number,\n): Promise<VerifyResponse | null> {\n const auth = payload.deposit.authorization.permit2Authorization;\n const payer = payload.channelConfig.payer;\n\n if (!auth) {\n return { isValid: false, invalidReason: Errors.ErrPermit2AuthorizationRequired, payer };\n }\n\n if (getAddress(auth.from) !== getAddress(payer)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2InvalidSignature, payer };\n }\n\n if (getAddress(auth.spender) !== getPermit2DepositCollectorAddress()) {\n return { isValid: false, invalidReason: Errors.ErrPermit2InvalidSpender, payer };\n }\n\n if (getAddress(auth.permitted.token) !== getAddress(requirements.asset)) {\n return { isValid: false, invalidReason: Errors.ErrTokenMismatch, payer };\n }\n\n if (BigInt(auth.permitted.amount) !== BigInt(payload.deposit.amount)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2AmountMismatch, payer };\n }\n\n if (auth.witness.channelId !== payload.voucher.channelId) {\n return { isValid: false, invalidReason: Errors.ErrChannelIdMismatch, payer };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(auth.deadline) < BigInt(now + 6)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2DeadlineExpired, payer };\n }\n\n try {\n const ok = await signer.verifyTypedData({\n address: getAddress(auth.from),\n domain: { name: \"Permit2\", chainId, verifyingContract: PERMIT2_ADDRESS },\n types: batchPermit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message: {\n permitted: {\n token: getAddress(auth.permitted.token),\n amount: BigInt(auth.permitted.amount),\n },\n spender: getAddress(auth.spender),\n nonce: BigInt(auth.nonce),\n deadline: BigInt(auth.deadline),\n witness: {\n channelId: auth.witness.channelId,\n },\n },\n signature: auth.signature,\n });\n if (!ok) {\n return { isValid: false, invalidReason: Errors.ErrPermit2InvalidSignature, payer };\n }\n } catch {\n return { isValid: false, invalidReason: Errors.ErrPermit2InvalidSignature, payer };\n }\n\n return null;\n}\n\n/**\n * Applies batch-specific EIP-2612 validation on top of the shared Permit2 checks.\n *\n * @param info - EIP-2612 sponsoring info from the payment envelope.\n * @param payer - Expected token owner.\n * @param tokenAddress - Expected token contract.\n * @param depositAmount - Required approval amount.\n * @returns Validation result.\n */\nfunction validateBatchEip2612Permit(\n info: Eip2612GasSponsoringInfo,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n depositAmount: string,\n): { isValid: true } | { isValid: false; invalidReason: string } {\n const baseline = validateEip2612PermitForPayment(info, payer, tokenAddress);\n if (!baseline.isValid) {\n return {\n isValid: false,\n invalidReason: baseline.invalidReason ?? Errors.ErrInvalidPayloadType,\n };\n }\n\n if (BigInt(info.amount) !== BigInt(depositAmount)) {\n return { isValid: false, invalidReason: Errors.ErrEip2612AmountMismatch };\n }\n\n return { isValid: true };\n}\n","import { PaymentRequirements, VerifyResponse } from \"@payai/x402/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport {\n BatchSettlementRefundPayload,\n BatchSettlementVoucherPayload,\n ChannelConfig,\n} from \"../types\";\nimport { getEvmChainId } from \"../../utils\";\nimport * as Errors from \"../errors\";\nimport {\n validateChannelConfig,\n verifyBatchSettlementVoucherTypedData,\n readChannelState,\n} from \"./utils\";\n\n/**\n * Verifies a cumulative voucher payload against onchain channel state.\n *\n * @param signer - Facilitator signer used for onchain reads and signature verification.\n * @param payload - Voucher or refund payload with signed voucher fields.\n * @param requirements - Server payment requirements (asset, network, amount).\n * @param channelConfig - Reconstructed channel configuration for the payer/receiver pair.\n * @returns A {@link VerifyResponse} indicating validity and returning channel state in `extra`.\n */\nexport async function verifyVoucher(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementVoucherPayload | BatchSettlementRefundPayload,\n requirements: PaymentRequirements,\n channelConfig: ChannelConfig,\n): Promise<VerifyResponse> {\n const { voucher } = payload;\n const channelId = voucher.channelId;\n const chainId = getEvmChainId(requirements.network);\n\n const configErr = validateChannelConfig(channelConfig, channelId, requirements);\n if (configErr) {\n return { isValid: false, invalidReason: configErr, payer: channelConfig.payer };\n }\n\n const voucherOk = await verifyBatchSettlementVoucherTypedData(\n signer,\n {\n channelId,\n maxClaimableAmount: voucher.maxClaimableAmount,\n payerAuthorizer: channelConfig.payerAuthorizer,\n payer: channelConfig.payer,\n signature: voucher.signature,\n },\n chainId,\n );\n if (!voucherOk) {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidVoucherSignature,\n payer: channelConfig.payer,\n };\n }\n\n const state = await readChannelState(signer, channelId);\n\n if (state.balance === 0n) {\n return { isValid: false, invalidReason: Errors.ErrChannelNotFound, payer: channelConfig.payer };\n }\n\n const maxClaimableAmount = BigInt(voucher.maxClaimableAmount);\n\n if (maxClaimableAmount > state.balance) {\n return {\n isValid: false,\n invalidReason: Errors.ErrCumulativeExceedsBalance,\n payer: channelConfig.payer,\n };\n }\n\n const belowClaimed =\n payload.type === \"refund\"\n ? maxClaimableAmount < state.totalClaimed\n : maxClaimableAmount <= state.totalClaimed;\n if (belowClaimed) {\n return {\n isValid: false,\n invalidReason: Errors.ErrCumulativeAmountBelowClaimed,\n payer: channelConfig.payer,\n };\n }\n\n return {\n isValid: true,\n payer: channelConfig.payer,\n extra: {\n channelId,\n balance: state.balance.toString(),\n totalClaimed: state.totalClaimed.toString(),\n withdrawRequestedAt: state.withdrawRequestedAt,\n refundNonce: state.refundNonce.toString(),\n },\n };\n}\n","import { SettleResponse, PaymentRequirements } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport type { AuthorizerSigner, BatchSettlementClaimPayload } from \"../types\";\nimport { batchSettlementABI } from \"../abi\";\nimport { BATCH_SETTLEMENT_ADDRESS } from \"../constants\";\nimport { signClaimBatch } from \"../authorizerSigner\";\nimport * as Errors from \"../errors\";\nimport { toContractChannelConfig } from \"./utils\";\n\n/**\n * Converts an array of {@link BatchSettlementVoucherClaim} into the onchain tuple format\n * expected by the contract's `claimWithSignature()` function.\n *\n * @param claims - Typed voucher claims with channel config, amounts, and signatures.\n * @returns Contract-ready VoucherClaim argument array.\n */\nexport function buildVoucherClaimArgs(claims: BatchSettlementClaimPayload[\"claims\"]) {\n return claims.map(c => ({\n voucher: {\n channel: toContractChannelConfig(c.voucher.channel),\n maxClaimableAmount: BigInt(c.voucher.maxClaimableAmount),\n },\n signature: c.signature,\n totalClaimed: BigInt(c.totalClaimed),\n }));\n}\n\n/**\n * Submits a batch claim via `claimWithSignature()`.\n *\n * When `claimAuthorizerSignature` is present in the payload it is used directly.\n * When absent the facilitator signs the `ClaimBatch` EIP-712 digest using\n * `authorizerSigner`, after verifying that every claim's `receiverAuthorizer`\n * matches `authorizerSigner.address`.\n *\n * @param signer - Facilitator signer used to submit the claim transaction.\n * @param payload - Claim payload containing voucher claims and optional authorizer signature.\n * @param requirements - Payment requirements for network identification.\n * @param authorizerSigner - Dedicated key for producing `ClaimBatch` EIP-712 signatures.\n * @returns A {@link SettleResponse} with the transaction hash on success.\n */\nexport async function executeClaimWithSignature(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementClaimPayload,\n requirements: PaymentRequirements,\n authorizerSigner: AuthorizerSigner,\n): Promise<SettleResponse> {\n const network = requirements.network;\n const claimArgs = buildVoucherClaimArgs(payload.claims);\n\n let sig = payload.claimAuthorizerSignature;\n\n if (!sig) {\n for (const claim of payload.claims) {\n if (\n getAddress(claim.voucher.channel.receiverAuthorizer) !==\n getAddress(authorizerSigner.address)\n ) {\n return {\n success: false,\n errorReason: Errors.ErrAuthorizerAddressMismatch,\n transaction: \"\",\n network,\n };\n }\n }\n sig = await signClaimBatch(authorizerSigner, payload.claims, network);\n }\n\n try {\n await signer.readContract({\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"claimWithSignature\",\n args: [claimArgs, sig],\n });\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrClaimSimulationFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n\n try {\n const tx = await signer.writeContract({\n address: getAddress(BATCH_SETTLEMENT_ADDRESS),\n abi: batchSettlementABI,\n functionName: \"claimWithSignature\",\n args: [claimArgs, sig],\n });\n\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrClaimTransactionFailed,\n errorMessage: `transaction reverted (receipt status ${receipt.status})`,\n transaction: tx,\n network,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network,\n amount: \"\",\n };\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrClaimTransactionFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n}\n","import { SettleResponse, PaymentRequirements } from \"@payai/x402/types\";\nimport { getAddress, isAddressEqual, parseEventLogs } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { BatchSettlementSettlePayload } from \"../types\";\nimport { batchSettlementABI } from \"../abi\";\nimport { BATCH_SETTLEMENT_ADDRESS } from \"../constants\";\nimport * as Errors from \"../errors\";\n\n/**\n * Transfers claimed funds from the contract.\n *\n * This should be called after one or more `claim()` transactions have updated the\n * receiver's `totalClaimed` accounting onchain.\n *\n * @param signer - Facilitator signer used to submit the settlement transaction.\n * @param payload - Settle payload containing the receiver address and token address.\n * @param requirements - Payment requirements for network identification.\n * @returns A {@link SettleResponse} with the transaction hash on success.\n */\nexport async function executeSettle(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementSettlePayload,\n requirements: PaymentRequirements,\n): Promise<SettleResponse> {\n const network = requirements.network;\n const contractAddr = getAddress(BATCH_SETTLEMENT_ADDRESS);\n const receiver = getAddress(payload.receiver);\n const token = getAddress(payload.token);\n\n // Check if there is anything to settle\n try {\n const [totalClaimed, totalSettled] = (await signer.readContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"receivers\",\n args: [receiver, token],\n })) as readonly [bigint, bigint];\n\n if (totalClaimed <= totalSettled) {\n return {\n success: false,\n errorReason: Errors.ErrNothingToSettle,\n errorMessage: \"nothing to settle for receiver and token\",\n transaction: \"\",\n network,\n };\n }\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrRpcReadFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n\n // Simulate the settle transaction\n try {\n await signer.readContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"settle\",\n args: [receiver, token],\n });\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrSettleSimulationFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n\n try {\n const tx = await signer.writeContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"settle\",\n args: [receiver, token],\n });\n\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrSettleTransactionFailed,\n errorMessage: `transaction reverted (receipt status ${receipt.status})`,\n transaction: tx,\n network,\n };\n }\n\n let amount = \"\";\n if (receipt.logs) {\n const logs = parseEventLogs({\n abi: batchSettlementABI,\n eventName: \"Settled\",\n logs: receipt.logs.filter(log => isAddressEqual(log.address, contractAddr)),\n });\n const settledLog = logs.find(\n log => isAddressEqual(log.args.receiver, receiver) && isAddressEqual(log.args.token, token),\n );\n amount = settledLog?.args.amount.toString() ?? \"0\";\n }\n\n return {\n success: true,\n transaction: tx,\n network,\n amount,\n };\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrSettleTransactionFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n}\n","import { SettleResponse, PaymentRequirements } from \"@payai/x402/types\";\nimport { encodeFunctionData, getAddress } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport type {\n AuthorizerSigner,\n BatchSettlementEnrichedRefundPayload,\n ChannelState,\n} from \"../types\";\nimport { batchSettlementABI } from \"../abi\";\nimport { BATCH_SETTLEMENT_ADDRESS } from \"../constants\";\nimport { computeChannelId } from \"../utils\";\nimport { signClaimBatch, signRefund } from \"../authorizerSigner\";\nimport * as Errors from \"../errors\";\nimport { buildVoucherClaimArgs } from \"./claim\";\nimport { readChannelState, toContractChannelConfig } from \"./utils\";\n\ntype RefundSettlementExtra = {\n channelState: {\n channelId: `0x${string}`;\n balance: string;\n totalClaimed: string;\n withdrawRequestedAt: number;\n refundNonce: string;\n };\n};\n\ntype RefundSettlementDetails = {\n amount: string;\n extra: RefundSettlementExtra;\n};\n\nconst REFUND_STATE_POLL_MS = 2_000;\nconst REFUND_STATE_POLL_INTERVAL_MS = 150;\n\n/**\n * Computes the token amount that `refundWithSignature` would transfer after any\n * bundled claims are applied.\n *\n * @param payload - Refund payload containing requested refund amount and claims.\n * @param preState - Onchain channel state before the refund transaction.\n * @param channelId - Channel being refunded.\n * @param network - Network identifier used to compute claim channel ids.\n * @returns Refund amount if it can be determined, or `null` when claim data should be left to simulation.\n */\nfunction getRefundableAmount(\n payload: BatchSettlementEnrichedRefundPayload,\n preState: ChannelState,\n channelId: `0x${string}`,\n network: string,\n): bigint | null {\n const postClaimTotalClaimed = payload.claims.reduce((max, claim) => {\n const claimChannelId = computeChannelId(claim.voucher.channel, network);\n if (claimChannelId.toLowerCase() !== channelId.toLowerCase()) {\n return max;\n }\n\n const totalClaimed = BigInt(claim.totalClaimed);\n return totalClaimed > max ? totalClaimed : max;\n }, preState.totalClaimed);\n\n if (postClaimTotalClaimed > preState.balance) {\n return null;\n }\n\n const requestedAmount = BigInt(payload.amount);\n if (requestedAmount === 0n) {\n return null;\n }\n\n const available = preState.balance - postClaimTotalClaimed;\n return requestedAmount > available ? available : requestedAmount;\n}\n\n/**\n * Builds facilitator-owned response details for a refund settlement after applying the refund amount.\n *\n * @param payload - Refund payload containing claims and amount.\n * @param channelId - Canonical channel id for the refund.\n * @param preState - Onchain channel state before this refund, or null if unknown.\n * @returns Actual refund amount and extra fields for the settlement response.\n */\nfunction buildRefundExtra(\n payload: BatchSettlementEnrichedRefundPayload,\n channelId: `0x${string}`,\n preState: ChannelState | null,\n): RefundSettlementDetails {\n const preTotalClaimed = preState?.totalClaimed ?? 0n;\n const preBalance = preState?.balance ?? 0n;\n\n const lastClaimTotal =\n payload.claims.length > 0\n ? BigInt(payload.claims[payload.claims.length - 1].totalClaimed)\n : preTotalClaimed;\n const postClaimTotalClaimed = lastClaimTotal > preTotalClaimed ? lastClaimTotal : preTotalClaimed;\n\n const available = preBalance - postClaimTotalClaimed;\n const requestedAmount = BigInt(payload.amount);\n const actualRefund = requestedAmount > available ? available : requestedAmount;\n\n return {\n amount: actualRefund.toString(),\n extra: {\n channelState: {\n channelId,\n balance: (preBalance - actualRefund).toString(),\n totalClaimed: postClaimTotalClaimed.toString(),\n withdrawRequestedAt: 0,\n refundNonce: String((preState?.refundNonce ?? 0n) + 1n),\n },\n },\n };\n}\n\n/**\n * Reads the post-refund state when pending withdrawal state can be affected.\n *\n * @param signer - Facilitator signer used for onchain reads.\n * @param channelId - Channel that was refunded.\n * @param submittedNonce - Nonce used for this refund transaction.\n * @returns Fresh channel state once the nonce advances, or `null` if RPC reads lag.\n */\nasync function readPostRefundState(\n signer: FacilitatorEvmSigner,\n channelId: `0x${string}`,\n submittedNonce: string,\n): Promise<ChannelState | null> {\n const expectedNonce = BigInt(submittedNonce) + 1n;\n const deadline = Date.now() + REFUND_STATE_POLL_MS;\n\n do {\n let state: ChannelState;\n try {\n state = await readChannelState(signer, channelId);\n } catch {\n return null;\n }\n if (state.refundNonce >= expectedNonce) {\n return state;\n }\n await new Promise(resolve => setTimeout(resolve, REFUND_STATE_POLL_INTERVAL_MS));\n } while (Date.now() < deadline);\n\n return null;\n}\n\n/**\n * Builds refund response details from confirmed post-transaction state.\n *\n * @param channelId - Canonical channel id for the refund.\n * @param preState - Onchain state read before the transaction.\n * @param postState - Onchain state after the transaction.\n * @returns Actual refund amount and extra fields for the settlement response.\n */\nfunction buildRefundExtraFromPostState(\n channelId: `0x${string}`,\n preState: ChannelState,\n postState: ChannelState,\n): RefundSettlementDetails {\n const actualRefund =\n preState.balance > postState.balance ? preState.balance - postState.balance : 0n;\n\n return {\n amount: actualRefund.toString(),\n extra: {\n channelState: {\n channelId,\n balance: postState.balance.toString(),\n totalClaimed: postState.totalClaimed.toString(),\n withdrawRequestedAt: postState.withdrawRequestedAt,\n refundNonce: postState.refundNonce.toString(),\n },\n },\n };\n}\n\n/**\n * Executes a cooperative refund via `refundWithSignature`.\n *\n * When `refundAuthorizerSignature` / `claimAuthorizerSignature` are present they are used\n * directly. When absent the facilitator signs the missing digests using\n * `authorizerSigner`, after verifying that `config.receiverAuthorizer` matches\n * `authorizerSigner.address`.\n *\n * If `payload.claims` is non-empty, the claim and refund are batched atomically via\n * the contract's `multicall`.\n *\n * @param signer - Facilitator signer used to submit the onchain transactions.\n * @param payload - Refund payload with optional signatures, amount, and nonce.\n * @param requirements - Payment requirements for network identification.\n * @param authorizerSigner - Dedicated key for producing EIP-712 signatures.\n * @returns A {@link SettleResponse} with the transaction hash on success.\n */\nexport async function executeRefundWithSignature(\n signer: FacilitatorEvmSigner,\n payload: BatchSettlementEnrichedRefundPayload,\n requirements: PaymentRequirements,\n authorizerSigner: AuthorizerSigner,\n): Promise<SettleResponse> {\n const network = requirements.network;\n\n try {\n const channelId = computeChannelId(payload.channelConfig, network);\n const preState = await readChannelState(signer, channelId);\n const contractAddr = getAddress(BATCH_SETTLEMENT_ADDRESS);\n const refundableAmount = getRefundableAmount(payload, preState, channelId, network);\n\n if (refundableAmount === 0n) {\n return {\n success: false,\n errorReason: Errors.ErrRefundNoBalance,\n errorMessage: \"Nothing to refund\",\n transaction: \"\",\n network,\n };\n }\n\n const hasClientSig = payload.refundAuthorizerSignature !== undefined;\n const authorizerMismatch =\n getAddress(payload.channelConfig.receiverAuthorizer) !== getAddress(authorizerSigner.address);\n\n if (!hasClientSig && authorizerMismatch) {\n return {\n success: false,\n errorReason: Errors.ErrAuthorizerAddressMismatch,\n transaction: \"\",\n network,\n };\n }\n\n const refundSig =\n payload.refundAuthorizerSignature ??\n (await signRefund(authorizerSigner, channelId, payload.amount, payload.refundNonce, network));\n\n const refundCalldata = encodeFunctionData({\n abi: batchSettlementABI,\n functionName: \"refundWithSignature\",\n args: [\n toContractChannelConfig(payload.channelConfig),\n BigInt(payload.amount),\n BigInt(payload.refundNonce),\n refundSig,\n ],\n });\n\n let tx: `0x${string}`;\n\n if (payload.claims.length > 0) {\n let claimSig = payload.claimAuthorizerSignature;\n if (!claimSig) {\n claimSig = await signClaimBatch(authorizerSigner, payload.claims, network);\n }\n\n const claimCalldata = encodeFunctionData({\n abi: batchSettlementABI,\n functionName: \"claimWithSignature\",\n args: [buildVoucherClaimArgs(payload.claims), claimSig],\n });\n\n try {\n await signer.readContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"multicall\",\n args: [[claimCalldata, refundCalldata]],\n });\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrRefundSimulationFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n\n tx = await signer.writeContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"multicall\",\n args: [[claimCalldata, refundCalldata]],\n });\n } else {\n try {\n await signer.readContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"refundWithSignature\",\n args: [\n toContractChannelConfig(payload.channelConfig),\n BigInt(payload.amount),\n BigInt(payload.refundNonce),\n refundSig,\n ],\n });\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrRefundSimulationFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n\n tx = await signer.writeContract({\n address: contractAddr,\n abi: batchSettlementABI,\n functionName: \"refundWithSignature\",\n args: [\n toContractChannelConfig(payload.channelConfig),\n BigInt(payload.amount),\n BigInt(payload.refundNonce),\n refundSig,\n ],\n });\n }\n\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrRefundTransactionFailed,\n errorMessage: `transaction reverted (receipt status ${receipt.status})`,\n transaction: tx,\n network,\n };\n }\n\n const postState =\n preState && preState.withdrawRequestedAt !== 0\n ? await readPostRefundState(signer, channelId, payload.refundNonce)\n : null;\n const refundDetails =\n preState && postState\n ? buildRefundExtraFromPostState(channelId, preState, postState)\n : buildRefundExtra(payload, channelId, preState);\n\n return {\n success: true,\n transaction: tx,\n network,\n payer: payload.channelConfig.payer,\n amount: refundDetails.amount,\n extra: refundDetails.extra,\n };\n } catch (e) {\n return {\n success: false,\n errorReason: Errors.ErrRefundTransactionFailed,\n errorMessage: e instanceof Error ? e.message : String(e),\n transaction: \"\",\n network,\n };\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@payai/x402/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { BATCH_SETTLEMENT_SCHEME } from \"../constants\";\nimport {\n isBatchSettlementDepositPayload,\n isBatchSettlementVoucherPayload,\n isBatchSettlementClaimPayload,\n isBatchSettlementSettlePayload,\n isBatchSettlementRefundPayload,\n isBatchSettlementEnrichedRefundPayload,\n} from \"../types\";\nimport type { AuthorizerSigner } from \"../types\";\nimport { verifyDeposit, settleDeposit } from \"./deposit\";\nimport { verifyVoucher } from \"./voucher\";\nimport { executeClaimWithSignature } from \"./claim\";\nimport { executeSettle } from \"./settle\";\nimport { executeRefundWithSignature } from \"./refund\";\nimport * as Errors from \"../errors\";\n\n/**\n * Facilitator-side implementation of the `batch-settlement` scheme for EVM networks.\n *\n * Routes incoming verify/settle requests to the appropriate handler based on payload\n * type (deposit, voucher, claim, settle, refund).\n */\nexport class BatchSettlementEvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = BATCH_SETTLEMENT_SCHEME;\n readonly caipFamily = \"eip155:*\";\n\n /**\n * Creates a facilitator scheme for verifying and settling batch-settlement payments.\n *\n * @param signer - Facilitator EVM signer(s) used for tx submission and onchain reads.\n * @param authorizerSigner - Dedicated key that provides EIP-712 signatures for\n * `claimWithSignature` / `refundWithSignature`. The facilitator will sign missing\n * authorizer signatures using this key when the server omits them.\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n private readonly authorizerSigner: AuthorizerSigner,\n ) {}\n\n /**\n * Returns facilitator-specific extra fields to be merged into payment requirements.\n *\n * Exposes the configured `receiverAuthorizer` address so the server and client can\n * embed it in `ChannelConfig`.\n *\n * @param _ - Network identifier (unused).\n * @returns Extra fields containing `receiverAuthorizer`.\n */\n getExtra(_: string): { receiverAuthorizer: `0x${string}` } | undefined {\n return { receiverAuthorizer: this.authorizerSigner.address };\n }\n\n /**\n * Returns all facilitator signer addresses available for the given network.\n *\n * @param _ - Network identifier (unused).\n * @returns Array of hex addresses.\n */\n getSigners(_: string): `0x${string}`[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload (deposit or voucher) without executing settlement.\n *\n * @param payload - The x402 payment payload envelope.\n * @param requirements - Server payment requirements (scheme, network, asset, amount).\n * @param context - Optional facilitator extension context.\n * @returns A {@link VerifyResponse} indicating validity with payer and channel state in `extra`.\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<VerifyResponse> {\n const rawPayload = payload.payload;\n\n if (\n payload.accepted.scheme !== BATCH_SETTLEMENT_SCHEME ||\n requirements.scheme !== BATCH_SETTLEMENT_SCHEME\n ) {\n return { isValid: false, invalidReason: Errors.ErrInvalidScheme };\n }\n\n if (payload.accepted.network !== requirements.network) {\n return { isValid: false, invalidReason: Errors.ErrNetworkMismatch };\n }\n\n if (isBatchSettlementDepositPayload(rawPayload)) {\n return verifyDeposit(this.signer, payload, rawPayload, requirements, context);\n }\n\n if (isBatchSettlementVoucherPayload(rawPayload)) {\n return verifyVoucher(this.signer, rawPayload, requirements, rawPayload.channelConfig);\n }\n\n if (isBatchSettlementRefundPayload(rawPayload)) {\n return verifyVoucher(this.signer, rawPayload, requirements, rawPayload.channelConfig);\n }\n\n return { isValid: false, invalidReason: Errors.ErrInvalidPayloadType };\n }\n\n /**\n * Executes settlement for a payment payload.\n *\n * Dispatches to the correct handler based on payload settle action:\n * - `deposit` → onchain `deposit(config, amount, collector, collectorData)`\n * - `claim` → onchain `claimWithSignature(VoucherClaim[], bytes)`\n * - `settle` → onchain `settle(receiver, token)`\n * - `refund` → optional claim + onchain `refundWithSignature(config, amount, nonce, sig)`\n *\n * @param payload - The x402 payment payload envelope.\n * @param requirements - Server payment requirements.\n * @param context - Optional facilitator extension context.\n * @returns A {@link SettleResponse} with the transaction hash on success.\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<SettleResponse> {\n const rawPayload = payload.payload;\n\n if (isBatchSettlementDepositPayload(rawPayload)) {\n return settleDeposit(this.signer, payload, rawPayload, requirements, context);\n }\n\n if (isBatchSettlementClaimPayload(rawPayload)) {\n return executeClaimWithSignature(\n this.signer,\n rawPayload,\n requirements,\n this.authorizerSigner,\n );\n }\n\n if (isBatchSettlementEnrichedRefundPayload(rawPayload)) {\n return executeRefundWithSignature(\n this.signer,\n rawPayload,\n requirements,\n this.authorizerSigner,\n );\n }\n\n if (isBatchSettlementSettlePayload(rawPayload)) {\n return executeSettle(this.signer, rawPayload, requirements);\n }\n\n return {\n success: false,\n errorReason: Errors.ErrInvalidPayloadType,\n transaction: \"\",\n network: requirements.network,\n };\n }\n}\n"],"mappings":"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","names":["getAddress","getAddress","parseErc6492Signature","getAddress","parseErc6492Signature","getAddress","getAddress","getAddress","getAddress","getAddress","encodeFunctionData","getAddress","getAddress","encodeFunctionData"]}
@@ -0,0 +1,53 @@
1
+ import { F as FileChannelStorageOptions } from '../../types-CF8P2-NM.mjs';
2
+ import { C as ChannelStorage, a as Channel, b as ChannelUpdateResult } from '../../storage-sZ1CDS4P.mjs';
3
+ import 'viem';
4
+
5
+ /**
6
+ * Node.js file-backed {@link ChannelStorage} for the batched server scheme.
7
+ */
8
+ declare class FileChannelStorage implements ChannelStorage {
9
+ private readonly root;
10
+ /**
11
+ * Creates file-backed server channel storage under the given root directory.
12
+ *
13
+ * @param options - Configuration including the storage root directory.
14
+ */
15
+ constructor(options: FileChannelStorageOptions);
16
+ /**
17
+ * Loads a persisted channel record, if present.
18
+ *
19
+ * @param channelId - The channel identifier (path segment is lowercased).
20
+ * @returns Parsed channel record or `undefined` when the file is missing.
21
+ */
22
+ get(channelId: string): Promise<Channel | undefined>;
23
+ /**
24
+ * Lists all stored channel records by reading the server directory.
25
+ *
26
+ * @returns Channel records sorted by channelId; empty array if the directory is missing.
27
+ */
28
+ list(): Promise<Channel[]>;
29
+ /**
30
+ * Atomically inspects and mutates a channel record under a cross-process file lock.
31
+ *
32
+ * @param channelId - The channel identifier.
33
+ * @param update - Mutation callback. Return `undefined` to delete, or `current` to leave unchanged.
34
+ * @returns The final stored channel and whether storage updated, stayed unchanged, or deleted.
35
+ */
36
+ updateChannel(channelId: string, update: (current: Channel | undefined) => Channel | undefined): Promise<ChannelUpdateResult>;
37
+ /**
38
+ * Absolute path to the JSON file for a channel.
39
+ *
40
+ * @param channelId - The channel identifier.
41
+ * @returns Filesystem path under `{root}/server/...`.
42
+ */
43
+ private filePath;
44
+ /**
45
+ * Creates an exclusive lock file, polling until no other process holds it.
46
+ *
47
+ * @param lockPath - Absolute path for the lock file (created with `O_EXCL`).
48
+ * @returns Writable file handle for the lock file; caller must close it to release.
49
+ */
50
+ private acquireLock;
51
+ }
52
+
53
+ export { FileChannelStorage, FileChannelStorageOptions };
@@ -0,0 +1,128 @@
1
+ import {
2
+ isNodeEnoent,
3
+ readJsonFile,
4
+ writeJsonAtomic
5
+ } from "../../chunk-2EUQTNJO.mjs";
6
+
7
+ // src/batch-settlement/server/fileStorage.ts
8
+ import { mkdir, open, readdir, readFile, unlink } from "fs/promises";
9
+ import { constants } from "fs";
10
+ import { dirname, join } from "path";
11
+ var FileChannelStorage = class {
12
+ /**
13
+ * Creates file-backed server channel storage under the given root directory.
14
+ *
15
+ * @param options - Configuration including the storage root directory.
16
+ */
17
+ constructor(options) {
18
+ this.root = options.directory;
19
+ }
20
+ /**
21
+ * Loads a persisted channel record, if present.
22
+ *
23
+ * @param channelId - The channel identifier (path segment is lowercased).
24
+ * @returns Parsed channel record or `undefined` when the file is missing.
25
+ */
26
+ async get(channelId) {
27
+ return readJsonFile(this.filePath(channelId));
28
+ }
29
+ /**
30
+ * Lists all stored channel records by reading the server directory.
31
+ *
32
+ * @returns Channel records sorted by channelId; empty array if the directory is missing.
33
+ */
34
+ async list() {
35
+ const dir = join(this.root, "server");
36
+ let names;
37
+ try {
38
+ names = await readdir(dir);
39
+ } catch (err) {
40
+ if (isNodeEnoent(err)) return [];
41
+ throw err;
42
+ }
43
+ const channels = [];
44
+ for (const name of names) {
45
+ if (!name.endsWith(".json")) continue;
46
+ const path = join(dir, name);
47
+ try {
48
+ const raw = await readFile(path, "utf8");
49
+ channels.push(JSON.parse(raw));
50
+ } catch (err) {
51
+ if (isNodeEnoent(err)) continue;
52
+ throw err;
53
+ }
54
+ }
55
+ return channels.sort((a, b) => a.channelId.localeCompare(b.channelId));
56
+ }
57
+ /**
58
+ * Atomically inspects and mutates a channel record under a cross-process file lock.
59
+ *
60
+ * @param channelId - The channel identifier.
61
+ * @param update - Mutation callback. Return `undefined` to delete, or `current` to leave unchanged.
62
+ * @returns The final stored channel and whether storage updated, stayed unchanged, or deleted.
63
+ */
64
+ async updateChannel(channelId, update) {
65
+ const lockPath = this.filePath(channelId) + ".lock";
66
+ await mkdir(dirname(lockPath), { recursive: true });
67
+ const lockHandle = await this.acquireLock(lockPath);
68
+ try {
69
+ const path = this.filePath(channelId);
70
+ let current;
71
+ try {
72
+ const raw = await readFile(path, "utf8");
73
+ current = JSON.parse(raw);
74
+ } catch (err) {
75
+ if (!isNodeEnoent(err)) throw err;
76
+ }
77
+ const next = update(current);
78
+ if (next === current) {
79
+ return { channel: current, status: "unchanged" };
80
+ }
81
+ if (!next) {
82
+ try {
83
+ await unlink(path);
84
+ } catch (err) {
85
+ if (!isNodeEnoent(err)) throw err;
86
+ }
87
+ return { channel: void 0, status: current ? "deleted" : "unchanged" };
88
+ }
89
+ await writeJsonAtomic(path, next);
90
+ return { channel: next, status: "updated" };
91
+ } finally {
92
+ await lockHandle.close();
93
+ await unlink(lockPath).catch(() => {
94
+ });
95
+ }
96
+ }
97
+ /**
98
+ * Absolute path to the JSON file for a channel.
99
+ *
100
+ * @param channelId - The channel identifier.
101
+ * @returns Filesystem path under `{root}/server/...`.
102
+ */
103
+ filePath(channelId) {
104
+ return join(this.root, "server", `${channelId.toLowerCase()}.json`);
105
+ }
106
+ /**
107
+ * Creates an exclusive lock file, polling until no other process holds it.
108
+ *
109
+ * @param lockPath - Absolute path for the lock file (created with `O_EXCL`).
110
+ * @returns Writable file handle for the lock file; caller must close it to release.
111
+ */
112
+ async acquireLock(lockPath) {
113
+ while (true) {
114
+ try {
115
+ return await open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
116
+ } catch (err) {
117
+ if (err.code !== "EEXIST") {
118
+ throw err;
119
+ }
120
+ await new Promise((resolve) => setTimeout(resolve, 10));
121
+ }
122
+ }
123
+ }
124
+ };
125
+ export {
126
+ FileChannelStorage
127
+ };
128
+ //# sourceMappingURL=file-storage.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/batch-settlement/server/fileStorage.ts"],"sourcesContent":["import { mkdir, open, readdir, readFile, unlink } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { isNodeEnoent, readJsonFile, writeJsonAtomic } from \"../storage-utils\";\nimport type { FileChannelStorageOptions } from \"../types\";\nimport type { ChannelStorage, Channel, ChannelUpdateResult } from \"./storage\";\n\nexport type { FileChannelStorageOptions };\n\n/**\n * Node.js file-backed {@link ChannelStorage} for the batched server scheme.\n */\nexport class FileChannelStorage implements ChannelStorage {\n private readonly root: string;\n\n /**\n * Creates file-backed server channel storage under the given root directory.\n *\n * @param options - Configuration including the storage root directory.\n */\n constructor(options: FileChannelStorageOptions) {\n this.root = options.directory;\n }\n\n /**\n * Loads a persisted channel record, if present.\n *\n * @param channelId - The channel identifier (path segment is lowercased).\n * @returns Parsed channel record or `undefined` when the file is missing.\n */\n async get(channelId: string): Promise<Channel | undefined> {\n return readJsonFile<Channel>(this.filePath(channelId));\n }\n\n /**\n * Lists all stored channel records by reading the server directory.\n *\n * @returns Channel records sorted by channelId; empty array if the directory is missing.\n */\n async list(): Promise<Channel[]> {\n const dir = join(this.root, \"server\");\n let names: string[];\n try {\n names = await readdir(dir);\n } catch (err: unknown) {\n if (isNodeEnoent(err)) return [];\n throw err;\n }\n\n const channels: Channel[] = [];\n for (const name of names) {\n if (!name.endsWith(\".json\")) continue;\n const path = join(dir, name);\n try {\n const raw = await readFile(path, \"utf8\");\n channels.push(JSON.parse(raw) as Channel);\n } catch (err: unknown) {\n // Skip files that disappeared between readdir and readFile (e.g. concurrent delete).\n // Rethrow other failures (corrupt JSON, permission denied) so callers see them.\n if (isNodeEnoent(err)) continue;\n throw err;\n }\n }\n return channels.sort((a, b) => a.channelId.localeCompare(b.channelId));\n }\n\n /**\n * Atomically inspects and mutates a channel record under a cross-process file lock.\n *\n * @param channelId - The channel identifier.\n * @param update - Mutation callback. Return `undefined` to delete, or `current` to leave unchanged.\n * @returns The final stored channel and whether storage updated, stayed unchanged, or deleted.\n */\n async updateChannel(\n channelId: string,\n update: (current: Channel | undefined) => Channel | undefined,\n ): Promise<ChannelUpdateResult> {\n const lockPath = this.filePath(channelId) + \".lock\";\n await mkdir(dirname(lockPath), { recursive: true });\n const lockHandle = await this.acquireLock(lockPath);\n\n try {\n const path = this.filePath(channelId);\n let current: Channel | undefined;\n try {\n const raw = await readFile(path, \"utf8\");\n current = JSON.parse(raw) as Channel;\n } catch (err: unknown) {\n if (!isNodeEnoent(err)) throw err;\n }\n\n const next = update(current);\n if (next === current) {\n return { channel: current, status: \"unchanged\" };\n }\n\n if (!next) {\n try {\n await unlink(path);\n } catch (err: unknown) {\n if (!isNodeEnoent(err)) throw err;\n }\n return { channel: undefined, status: current ? \"deleted\" : \"unchanged\" };\n }\n\n await writeJsonAtomic(path, next);\n return { channel: next, status: \"updated\" };\n } finally {\n await lockHandle.close();\n await unlink(lockPath).catch(() => {});\n }\n }\n\n /**\n * Absolute path to the JSON file for a channel.\n *\n * @param channelId - The channel identifier.\n * @returns Filesystem path under `{root}/server/...`.\n */\n private filePath(channelId: string): string {\n return join(this.root, \"server\", `${channelId.toLowerCase()}.json`);\n }\n\n /**\n * Creates an exclusive lock file, polling until no other process holds it.\n *\n * @param lockPath - Absolute path for the lock file (created with `O_EXCL`).\n * @returns Writable file handle for the lock file; caller must close it to release.\n */\n private async acquireLock(lockPath: string) {\n while (true) {\n try {\n return await open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw err;\n }\n await new Promise(resolve => setTimeout(resolve, 10));\n }\n }\n }\n}\n"],"mappings":"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","names":[]}