@payai/x402-evm 2.4.1 → 2.4.2

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/client/voucher.ts","../../src/batch-settlement/client/eip3009.ts","../../src/batch-settlement/client/storage.ts","../../src/batch-settlement/client/config.ts","../../src/batch-settlement/client/channel.ts","../../src/batch-settlement/client/recovery.ts","../../src/batch-settlement/client/hooks.ts","../../src/batch-settlement/client/refund.ts","../../src/batch-settlement/client/scheme.ts","../../src/batch-settlement/client/permit2.ts"],"sourcesContent":["import { ClientEvmSigner } from \"../../signer\";\nimport { voucherTypes } from \"../constants\";\nimport { BatchSettlementVoucherFields } from \"../types\";\nimport { getEvmChainId } from \"../../utils\";\nimport { getBatchSettlementEip712Domain } from \"../utils\";\n\n/**\n * Signs a cumulative voucher using the client's wallet.\n *\n * The voucher authorises the receiver to claim up to `maxClaimableAmount` from the\n * channel identified by `channelId`. The signature covers the EIP-712 `Voucher` struct\n * under the batched domain.\n *\n * @param signer - Client wallet used to produce the EIP-712 signature.\n * @param channelId - Identifier of the payment channel. This is the EIP-712\n * hash of the `ChannelConfig` typed data for the batch settlement domain; see\n * `computeChannelId`.\n * @param maxClaimableAmount - Cumulative ceiling the receiver may claim (decimal string in token units).\n * @param network - CAIP-2 network identifier (e.g. `eip155:84532`).\n * @returns Signed voucher fields ready to be included in a payment payload.\n */\nexport async function signVoucher(\n signer: ClientEvmSigner,\n channelId: `0x${string}`,\n maxClaimableAmount: string,\n network: string,\n): Promise<BatchSettlementVoucherFields> {\n const chainId = getEvmChainId(network);\n\n const signature = await signer.signTypedData({\n domain: getBatchSettlementEip712Domain(chainId),\n types: voucherTypes,\n primaryType: \"Voucher\",\n message: {\n channelId,\n maxClaimableAmount: BigInt(maxClaimableAmount),\n },\n });\n\n return {\n channelId,\n maxClaimableAmount,\n signature,\n };\n}\n","import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ChannelConfig, BatchSettlementDepositPayload } from \"../types\";\nimport { ERC3009_DEPOSIT_COLLECTOR_ADDRESS, receiveAuthorizationTypes } from \"../constants\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\nimport { signVoucher } from \"./voucher\";\nimport { computeChannelId } from \"../utils\";\nimport { buildErc3009DepositNonce } from \"../encoding\";\n\n/**\n * Creates a deposit payload that bundles an ERC-3009 `receiveWithAuthorization` approval\n * together with a cumulative voucher signature.\n *\n * When the facilitator submits this payload onchain, the contract atomically transfers\n * tokens from the payer into the channel and records the initial voucher.\n *\n * @param signer - Client wallet used to sign the ERC-3009 authorization (`from` = payer).\n * @param x402Version - Protocol version to embed in the payload envelope.\n * @param paymentRequirements - Server-provided payment requirements (asset, network, amount, etc.).\n * @param channelConfig - Immutable channel configuration (payer, receiver, token, …).\n * @param depositAmount - Number of tokens (decimal string) to deposit into the channel.\n * @param maxClaimableAmount - Cumulative ceiling for the accompanying voucher.\n * @param voucherSigner - Optional key that signs the voucher; defaults to `signer` (same as payer).\n * @returns A {@link PaymentPayloadResult} containing the signed deposit + voucher payload.\n */\nexport async function createBatchSettlementEIP3009DepositPayload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n channelConfig: ChannelConfig,\n depositAmount: string,\n maxClaimableAmount: string,\n voucherSigner?: ClientEvmSigner,\n): Promise<PaymentPayloadResult> {\n const salt = createNonce();\n const now = Math.floor(Date.now() / 1000);\n const chainId = getEvmChainId(paymentRequirements.network);\n\n if (!paymentRequirements.extra?.name || !paymentRequirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${paymentRequirements.asset}`,\n );\n }\n\n const { name, version } = paymentRequirements.extra;\n\n const channelId = computeChannelId(channelConfig, paymentRequirements.network);\n\n const erc3009Nonce = buildErc3009DepositNonce(channelId, salt);\n\n const signature = await signer.signTypedData({\n domain: {\n name,\n version,\n chainId,\n verifyingContract: getAddress(paymentRequirements.asset),\n },\n types: receiveAuthorizationTypes,\n primaryType: \"ReceiveWithAuthorization\",\n message: {\n from: getAddress(signer.address),\n to: getAddress(ERC3009_DEPOSIT_COLLECTOR_ADDRESS),\n value: BigInt(depositAmount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + paymentRequirements.maxTimeoutSeconds),\n nonce: erc3009Nonce,\n },\n });\n\n const vSigner = voucherSigner ?? signer;\n const voucher = await signVoucher(\n vSigner,\n channelId,\n maxClaimableAmount,\n paymentRequirements.network,\n );\n\n const payload: BatchSettlementDepositPayload = {\n type: \"deposit\",\n channelConfig,\n voucher,\n deposit: {\n amount: depositAmount,\n authorization: {\n erc3009Authorization: {\n validAfter: (now - 600).toString(),\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n salt,\n signature,\n },\n },\n },\n };\n\n return {\n x402Version,\n payload,\n };\n}\n","/**\n * Client-side channel fields mirrored from PAYMENT-RESPONSE / recovery flows.\n */\nexport interface BatchSettlementClientContext {\n /** Current cumulative amount charged by the server for this channel */\n chargedCumulativeAmount?: string;\n /** Current onchain channel balance */\n balance?: string;\n /** Total claimed onchain */\n totalClaimed?: string;\n /** Latest client-signed maxClaimableAmount cap (after corrective recovery, optional) */\n signedMaxClaimable?: string;\n /** Client voucher signature for {@link signedMaxClaimable} (optional) */\n signature?: `0x${string}`;\n}\n\nexport interface ClientChannelStorage {\n get(key: string): Promise<BatchSettlementClientContext | undefined>;\n set(key: string, context: BatchSettlementClientContext): Promise<void>;\n delete(key: string): Promise<void>;\n}\n\n/**\n * Default in-memory {@link ClientChannelStorage} (channel records do not survive process restart).\n */\nexport class InMemoryClientChannelStorage implements ClientChannelStorage {\n private readonly channels = new Map<string, BatchSettlementClientContext>();\n\n /**\n * Returns the channel record for `key` if present.\n *\n * @param key - Channel storage key (channelId).\n * @returns Persisted context or undefined.\n */\n async get(key: string): Promise<BatchSettlementClientContext | undefined> {\n return this.channels.get(key);\n }\n\n /**\n * Stores or replaces the channel record for `key`.\n *\n * @param key - Channel storage key.\n * @param context - Channel fields to persist.\n * @returns Resolves when stored.\n */\n async set(key: string, context: BatchSettlementClientContext): Promise<void> {\n this.channels.set(key, context);\n }\n\n /**\n * Removes the channel record for `key` if it exists.\n *\n * @param key - Channel storage key.\n * @returns Resolves when removed.\n */\n async delete(key: string): Promise<void> {\n this.channels.delete(key);\n }\n}\n","import type { PaymentRequirements } from \"@payai/x402/types\";\nimport type { ClientEvmSigner } from \"../../signer\";\nimport type { EvmSchemeOptions } from \"../../shared/rpc\";\nimport type { ChannelConfig } from \"../types\";\nimport { type ClientChannelStorage, InMemoryClientChannelStorage } from \"./storage\";\nimport type { BatchSettlementClientContext } from \"./storage\";\n\nconst DEFAULT_SALT =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\" as `0x${string}`;\n\n/**\n * Caller-tunable policy controlling how the client sizes channel deposits.\n */\nexport interface BatchSettlementDepositPolicy {\n depositMultiplier?: number;\n}\n\n/**\n * Return shape for custom deposit sizing.\n */\nexport type BatchSettlementDepositStrategyResult = string | bigint | false | undefined;\n\n/**\n * Information supplied before the client signs a deposit authorization.\n */\nexport interface BatchSettlementDepositStrategyContext {\n paymentRequirements: PaymentRequirements;\n channelConfig: ChannelConfig;\n channelId: `0x${string}`;\n clientContext: BatchSettlementClientContext;\n requestAmount: string;\n maxClaimableAmount: string;\n currentBalance: string;\n minimumDepositAmount: string;\n depositAmount: string;\n}\n\n/**\n * Custom deposit sizing callback for initial deposits and top-ups.\n */\nexport type BatchSettlementDepositStrategy = (\n context: BatchSettlementDepositStrategyContext,\n) => BatchSettlementDepositStrategyResult | Promise<BatchSettlementDepositStrategyResult>;\n\n/**\n * Full options object accepted by `BatchSettlementEvmScheme`. Either this or a\n * bare {@link BatchSettlementDepositPolicy} can be passed as the second\n * constructor argument.\n */\nexport interface BatchSettlementEvmSchemeOptions {\n depositPolicy?: BatchSettlementDepositPolicy;\n /** Optional callback for app-specific deposit sizing or skipping. */\n depositStrategy?: BatchSettlementDepositStrategy;\n storage?: ClientChannelStorage;\n salt?: `0x${string}`;\n payerAuthorizer?: `0x${string}`;\n rpcUrl?: string;\n /** When set, EIP-712 vouchers are signed with this key; deposits still use the main `signer`. */\n voucherSigner?: ClientEvmSigner;\n}\n\n/**\n * Resolved options after merging defaults — used internally by the scheme,\n * recovery, and refund modules.\n */\nexport interface ResolvedClientOptions {\n depositPolicy?: BatchSettlementDepositPolicy;\n depositStrategy?: BatchSettlementDepositStrategy;\n storage: ClientChannelStorage;\n salt: `0x${string}`;\n payerAuthorizer?: `0x${string}`;\n voucherSigner?: ClientEvmSigner;\n extensionRpcOptions?: EvmSchemeOptions;\n}\n\n/**\n * Discriminates a full options object from a bare deposit-policy object.\n *\n * @param o - Constructor argument that may be options, deposit policy only, or undefined.\n * @returns `true` when `o` is a {@link BatchSettlementEvmSchemeOptions} object.\n */\nexport function isBatchSettlementEvmSchemeOptions(\n o: BatchSettlementEvmSchemeOptions | BatchSettlementDepositPolicy | undefined,\n): o is BatchSettlementEvmSchemeOptions {\n return (\n o !== undefined &&\n typeof o === \"object\" &&\n (\"storage\" in o ||\n \"depositPolicy\" in o ||\n \"depositStrategy\" in o ||\n \"salt\" in o ||\n \"payerAuthorizer\" in o ||\n \"rpcUrl\" in o ||\n \"voucherSigner\" in o)\n );\n}\n\n/**\n * Normalises the constructor's second argument into a uniform options shape.\n *\n * @param second - Optional second constructor argument (options or deposit policy).\n * @returns Resolved storage, salt, deposit policy, and optional payer authorizer.\n */\nexport function resolveClientOptions(\n second?: BatchSettlementEvmSchemeOptions | BatchSettlementDepositPolicy,\n): ResolvedClientOptions {\n if (second === undefined) {\n return { storage: new InMemoryClientChannelStorage(), salt: DEFAULT_SALT };\n }\n if (isBatchSettlementEvmSchemeOptions(second)) {\n return {\n storage: second.storage ?? new InMemoryClientChannelStorage(),\n depositPolicy: second.depositPolicy,\n depositStrategy: second.depositStrategy,\n salt: second.salt ?? DEFAULT_SALT,\n payerAuthorizer: second.payerAuthorizer,\n voucherSigner: second.voucherSigner,\n extensionRpcOptions: second.rpcUrl ? { rpcUrl: second.rpcUrl } : undefined,\n };\n }\n return {\n storage: new InMemoryClientChannelStorage(),\n depositPolicy: second,\n salt: DEFAULT_SALT,\n };\n}\n\n/**\n * Validates a {@link BatchSettlementDepositPolicy}, throwing on invalid fields.\n *\n * @param policy - The policy to validate (no-op when undefined).\n */\nexport function validateDepositPolicy(policy: BatchSettlementDepositPolicy | undefined): void {\n if (!policy) return;\n\n const m = policy.depositMultiplier;\n if (m !== undefined && (!Number.isInteger(m) || m < 3)) {\n throw new Error(\"depositMultiplier must be an integer >= 3\");\n }\n}\n\n/**\n * Computes the deposit amount based on the deposit multiplier.\n *\n * @param policy - Deposit policy controlling multiplier (may be undefined).\n * @param requestAmount - Amount requested for this operation, in token base units.\n * @returns Deposit amount string in token base units.\n */\nexport function depositAmountForRequest(\n policy: BatchSettlementDepositPolicy | undefined,\n requestAmount: bigint,\n): string {\n const mult = BigInt(policy?.depositMultiplier ?? 5);\n return (mult * requestAmount).toString();\n}\n","import { decodePaymentResponseHeader } from \"@payai/x402/http\";\nimport type { PaymentRequirements, SettleResponse } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport type { ClientEvmSigner } from \"../../signer\";\nimport { batchSettlementABI } from \"../abi\";\nimport { BATCH_SETTLEMENT_ADDRESS, MIN_WITHDRAW_DELAY } from \"../constants\";\nimport type {\n BatchSettlementPaymentRequirementsExtra,\n BatchSettlementPaymentResponseExtra,\n ChannelConfig,\n} from \"../types\";\nimport { computeChannelId } from \"../utils\";\nimport type { BatchSettlementClientContext, ClientChannelStorage } from \"./storage\";\n\ntype ResponseChannelState = NonNullable<BatchSettlementPaymentResponseExtra[\"channelState\"]>;\n\n/**\n * Reads the nested channel state from a settlement response extra object.\n *\n * @param extra - Settlement response extra fields.\n * @returns Channel state fields, or undefined when absent.\n */\nfunction readResponseChannelState(\n extra: Record<string, unknown>,\n): ResponseChannelState | undefined {\n const channelState = extra.channelState;\n if (typeof channelState !== \"object\" || channelState === null) {\n return undefined;\n }\n return channelState as ResponseChannelState;\n}\n\n/**\n * Runtime dependency bag shared by every storage-bound client helper (channel,\n * recovery, refund) and the {@link BatchSettlementEvmScheme} class.\n */\nexport interface BatchSettlementClientDeps {\n signer: ClientEvmSigner;\n storage: ClientChannelStorage;\n salt: `0x${string}`;\n payerAuthorizer?: `0x${string}`;\n voucherSigner?: ClientEvmSigner;\n}\n\n/**\n * Constructs the immutable {@link ChannelConfig} from payment requirements and\n * a client deps bag (signer, salt, optional payerAuthorizer / voucherSigner).\n *\n * @param deps - Client identity inputs.\n * @param paymentRequirements - Server payment requirements providing receiver, asset, and extra fields.\n * @returns The ChannelConfig that uniquely identifies this payment channel.\n */\nexport function buildChannelConfig(\n deps: BatchSettlementClientDeps,\n paymentRequirements: PaymentRequirements,\n): ChannelConfig {\n const extra = paymentRequirements.extra as\n | Partial<BatchSettlementPaymentRequirementsExtra>\n | undefined;\n const receiverAuthorizer = extra?.receiverAuthorizer;\n if (\n !receiverAuthorizer ||\n getAddress(receiverAuthorizer) === \"0x0000000000000000000000000000000000000000\"\n ) {\n throw new Error(\"Payment requirements must include a non-zero extra.receiverAuthorizer\");\n }\n\n return {\n payer: deps.signer.address,\n payerAuthorizer: getAddress(\n deps.payerAuthorizer ?? deps.voucherSigner?.address ?? deps.signer.address,\n ),\n receiver: paymentRequirements.payTo as `0x${string}`,\n receiverAuthorizer: getAddress(receiverAuthorizer),\n token: paymentRequirements.asset as `0x${string}`,\n withdrawDelay:\n typeof extra?.withdrawDelay === \"number\" ? extra.withdrawDelay : MIN_WITHDRAW_DELAY,\n salt: deps.salt,\n };\n}\n\n/**\n * Updates local channel state from a parsed `SettleResponse`.\n *\n * @param storage - Client channel storage.\n * @param settle - The parsed settle response.\n */\nexport async function processSettleResponse(\n storage: ClientChannelStorage,\n settle: SettleResponse,\n): Promise<void> {\n const extra = settle.extra ?? {};\n const channelState = readResponseChannelState(extra);\n if (!channelState) return;\n\n const channelId = channelState.channelId;\n const key = channelId.toLowerCase();\n\n const prev = await storage.get(key);\n const next: BatchSettlementClientContext = { ...(prev ?? {}) };\n\n if (channelState.chargedCumulativeAmount !== undefined) {\n next.chargedCumulativeAmount = String(channelState.chargedCumulativeAmount);\n }\n if (channelState.balance !== undefined) {\n next.balance = String(channelState.balance);\n }\n if (channelState.totalClaimed !== undefined) {\n next.totalClaimed = String(channelState.totalClaimed);\n }\n\n await storage.set(key, next);\n}\n\n/**\n * Reconciles local channel state with the outcome of a cooperative refund.\n *\n * Deletes the channel record when the post-refund balance is zero (full refund),\n * otherwise updates local state from the server snapshot.\n *\n * @param storage - Client channel storage.\n * @param channelKey - Lowercased channel id used as the storage key.\n * @param settleExtra - The `extra` block from the refund settle response.\n */\nexport async function updateChannelAfterRefund(\n storage: ClientChannelStorage,\n channelKey: string,\n settleExtra: Record<string, unknown>,\n): Promise<void> {\n const channelState = readResponseChannelState(settleExtra);\n if (!channelState) {\n await storage.delete(channelKey);\n return;\n }\n\n const balanceAfter =\n channelState.balance !== undefined ? BigInt(String(channelState.balance)) : undefined;\n\n if (balanceAfter === undefined || balanceAfter <= 0n) {\n await storage.delete(channelKey);\n return;\n }\n\n const prev = await storage.get(channelKey);\n const next: BatchSettlementClientContext = { ...(prev ?? {}) };\n next.balance = balanceAfter.toString();\n if (channelState.chargedCumulativeAmount !== undefined) {\n next.chargedCumulativeAmount = String(channelState.chargedCumulativeAmount);\n }\n if (channelState.totalClaimed !== undefined) {\n next.totalClaimed = String(channelState.totalClaimed);\n }\n await storage.set(channelKey, next);\n}\n\n/**\n * Processes the `PAYMENT-RESPONSE` header after a successful request.\n *\n * Decodes the header into a `SettleResponse` and delegates to\n * {@link processSettleResponse}.\n *\n * @param storage - Client channel storage.\n * @param getHeader - Function to retrieve a response header by name.\n */\nexport async function processPaymentResponse(\n storage: ClientChannelStorage,\n getHeader: (name: string) => string | null | undefined,\n): Promise<void> {\n const raw = getHeader(\"PAYMENT-RESPONSE\");\n if (!raw) return;\n\n const settle = decodePaymentResponseHeader(raw);\n await processSettleResponse(storage, settle);\n}\n\n/**\n * Recovers a channel record from onchain state (useful after a cold start or\n * channel record loss).\n *\n * @param deps - Signer + storage + identity inputs.\n * @param paymentRequirements - Server payment requirements used to derive the ChannelConfig.\n * @returns The recovered client context.\n */\nexport async function recoverChannel(\n deps: BatchSettlementClientDeps,\n paymentRequirements: PaymentRequirements,\n): Promise<BatchSettlementClientContext> {\n if (!deps.signer.readContract) {\n throw new Error(\"recoverChannel requires ClientEvmSigner.readContract\");\n }\n\n const config = buildChannelConfig(deps, paymentRequirements);\n const channelId = computeChannelId(config, paymentRequirements.network);\n\n const [chBalance, chTotalClaimed] = await readChannelBalanceAndTotalClaimed(\n deps.signer,\n channelId,\n );\n\n const ctx: BatchSettlementClientContext = {\n chargedCumulativeAmount: chTotalClaimed.toString(),\n balance: chBalance.toString(),\n totalClaimed: chTotalClaimed.toString(),\n };\n\n await deps.storage.set(channelId.toLowerCase(), ctx);\n return ctx;\n}\n\n/**\n * Reads `channels(channelId)` returning `[balance, totalClaimed]`.\n *\n * @param signer - Signer providing `readContract`.\n * @param channelId - The `bytes32` channel id to query.\n * @returns Tuple of `[balance, totalClaimed]` as bigints.\n */\nexport async function readChannelBalanceAndTotalClaimed(\n signer: ClientEvmSigner,\n channelId: `0x${string}`,\n): Promise<[bigint, bigint]> {\n if (!signer.readContract) {\n throw new Error(\"readChannelBalanceAndTotalClaimed requires ClientEvmSigner.readContract\");\n }\n return (await signer.readContract({\n address: BATCH_SETTLEMENT_ADDRESS,\n abi: batchSettlementABI,\n functionName: \"channels\",\n args: [channelId],\n })) as [bigint, bigint];\n}\n\n/**\n * Returns whether a local channel record exists for the given channel.\n *\n * @param storage - Client channel storage.\n * @param channelId - The channel identifier to check.\n * @returns `true` when a channel record is stored.\n */\nexport async function hasChannel(\n storage: ClientChannelStorage,\n channelId: string,\n): Promise<boolean> {\n const channel = await storage.get(channelId.toLowerCase());\n return channel !== undefined;\n}\n\n/**\n * Returns the local channel context for a channel, if present.\n *\n * @param storage - Client channel storage.\n * @param channelId - The channel identifier.\n * @returns Stored context or `undefined`.\n */\nexport async function getChannel(\n storage: ClientChannelStorage,\n channelId: string,\n): Promise<BatchSettlementClientContext | undefined> {\n return storage.get(channelId.toLowerCase());\n}\n","import type { PaymentRequired, PaymentRequirements } from \"@payai/x402/types\";\nimport { getAddress, recoverTypedDataAddress } from \"viem\";\nimport { BATCH_SETTLEMENT_SCHEME, voucherTypes } from \"../constants\";\nimport type { BatchSettlementClientContext } from \"./storage\";\nimport { computeChannelId, getBatchSettlementEip712Domain } from \"../utils\";\nimport { getEvmChainId } from \"../../utils\";\nimport {\n type BatchSettlementClientDeps,\n buildChannelConfig,\n readChannelBalanceAndTotalClaimed,\n} from \"./channel\";\nimport * as Errors from \"../errors\";\nimport type { BatchSettlementChannelStateExtra, BatchSettlementVoucherStateExtra } from \"../types\";\n\n/**\n * Handles a corrective 402 response from the server when the client's\n * cumulative base is out of sync.\n *\n * Validates the server-provided state (chargedCumulativeAmount,\n * signedMaxClaimable, signature) against onchain data and the client's own\n * signing key, then updates the local channel state if everything checks out.\n *\n * @param deps - Signer + storage + identity inputs.\n * @param paymentRequired - The decoded 402 response body.\n * @returns `true` if the channel state was successfully resynced and the request can be retried.\n */\nexport async function processCorrectivePaymentRequired(\n deps: BatchSettlementClientDeps,\n paymentRequired: PaymentRequired,\n): Promise<boolean> {\n if (\n paymentRequired.error !== Errors.ErrCumulativeAmountMismatch &&\n paymentRequired.error !== Errors.ErrCumulativeAmountBelowClaimed\n ) {\n return false;\n }\n\n const accept = paymentRequired.accepts.find(a => a.scheme === BATCH_SETTLEMENT_SCHEME);\n if (!accept) {\n return false;\n }\n\n const channelState = accept.extra.channelState as BatchSettlementChannelStateExtra | undefined;\n const voucherState = accept.extra.voucherState as BatchSettlementVoucherStateExtra | undefined;\n const hasSig =\n channelState?.chargedCumulativeAmount !== undefined &&\n voucherState?.signedMaxClaimable !== undefined &&\n voucherState.signature !== undefined;\n\n if (!hasSig) {\n return recoverFromOnChainState(deps, accept);\n }\n\n return recoverFromSignature(deps, accept, channelState, voucherState);\n}\n\n/**\n * Recovers channel state from a corrective 402 that includes a server-provided\n * voucher signature. Verifies the signature matches the client's own signing\n * key before accepting.\n *\n * @param deps - Signer + storage + identity inputs.\n * @param accept - Batch settlement payment requirements from the corrective 402.\n * @param channelState - Server channel snapshot from `accept.extra.channelState`.\n * @param voucherState - Latest signed voucher proof from `accept.extra.voucherState`.\n * @returns `true` when local channel state was updated successfully.\n */\nexport async function recoverFromSignature(\n deps: BatchSettlementClientDeps,\n accept: PaymentRequirements,\n channelState: BatchSettlementChannelStateExtra,\n voucherState: BatchSettlementVoucherStateExtra,\n): Promise<boolean> {\n const chargedRaw = channelState.chargedCumulativeAmount;\n const signedRaw = voucherState.signedMaxClaimable;\n const sig = voucherState.signature as `0x${string}`;\n\n const charged = BigInt(String(chargedRaw));\n const signed = BigInt(String(signedRaw));\n\n if (charged > signed) {\n return false;\n }\n\n const config = buildChannelConfig(deps, accept);\n const channelId = computeChannelId(config, accept.network);\n\n if (!deps.signer.readContract) {\n return false;\n }\n\n const [chBalance, chTotalClaimed] = await readChannelBalanceAndTotalClaimed(\n deps.signer,\n channelId,\n );\n\n if (charged < chTotalClaimed) {\n return false;\n }\n\n const chainId = getEvmChainId(accept.network);\n const recovered = await recoverTypedDataAddress({\n domain: getBatchSettlementEip712Domain(chainId),\n types: voucherTypes,\n primaryType: \"Voucher\",\n message: {\n channelId,\n maxClaimableAmount: signed,\n },\n signature: sig,\n });\n\n const expectedSigner = getAddress(\n deps.payerAuthorizer ?? deps.voucherSigner?.address ?? deps.signer.address,\n );\n if (recovered.toLowerCase() !== expectedSigner.toLowerCase()) {\n return false;\n }\n\n const ctx: BatchSettlementClientContext = {\n chargedCumulativeAmount: charged.toString(),\n signedMaxClaimable: signed.toString(),\n signature: sig,\n balance: chBalance.toString(),\n totalClaimed: chTotalClaimed.toString(),\n };\n\n await deps.storage.set(channelId.toLowerCase(), ctx);\n return true;\n}\n\n/**\n * Recovers channel state purely from onchain state when the server has no stored\n * voucher (e.g. after a cooperative refund deleted the channel record). The onchain\n * `totalClaimed` becomes the new baseline — no signature verification is\n * needed because the contract is the source of truth when no outstanding\n * voucher exists.\n *\n * @param deps - Signer + storage + identity inputs.\n * @param accept - Batch settlement payment requirements from the corrective 402.\n * @returns `true` when local channel state was updated from onchain data.\n */\nexport async function recoverFromOnChainState(\n deps: BatchSettlementClientDeps,\n accept: PaymentRequirements,\n): Promise<boolean> {\n if (!deps.signer.readContract) {\n return false;\n }\n\n const config = buildChannelConfig(deps, accept);\n const channelId = computeChannelId(config, accept.network);\n\n const [chBalance, chTotalClaimed] = await readChannelBalanceAndTotalClaimed(\n deps.signer,\n channelId,\n );\n\n const ctx: BatchSettlementClientContext = {\n chargedCumulativeAmount: chTotalClaimed.toString(),\n balance: chBalance.toString(),\n totalClaimed: chTotalClaimed.toString(),\n };\n\n await deps.storage.set(channelId.toLowerCase(), ctx);\n return true;\n}\n","import type { PaymentResponseContext } from \"@payai/x402/client\";\nimport type { SchemeClientHooks } from \"@payai/x402/types\";\nimport { isBatchSettlementRefundPayload } from \"../types\";\nimport type { BatchSettlementClientDeps } from \"./channel\";\nimport { processSettleResponse, updateChannelAfterRefund } from \"./channel\";\nimport { processCorrectivePaymentRequired } from \"./recovery\";\n\n/**\n * Creates storage-aware client hooks for batch-settlement payment responses.\n *\n * @param deps - Client identity and storage inputs.\n * @returns Scheme hooks for response reconciliation and corrective recovery.\n */\nexport function createBatchSettlementClientHooks(\n deps: BatchSettlementClientDeps,\n): SchemeClientHooks {\n return {\n onPaymentResponse: ctx => handleBatchSettlementPaymentResponse(deps, ctx),\n };\n}\n\n/**\n * Reconciles batch-settlement client state after a paid request or refund attempt.\n *\n * @param deps - Client identity and storage inputs.\n * @param ctx - Core payment response context.\n * @returns A recovery signal when corrective recovery succeeds.\n */\nexport async function handleBatchSettlementPaymentResponse(\n deps: BatchSettlementClientDeps,\n ctx: PaymentResponseContext,\n): Promise<void | { recovered: true }> {\n if (ctx.settleResponse) {\n if (isBatchSettlementRefundPayload(ctx.paymentPayload.payload)) {\n const extra = ctx.settleResponse.extra ?? {};\n const channelState = extra.channelState;\n const channelId =\n typeof channelState === \"object\" && channelState !== null && \"channelId\" in channelState\n ? channelState.channelId\n : undefined;\n if (typeof channelId === \"string\" && channelId) {\n await updateChannelAfterRefund(deps.storage, channelId.toLowerCase(), extra);\n }\n return;\n }\n\n await processSettleResponse(deps.storage, ctx.settleResponse);\n return;\n }\n\n if (ctx.paymentRequired) {\n const recovered = await processCorrectivePaymentRequired(deps, ctx.paymentRequired);\n return recovered ? { recovered: true } : undefined;\n }\n}\n","import { decodePaymentRequiredHeader, decodePaymentResponseHeader } from \"@payai/x402/http\";\nimport { x402Client, x402HTTPClient } from \"@payai/x402/client\";\nimport type {\n PaymentPayload,\n PaymentRequired,\n PaymentRequirements,\n SettleResponse,\n} from \"@payai/x402/types\";\nimport { BATCH_SETTLEMENT_SCHEME } from \"../constants\";\nimport * as Errors from \"../errors\";\nimport type {\n BatchSettlementPaymentRequirementsExtra,\n BatchSettlementRefundPayload,\n} from \"../types\";\nimport { computeChannelId } from \"../utils\";\nimport { type BatchSettlementClientDeps, buildChannelConfig, recoverChannel } from \"./channel\";\nimport { createBatchSettlementClientHooks } from \"./hooks\";\nimport { signVoucher } from \"./voucher\";\n\n/**\n * Refund-specific server errors that the client cannot recover from automatically.\n * Seeing any of these means the user should adjust their request (or accept that the\n * channel has nothing left to refund) — retrying will not help.\n */\nconst NON_RECOVERABLE_REFUND_ERRORS: ReadonlySet<string> = new Set([\n Errors.ErrRefundNoBalance,\n Errors.ErrRefundAmountInvalid,\n]);\n\ninterface RefundRequirementsProbe {\n paymentRequired: PaymentRequired;\n requirements: PaymentRequirements;\n}\n\n/**\n * Caller-facing options for {@link refundChannel}.\n */\nexport interface RefundOptions {\n /** Token base units to refund; omit for a full refund (drains remaining balance). */\n amount?: string;\n /** Custom fetch implementation (defaults to `globalThis.fetch`). */\n fetch?: typeof fetch;\n}\n\n/**\n * Sends a cooperative refund request to the channel that backs `url`.\n *\n * Flow:\n * 1. Probe the URL with `GET` (no payment) to obtain the route's payment requirements.\n * 2. Build the `ChannelConfig` and resolve the local session (or recover it).\n * 3. Sign a zero-charge refund voucher (`maxClaimableAmount = chargedCumulativeAmount`).\n * 4. Send the voucher via `PAYMENT-SIGNATURE`. On a corrective 402, run the\n * standard recovery path and retry once.\n * 5. Return the parsed `SettleResponse` from the server.\n *\n * @param ctx - Identity inputs (storage, signers, salt, payerAuthorizer).\n * @param url - Any protected route on the channel to refund (the resource handler is bypassed).\n * @param options - Optional `amount` (partial refund) and `fetch` override.\n * @returns The settle response describing the refund outcome.\n * @throws When the probe fails, the receiver lacks an authorizer, or recovery fails.\n */\nexport async function refundChannel(\n ctx: BatchSettlementClientDeps,\n url: string,\n options?: RefundOptions,\n): Promise<SettleResponse> {\n const fetchImpl = options?.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\"refund requires a fetch implementation (globalThis.fetch unavailable)\");\n }\n\n const refundAmount = normalizeRefundAmount(options?.amount);\n const probe = await probeRefundRequirements(url, fetchImpl);\n return executeRefund(ctx, url, probe, refundAmount, fetchImpl);\n}\n\n/**\n * Probes a URL with an unauthenticated GET to retrieve batch-settlement payment\n * requirements via the 402 PAYMENT-REQUIRED header.\n *\n * @param url - The protected URL to probe.\n * @param fetchImpl - Fetch implementation used for the probe.\n * @returns Matching batch-settlement payment requirements for the route.\n */\nasync function probeRefundRequirements(\n url: string,\n fetchImpl: typeof fetch,\n): Promise<RefundRequirementsProbe> {\n const probe = await fetchImpl(url, { method: \"GET\" });\n if (probe.status !== 402) {\n throw new Error(`Refund probe expected 402, got ${probe.status}`);\n }\n\n const header = probe.headers.get(\"PAYMENT-REQUIRED\");\n if (!header) {\n throw new Error(\"Refund probe response missing PAYMENT-REQUIRED header\");\n }\n\n const paymentRequired = decodePaymentRequiredHeader(header);\n const requirements = paymentRequired.accepts.find(a => a.scheme === BATCH_SETTLEMENT_SCHEME);\n if (!requirements) {\n throw new Error(`No ${BATCH_SETTLEMENT_SCHEME} payment option at ${url}`);\n }\n\n const extra = requirements.extra as Partial<BatchSettlementPaymentRequirementsExtra> | undefined;\n if (!extra?.receiverAuthorizer) {\n throw new Error(\"Refund requires a configured receiverAuthorizer on the receiver\");\n }\n\n return { paymentRequired, requirements };\n}\n\n/**\n * Builds and submits the refund voucher, retrying once after a corrective 402.\n *\n * @param ctx - Identity inputs (storage, signers, salt, payerAuthorizer).\n * @param url - The protected URL to send the refund voucher to.\n * @param probe - Resolved payment requirements and probe metadata for this channel.\n * @param refundAmount - Optional partial refund amount in token base units.\n * @param fetchImpl - Fetch implementation used for the request.\n * @returns The parsed settle response.\n */\nasync function executeRefund(\n ctx: BatchSettlementClientDeps,\n url: string,\n probe: RefundRequirementsProbe,\n refundAmount: string | undefined,\n fetchImpl: typeof fetch,\n): Promise<SettleResponse> {\n const maxAttempts = 2;\n const { paymentRequired, requirements } = probe;\n const httpClient = createRefundHttpClient(ctx, requirements);\n\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n const paymentPayload = await buildRefundPaymentPayload(\n ctx,\n paymentRequired,\n requirements,\n refundAmount,\n );\n const headers = httpClient.encodePaymentSignatureHeader(paymentPayload);\n\n const response = await fetchImpl(url, { method: \"GET\", headers });\n\n if (response.status === 402) {\n const nonRecoverable = getNonRecoverableRefundFailure(response);\n if (nonRecoverable) {\n throw new Error(nonRecoverable);\n }\n }\n\n const result = await httpClient.processPaymentResult(\n paymentPayload,\n name => response.headers.get(name),\n response.status,\n );\n\n if (response.status === 402) {\n if (result.recovered && attempt < maxAttempts) {\n continue;\n }\n if (result.recovered) {\n throw new Error(`Refund failed: server returned 402 after ${attempt} attempt(s)`);\n }\n\n const corrective = getRefundPaymentRequired(response);\n throw new Error(`Refund failed: ${corrective.error ?? \"unknown\"}`);\n }\n\n if (!result.settleResponse) {\n throw new Error(\n `Refund response missing PAYMENT-RESPONSE header (status ${response.status})`,\n );\n }\n\n return result.settleResponse;\n }\n\n throw new Error(\"Refund failed: retry budget exhausted\");\n}\n\n/**\n * Builds the refund payload with a zero-charge `maxClaimableAmount`.\n *\n * @param ctx - Identity inputs (storage, signers, salt, payerAuthorizer).\n * @param paymentRequired - Decoded 402 body from the probe (resource, extensions, etc.).\n * @param requirements - Resolved payment requirements for the channel.\n * @param refundAmount - Optional partial refund amount in token base units.\n * @returns A full payment payload wrapping the signed refund request.\n */\nasync function buildRefundPaymentPayload(\n ctx: BatchSettlementClientDeps,\n paymentRequired: PaymentRequired,\n requirements: PaymentRequirements,\n refundAmount: string | undefined,\n): Promise<PaymentPayload> {\n const config = buildChannelConfig(ctx, requirements);\n const channelId = computeChannelId(config, requirements.network);\n const key = channelId.toLowerCase();\n\n let channel = await ctx.storage.get(key);\n if (channel === undefined && ctx.signer.readContract) {\n channel = await recoverChannel(ctx, requirements);\n }\n if (channel === undefined) {\n throw new Error(\n \"Refund requires an existing channel record; deposit first or call from a context with an EVM RPC\",\n );\n }\n\n // Avoid a refund request when local state shows the channel has no refundable balance.\n const charged = channel.chargedCumulativeAmount ?? \"0\";\n if (channel.balance !== undefined && BigInt(channel.balance) <= BigInt(charged)) {\n throw new Error(\n `Refund failed: channel has no remaining balance (balance=${channel.balance}, chargedCumulativeAmount=${charged})`,\n );\n }\n\n const voucherSigner = ctx.voucherSigner ?? ctx.signer;\n const voucher = await signVoucher(voucherSigner, channelId, charged, requirements.network);\n\n const payload: BatchSettlementRefundPayload = {\n type: \"refund\",\n channelConfig: config,\n voucher,\n ...(refundAmount !== undefined ? { amount: refundAmount } : {}),\n };\n\n return {\n x402Version: 2,\n accepted: requirements,\n payload: payload as unknown as Record<string, unknown>,\n ...(paymentRequired.resource ? { resource: paymentRequired.resource } : {}),\n ...(paymentRequired.extensions ? { extensions: paymentRequired.extensions } : {}),\n };\n}\n\n/**\n * Creates an x402 HTTP client for batch settlement with hooks; refund payloads are supplied\n * by {@link refundChannel} instead of the default payment builder.\n *\n * @param ctx - Identity inputs (storage, signers, salt, payerAuthorizer).\n * @param requirements - Resolved payment requirements for the channel network.\n * @returns An `x402HTTPClient` wired for batch-settlement scheme hooks.\n */\nfunction createRefundHttpClient(\n ctx: BatchSettlementClientDeps,\n requirements: PaymentRequirements,\n): x402HTTPClient {\n const client = new x402Client().register(requirements.network, {\n scheme: BATCH_SETTLEMENT_SCHEME,\n schemeHooks: createBatchSettlementClientHooks(ctx),\n createPaymentPayload: async () => {\n throw new Error(\"Refund payloads are built by refundChannel\");\n },\n });\n return new x402HTTPClient(client);\n}\n\n/**\n * If the refund HTTP response cannot be recovered by retrying, returns a user-facing message;\n * otherwise returns `undefined`.\n *\n * @param response - The refund request response (402 with headers or settle failure).\n * @returns A formatted failure string, or `undefined` when retry may succeed.\n */\nfunction getNonRecoverableRefundFailure(response: Response): string | undefined {\n const settleHeader = response.headers.get(\"PAYMENT-RESPONSE\");\n if (settleHeader) {\n return formatRefundFailure(decodePaymentResponseHeader(settleHeader));\n }\n\n const paymentRequired = getRefundPaymentRequired(response);\n const errorCode = paymentRequired.error;\n if (errorCode && NON_RECOVERABLE_REFUND_ERRORS.has(errorCode)) {\n return `Refund failed: ${errorCode}`;\n }\n}\n\n/**\n * Reads and decodes the `PAYMENT-REQUIRED` header from a refund-related 402 response.\n *\n * @param response - HTTP response that must include `PAYMENT-REQUIRED`.\n * @returns The decoded {@link PaymentRequired} payload.\n * @throws When the header is missing.\n */\nfunction getRefundPaymentRequired(response: Response): PaymentRequired {\n const requiredHeader = response.headers.get(\"PAYMENT-REQUIRED\");\n if (!requiredHeader) {\n throw new Error(\"Refund 402 missing PAYMENT-REQUIRED header\");\n }\n return decodePaymentRequiredHeader(requiredHeader);\n}\n\n/**\n * Builds a human-readable error message from a settle failure response.\n *\n * @param settle - The decoded SettleResponse from the server's 402 reply.\n * @returns A formatted error string suitable for `throw new Error(...)`.\n */\nfunction formatRefundFailure(settle: SettleResponse): string {\n const reason = settle.errorReason ?? \"unknown_settlement_error\";\n const message = settle.errorMessage;\n if (message && message !== reason) {\n return `Refund failed: ${reason}: ${message}`;\n }\n return `Refund failed: ${reason}`;\n}\n\n/**\n * Validates and normalises the optional `refundAmount` argument.\n *\n * @param amount - Raw amount from caller (string of base units).\n * @returns The same string when valid, or `undefined` when omitted.\n */\nfunction normalizeRefundAmount(amount: string | undefined): string | undefined {\n if (amount === undefined) return undefined;\n if (!/^\\d+$/.test(amount) || amount === \"0\") {\n throw new Error(`Invalid refund amount \"${amount}\": must be a positive integer string`);\n }\n return amount;\n}\n","import {\n SchemeNetworkClient,\n SchemeClientHooks,\n PaymentRequired,\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n SettleResponse,\n} from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { BATCH_SETTLEMENT_SCHEME } from \"../constants\";\nimport {\n BatchSettlementAssetTransferMethod,\n BatchSettlementVoucherPayload,\n ChannelConfig,\n} from \"../types\";\nimport { computeChannelId } from \"../utils\";\nimport {\n trySignEip2612PermitExtension,\n trySignErc20ApprovalExtension,\n} from \"../../shared/extensions\";\nimport type { EvmSchemeOptions } from \"../../shared/rpc\";\nimport { createBatchSettlementEIP3009DepositPayload } from \"./eip3009\";\nimport { createBatchSettlementPermit2DepositPayload } from \"./permit2\";\nimport {\n type BatchSettlementDepositStrategy,\n type BatchSettlementDepositStrategyContext,\n type BatchSettlementDepositPolicy,\n type BatchSettlementEvmSchemeOptions,\n depositAmountForRequest,\n resolveClientOptions,\n validateDepositPolicy,\n} from \"./config\";\nimport { refundChannel, type RefundOptions } from \"./refund\";\nimport {\n type BatchSettlementClientDeps,\n buildChannelConfig,\n processSettleResponse,\n recoverChannel,\n} from \"./channel\";\nimport { createBatchSettlementClientHooks } from \"./hooks\";\nimport { processCorrectivePaymentRequired } from \"./recovery\";\nimport type { ClientChannelStorage } from \"./storage\";\nimport { signVoucher } from \"./voucher\";\n\nexport type { BatchSettlementClientContext } from \"./storage\";\nexport type {\n BatchSettlementDepositPolicy,\n BatchSettlementDepositStrategy,\n BatchSettlementDepositStrategyContext,\n BatchSettlementDepositStrategyResult,\n BatchSettlementEvmSchemeOptions,\n} from \"./config\";\nexport type { RefundOptions } from \"./refund\";\n\n/**\n * Client-side implementation of the `batch-settlement` scheme for EVM networks.\n *\n * Builds payment payloads (deposit + voucher or voucher-only), processes server\n * responses to update local session state via {@link processSettleResponse},\n * handles corrective 402 resynchronisation via\n * {@link processCorrectivePaymentRequired}, and supports on-demand cooperative\n * refund requests via {@link refundChannel}.\n */\nexport class BatchSettlementEvmScheme implements SchemeNetworkClient {\n readonly scheme = BATCH_SETTLEMENT_SCHEME;\n\n readonly schemeHooks: SchemeClientHooks;\n\n private readonly storage: ClientChannelStorage;\n private readonly depositPolicy: BatchSettlementDepositPolicy | undefined;\n private readonly depositStrategy: BatchSettlementDepositStrategy | undefined;\n private readonly salt: `0x${string}`;\n private readonly payerAuthorizer: `0x${string}` | undefined;\n private readonly voucherSigner: ClientEvmSigner | undefined;\n private readonly extensionRpcOptions: EvmSchemeOptions | undefined;\n\n /**\n * Constructs a batched client scheme.\n *\n * @param signer - Client EVM wallet used for signing vouchers and ERC-3009 authorizations.\n * @param optionsOrPolicy - Either a full options object or a bare deposit-policy.\n */\n constructor(\n private readonly signer: ClientEvmSigner,\n optionsOrPolicy?: BatchSettlementEvmSchemeOptions | BatchSettlementDepositPolicy,\n ) {\n const {\n storage,\n depositPolicy,\n depositStrategy,\n salt,\n payerAuthorizer,\n voucherSigner,\n extensionRpcOptions,\n } = resolveClientOptions(optionsOrPolicy);\n this.storage = storage;\n this.depositPolicy = depositPolicy;\n this.depositStrategy = depositStrategy;\n this.salt = salt;\n this.payerAuthorizer = payerAuthorizer;\n this.voucherSigner = voucherSigner;\n this.extensionRpcOptions = extensionRpcOptions;\n\n if (\n payerAuthorizer !== undefined &&\n voucherSigner !== undefined &&\n getAddress(payerAuthorizer) !== getAddress(voucherSigner.address)\n ) {\n throw new Error(\"payerAuthorizer address must match voucherSigner.address\");\n }\n\n validateDepositPolicy(depositPolicy);\n this.schemeHooks = createBatchSettlementClientHooks(this.deps());\n }\n\n /**\n * Creates the payment payload for a batched request.\n *\n * If the channel has no onchain deposit (or needs a top-up), builds an\n * ERC-3009 deposit payload bundled with a voucher. Otherwise, signs and\n * returns a voucher-only payload.\n *\n * @param x402Version - Protocol version for the payload envelope.\n * @param paymentRequirements - Server payment requirements (scheme, network, asset, amount).\n * @param context - Optional payment payload context with extension hints.\n * @returns A {@link PaymentPayloadResult} ready to be sent as the `X-PAYMENT` header.\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const deps = this.deps();\n const config = buildChannelConfig(deps, paymentRequirements);\n const channelId = computeChannelId(config, paymentRequirements.network);\n const key = channelId.toLowerCase();\n\n let batchedCtx = await this.storage.get(key);\n if (batchedCtx === undefined && this.signer.readContract) {\n batchedCtx = await recoverChannel(deps, paymentRequirements);\n }\n batchedCtx = batchedCtx ?? {};\n\n const needsInitialDeposit = !batchedCtx.balance || batchedCtx.balance === \"0\";\n\n const baseCumulative = BigInt(batchedCtx.chargedCumulativeAmount ?? \"0\");\n const requestAmount = BigInt(paymentRequirements.amount);\n const maxClaimableAmount = (baseCumulative + requestAmount).toString();\n\n const currentBalance = BigInt(batchedCtx.balance ?? \"0\");\n const needsTopUp = !needsInitialDeposit && BigInt(maxClaimableAmount) > currentBalance;\n\n if (needsInitialDeposit || needsTopUp) {\n const computedDeposit = depositAmountForRequest(this.depositPolicy, requestAmount);\n const minimumDepositAmount = BigInt(maxClaimableAmount) - currentBalance;\n const depositAmount = await this.resolveDepositAmount({\n paymentRequirements,\n channelConfig: config,\n channelId,\n clientContext: batchedCtx,\n requestAmount: requestAmount.toString(),\n maxClaimableAmount,\n currentBalance: currentBalance.toString(),\n minimumDepositAmount: minimumDepositAmount.toString(),\n depositAmount: computedDeposit,\n });\n if (depositAmount === false) {\n return this.createVoucherPayload(\n x402Version,\n channelId,\n maxClaimableAmount,\n paymentRequirements.network,\n config,\n );\n }\n\n const assetTransferMethod =\n (paymentRequirements.extra?.assetTransferMethod as BatchSettlementAssetTransferMethod) ??\n \"eip3009\";\n\n if (assetTransferMethod === \"eip3009\") {\n return createBatchSettlementEIP3009DepositPayload(\n this.signer,\n x402Version,\n paymentRequirements,\n config,\n depositAmount,\n maxClaimableAmount,\n this.voucherSigner,\n );\n }\n\n if (assetTransferMethod !== \"permit2\") {\n throw new Error(`unsupported batch-settlement assetTransferMethod: ${assetTransferMethod}`);\n }\n\n const result = await createBatchSettlementPermit2DepositPayload(\n this.signer,\n x402Version,\n paymentRequirements,\n config,\n depositAmount,\n maxClaimableAmount,\n this.voucherSigner,\n );\n\n const eip2612Extensions = await trySignEip2612PermitExtension(\n this.signer,\n this.extensionRpcOptions,\n paymentRequirements,\n result,\n context,\n depositAmount,\n );\n if (eip2612Extensions) {\n return { ...result, extensions: eip2612Extensions };\n }\n\n const erc20Extensions = await trySignErc20ApprovalExtension(\n this.signer,\n this.extensionRpcOptions,\n paymentRequirements,\n context,\n depositAmount,\n );\n if (erc20Extensions) {\n return { ...result, extensions: erc20Extensions };\n }\n\n return result;\n }\n\n return this.createVoucherPayload(\n x402Version,\n channelId,\n maxClaimableAmount,\n paymentRequirements.network,\n config,\n );\n }\n\n /**\n * Sends a cooperative refund request.\n *\n * @param url - The route URL backing the channel to refund.\n * @param options - Optional `amount` (partial refund) and `fetch` override.\n * @returns The settle response describing the refund outcome.\n */\n async refund(url: string, options?: RefundOptions): Promise<SettleResponse> {\n return refundChannel(this.deps(), url, options);\n }\n\n /**\n * Updates local channel state from a settle response.\n *\n * @param settle - The parsed settle response from the server.\n * @returns Resolves when local channel state has been updated.\n */\n async processSettleResponse(settle: SettleResponse): Promise<void> {\n return processSettleResponse(this.storage, settle);\n }\n\n /**\n * Resyncs local channel state from a corrective 402 response.\n *\n * @param paymentRequired - The decoded 402 response body.\n * @returns `true` if local state was successfully resynced and a retry is warranted.\n */\n async processCorrectivePaymentRequired(paymentRequired: PaymentRequired): Promise<boolean> {\n return processCorrectivePaymentRequired(this.deps(), paymentRequired);\n }\n\n /**\n * Builds the immutable {@link ChannelConfig} for a given set of payment\n * requirements, using the scheme's own signer and salt.\n *\n * @param paymentRequirements - Server payment requirements for the channel.\n * @returns The channel config that uniquely identifies the payment channel.\n */\n buildChannelConfig(paymentRequirements: PaymentRequirements): ChannelConfig {\n return buildChannelConfig(this.deps(), paymentRequirements);\n }\n\n /**\n * Resolves the deposit amount after applying the optional custom strategy.\n *\n * @param context - Deposit attempt context exposed to the strategy.\n * @returns The deposit amount to sign, or `false` to skip this deposit attempt.\n */\n private async resolveDepositAmount(\n context: BatchSettlementDepositStrategyContext,\n ): Promise<string | false> {\n const strategyResult = await this.depositStrategy?.(context);\n if (strategyResult === false) return false;\n if (strategyResult === undefined) return context.depositAmount;\n\n const depositAmount = this.normalizeStrategyDepositAmount(strategyResult);\n if (BigInt(depositAmount) < BigInt(context.minimumDepositAmount)) {\n throw new Error(\n `depositStrategy returned ${depositAmount}, below required top-up ${context.minimumDepositAmount}`,\n );\n }\n return depositAmount;\n }\n\n /**\n * Normalizes and validates a strategy-provided base-unit deposit amount.\n *\n * @param value - Strategy-provided string or bigint amount.\n * @returns Normalized decimal string.\n */\n private normalizeStrategyDepositAmount(value: string | bigint): string {\n if (typeof value === \"bigint\") {\n if (value <= 0n) {\n throw new Error(\"depositStrategy must return a positive integer deposit amount\");\n }\n return value.toString();\n }\n\n if (/^\\d+$/.test(value) && BigInt(value) > 0n) {\n return BigInt(value).toString();\n }\n\n throw new Error(\"depositStrategy must return a positive integer deposit amount\");\n }\n\n /**\n * Signs a voucher-only payment payload for the current channel.\n *\n * @param x402Version - Protocol version for the payload envelope.\n * @param channelId - Channel identifier for the voucher.\n * @param maxClaimableAmount - Cumulative ceiling for the voucher.\n * @param network - CAIP-2 network identifier.\n * @param config - Immutable channel configuration.\n * @returns Voucher-only payment payload.\n */\n private async createVoucherPayload(\n x402Version: number,\n channelId: `0x${string}`,\n maxClaimableAmount: string,\n network: string,\n config: ChannelConfig,\n ): Promise<PaymentPayloadResult> {\n const voucherSigner = this.voucherSigner ?? this.signer;\n const voucher = await signVoucher(voucherSigner, channelId, maxClaimableAmount, network);\n\n const payload: BatchSettlementVoucherPayload = {\n type: \"voucher\",\n channelConfig: config,\n voucher,\n };\n\n return {\n x402Version,\n payload,\n };\n }\n\n /**\n * Bundles the class state into the {@link BatchSettlementClientDeps} shape\n * consumed by the `channel`, `recovery`, and `refund` modules.\n *\n * @returns Client deps wrapping the scheme's own signer and storage.\n */\n private deps(): BatchSettlementClientDeps {\n return {\n signer: this.signer,\n storage: this.storage,\n salt: this.salt,\n payerAuthorizer: this.payerAuthorizer,\n voucherSigner: this.voucherSigner,\n };\n }\n}\n","import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { PERMIT2_ADDRESS } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { createPermit2Nonce, getEvmChainId } from \"../../utils\";\nimport { PERMIT2_DEPOSIT_COLLECTOR_ADDRESS, batchPermit2WitnessTypes } from \"../constants\";\nimport { ChannelConfig, BatchSettlementDepositPayload } from \"../types\";\nimport { computeChannelId } from \"../utils\";\nimport { signVoucher } from \"./voucher\";\n\n/**\n * Builds a batch deposit payload using a channel-bound Permit2 witness transfer.\n *\n * @param signer - Payer signer for the Permit2 authorization.\n * @param x402Version - Protocol version for the payment envelope.\n * @param paymentRequirements - Server-provided payment requirements.\n * @param channelConfig - Channel configuration bound into the voucher and witness.\n * @param depositAmount - Token amount deposited into the channel.\n * @param maxClaimableAmount - Cumulative amount signed in the voucher.\n * @param voucherSigner - Optional signer for the voucher.\n * @returns Signed deposit payload and voucher.\n */\nexport async function createBatchSettlementPermit2DepositPayload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n channelConfig: ChannelConfig,\n depositAmount: string,\n maxClaimableAmount: string,\n voucherSigner?: ClientEvmSigner,\n): Promise<PaymentPayloadResult> {\n const chainId = getEvmChainId(paymentRequirements.network);\n const nonce = createPermit2Nonce();\n const deadline = Math.floor(Date.now() / 1000 + paymentRequirements.maxTimeoutSeconds).toString();\n const channelId = computeChannelId(channelConfig, paymentRequirements.network);\n\n const permit2Authorization = {\n from: signer.address,\n permitted: {\n token: getAddress(paymentRequirements.asset),\n amount: depositAmount,\n },\n spender: getAddress(PERMIT2_DEPOSIT_COLLECTOR_ADDRESS),\n nonce,\n deadline,\n witness: {\n channelId,\n },\n };\n\n const signature = await signer.signTypedData({\n domain: { name: \"Permit2\", chainId, verifyingContract: PERMIT2_ADDRESS },\n types: batchPermit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message: {\n permitted: {\n token: permit2Authorization.permitted.token,\n amount: BigInt(permit2Authorization.permitted.amount),\n },\n spender: permit2Authorization.spender,\n nonce: BigInt(permit2Authorization.nonce),\n deadline: BigInt(permit2Authorization.deadline),\n witness: {\n channelId,\n },\n },\n });\n\n const voucher = await signVoucher(\n voucherSigner ?? signer,\n channelId,\n maxClaimableAmount,\n paymentRequirements.network,\n );\n\n const payload: BatchSettlementDepositPayload = {\n type: \"deposit\",\n channelConfig,\n voucher,\n deposit: {\n amount: depositAmount,\n authorization: {\n permit2Authorization: {\n ...permit2Authorization,\n signature,\n },\n },\n },\n };\n\n return { x402Version, payload };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,eAAsB,YACpB,QACA,WACA,oBACA,SACuC;AACvC,QAAM,UAAU,cAAc,OAAO;AAErC,QAAM,YAAY,MAAM,OAAO,cAAc;AAAA,IAC3C,QAAQ,+BAA+B,OAAO;AAAA,IAC9C,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP;AAAA,MACA,oBAAoB,OAAO,kBAAkB;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3CA,SAAS,kBAAkB;AAyB3B,eAAsB,2CACpB,QACA,aACA,qBACA,eACA,eACA,oBACA,eAC+B;AAC/B,QAAM,OAAO,YAAY;AACzB,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,UAAU,cAAc,oBAAoB,OAAO;AAEzD,MAAI,CAAC,oBAAoB,OAAO,QAAQ,CAAC,oBAAoB,OAAO,SAAS;AAC3E,UAAM,IAAI;AAAA,MACR,4FAA4F,oBAAoB,KAAK;AAAA,IACvH;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,QAAQ,IAAI,oBAAoB;AAE9C,QAAM,YAAY,iBAAiB,eAAe,oBAAoB,OAAO;AAE7E,QAAM,eAAe,yBAAyB,WAAW,IAAI;AAE7D,QAAM,YAAY,MAAM,OAAO,cAAc;AAAA,IAC3C,QAAQ;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB,WAAW,oBAAoB,KAAK;AAAA,IACzD;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP,MAAM,WAAW,OAAO,OAAO;AAAA,MAC/B,IAAI,WAAW,iCAAiC;AAAA,MAChD,OAAO,OAAO,aAAa;AAAA,MAC3B,YAAY,OAAO,MAAM,GAAG;AAAA,MAC5B,aAAa,OAAO,MAAM,oBAAoB,iBAAiB;AAAA,MAC/D,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,UAAU,iBAAiB;AACjC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,EACtB;AAEA,QAAM,UAAyC;AAAA,IAC7C,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,eAAe;AAAA,QACb,sBAAsB;AAAA,UACpB,aAAa,MAAM,KAAK,SAAS;AAAA,UACjC,cAAc,MAAM,oBAAoB,mBAAmB,SAAS;AAAA,UACpE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;AC1EO,IAAM,+BAAN,MAAmE;AAAA,EAAnE;AACL,SAAiB,WAAW,oBAAI,IAA0C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1E,MAAM,IAAI,KAAgE;AACxE,WAAO,KAAK,SAAS,IAAI,GAAG;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,IAAI,KAAa,SAAsD;AAC3E,SAAK,SAAS,IAAI,KAAK,OAAO;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,KAA4B;AACvC,SAAK,SAAS,OAAO,GAAG;AAAA,EAC1B;AACF;;;ACnDA,IAAM,eACJ;AAyEK,SAAS,kCACd,GACsC;AACtC,SACE,MAAM,UACN,OAAO,MAAM,aACZ,aAAa,KACZ,mBAAmB,KACnB,qBAAqB,KACrB,UAAU,KACV,qBAAqB,KACrB,YAAY,KACZ,mBAAmB;AAEzB;AAQO,SAAS,qBACd,QACuB;AACvB,MAAI,WAAW,QAAW;AACxB,WAAO,EAAE,SAAS,IAAI,6BAA6B,GAAG,MAAM,aAAa;AAAA,EAC3E;AACA,MAAI,kCAAkC,MAAM,GAAG;AAC7C,WAAO;AAAA,MACL,SAAS,OAAO,WAAW,IAAI,6BAA6B;AAAA,MAC5D,eAAe,OAAO;AAAA,MACtB,iBAAiB,OAAO;AAAA,MACxB,MAAM,OAAO,QAAQ;AAAA,MACrB,iBAAiB,OAAO;AAAA,MACxB,eAAe,OAAO;AAAA,MACtB,qBAAqB,OAAO,SAAS,EAAE,QAAQ,OAAO,OAAO,IAAI;AAAA,IACnE;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS,IAAI,6BAA6B;AAAA,IAC1C,eAAe;AAAA,IACf,MAAM;AAAA,EACR;AACF;AAOO,SAAS,sBAAsB,QAAwD;AAC5F,MAAI,CAAC,OAAQ;AAEb,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,WAAc,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,IAAI;AACtD,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AACF;AASO,SAAS,wBACd,QACA,eACQ;AACR,QAAM,OAAO,OAAO,QAAQ,qBAAqB,CAAC;AAClD,UAAQ,OAAO,eAAe,SAAS;AACzC;;;AC1JA,SAAS,mCAAmC;AAE5C,SAAS,cAAAA,mBAAkB;AAoB3B,SAAS,yBACP,OACkC;AAClC,QAAM,eAAe,MAAM;AAC3B,MAAI,OAAO,iBAAiB,YAAY,iBAAiB,MAAM;AAC7D,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAsBO,SAAS,mBACd,MACA,qBACe;AACf,QAAM,QAAQ,oBAAoB;AAGlC,QAAM,qBAAqB,OAAO;AAClC,MACE,CAAC,sBACDC,YAAW,kBAAkB,MAAM,8CACnC;AACA,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AAEA,SAAO;AAAA,IACL,OAAO,KAAK,OAAO;AAAA,IACnB,iBAAiBA;AAAA,MACf,KAAK,mBAAmB,KAAK,eAAe,WAAW,KAAK,OAAO;AAAA,IACrE;AAAA,IACA,UAAU,oBAAoB;AAAA,IAC9B,oBAAoBA,YAAW,kBAAkB;AAAA,IACjD,OAAO,oBAAoB;AAAA,IAC3B,eACE,OAAO,OAAO,kBAAkB,WAAW,MAAM,gBAAgB;AAAA,IACnE,MAAM,KAAK;AAAA,EACb;AACF;AAQA,eAAsB,sBACpB,SACA,QACe;AACf,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,eAAe,yBAAyB,KAAK;AACnD,MAAI,CAAC,aAAc;AAEnB,QAAM,YAAY,aAAa;AAC/B,QAAM,MAAM,UAAU,YAAY;AAElC,QAAM,OAAO,MAAM,QAAQ,IAAI,GAAG;AAClC,QAAM,OAAqC,EAAE,GAAI,QAAQ,CAAC,EAAG;AAE7D,MAAI,aAAa,4BAA4B,QAAW;AACtD,SAAK,0BAA0B,OAAO,aAAa,uBAAuB;AAAA,EAC5E;AACA,MAAI,aAAa,YAAY,QAAW;AACtC,SAAK,UAAU,OAAO,aAAa,OAAO;AAAA,EAC5C;AACA,MAAI,aAAa,iBAAiB,QAAW;AAC3C,SAAK,eAAe,OAAO,aAAa,YAAY;AAAA,EACtD;AAEA,QAAM,QAAQ,IAAI,KAAK,IAAI;AAC7B;AAYA,eAAsB,yBACpB,SACA,YACA,aACe;AACf,QAAM,eAAe,yBAAyB,WAAW;AACzD,MAAI,CAAC,cAAc;AACjB,UAAM,QAAQ,OAAO,UAAU;AAC/B;AAAA,EACF;AAEA,QAAM,eACJ,aAAa,YAAY,SAAY,OAAO,OAAO,aAAa,OAAO,CAAC,IAAI;AAE9E,MAAI,iBAAiB,UAAa,gBAAgB,IAAI;AACpD,UAAM,QAAQ,OAAO,UAAU;AAC/B;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,QAAQ,IAAI,UAAU;AACzC,QAAM,OAAqC,EAAE,GAAI,QAAQ,CAAC,EAAG;AAC7D,OAAK,UAAU,aAAa,SAAS;AACrC,MAAI,aAAa,4BAA4B,QAAW;AACtD,SAAK,0BAA0B,OAAO,aAAa,uBAAuB;AAAA,EAC5E;AACA,MAAI,aAAa,iBAAiB,QAAW;AAC3C,SAAK,eAAe,OAAO,aAAa,YAAY;AAAA,EACtD;AACA,QAAM,QAAQ,IAAI,YAAY,IAAI;AACpC;AAWA,eAAsB,uBACpB,SACA,WACe;AACf,QAAM,MAAM,UAAU,kBAAkB;AACxC,MAAI,CAAC,IAAK;AAEV,QAAM,SAAS,4BAA4B,GAAG;AAC9C,QAAM,sBAAsB,SAAS,MAAM;AAC7C;AAUA,eAAsB,eACpB,MACA,qBACuC;AACvC,MAAI,CAAC,KAAK,OAAO,cAAc;AAC7B,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAEA,QAAM,SAAS,mBAAmB,MAAM,mBAAmB;AAC3D,QAAM,YAAY,iBAAiB,QAAQ,oBAAoB,OAAO;AAEtE,QAAM,CAAC,WAAW,cAAc,IAAI,MAAM;AAAA,IACxC,KAAK;AAAA,IACL;AAAA,EACF;AAEA,QAAM,MAAoC;AAAA,IACxC,yBAAyB,eAAe,SAAS;AAAA,IACjD,SAAS,UAAU,SAAS;AAAA,IAC5B,cAAc,eAAe,SAAS;AAAA,EACxC;AAEA,QAAM,KAAK,QAAQ,IAAI,UAAU,YAAY,GAAG,GAAG;AACnD,SAAO;AACT;AASA,eAAsB,kCACpB,QACA,WAC2B;AAC3B,MAAI,CAAC,OAAO,cAAc;AACxB,UAAM,IAAI,MAAM,yEAAyE;AAAA,EAC3F;AACA,SAAQ,MAAM,OAAO,aAAa;AAAA,IAChC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AACH;AASA,eAAsB,WACpB,SACA,WACkB;AAClB,QAAM,UAAU,MAAM,QAAQ,IAAI,UAAU,YAAY,CAAC;AACzD,SAAO,YAAY;AACrB;AASA,eAAsB,WACpB,SACA,WACmD;AACnD,SAAO,QAAQ,IAAI,UAAU,YAAY,CAAC;AAC5C;;;ACjQA,SAAS,cAAAC,aAAY,+BAA+B;AAyBpD,eAAsB,iCACpB,MACA,iBACkB;AAClB,MACE,gBAAgB,UAAiB,+BACjC,gBAAgB,UAAiB,iCACjC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,gBAAgB,QAAQ,KAAK,OAAK,EAAE,WAAW,uBAAuB;AACrF,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,OAAO,MAAM;AAClC,QAAM,eAAe,OAAO,MAAM;AAClC,QAAM,SACJ,cAAc,4BAA4B,UAC1C,cAAc,uBAAuB,UACrC,aAAa,cAAc;AAE7B,MAAI,CAAC,QAAQ;AACX,WAAO,wBAAwB,MAAM,MAAM;AAAA,EAC7C;AAEA,SAAO,qBAAqB,MAAM,QAAQ,cAAc,YAAY;AACtE;AAaA,eAAsB,qBACpB,MACA,QACA,cACA,cACkB;AAClB,QAAM,aAAa,aAAa;AAChC,QAAM,YAAY,aAAa;AAC/B,QAAM,MAAM,aAAa;AAEzB,QAAM,UAAU,OAAO,OAAO,UAAU,CAAC;AACzC,QAAM,SAAS,OAAO,OAAO,SAAS,CAAC;AAEvC,MAAI,UAAU,QAAQ;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,mBAAmB,MAAM,MAAM;AAC9C,QAAM,YAAY,iBAAiB,QAAQ,OAAO,OAAO;AAEzD,MAAI,CAAC,KAAK,OAAO,cAAc;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,WAAW,cAAc,IAAI,MAAM;AAAA,IACxC,KAAK;AAAA,IACL;AAAA,EACF;AAEA,MAAI,UAAU,gBAAgB;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,cAAc,OAAO,OAAO;AAC5C,QAAM,YAAY,MAAM,wBAAwB;AAAA,IAC9C,QAAQ,+BAA+B,OAAO;AAAA,IAC9C,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP;AAAA,MACA,oBAAoB;AAAA,IACtB;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AAED,QAAM,iBAAiBC;AAAA,IACrB,KAAK,mBAAmB,KAAK,eAAe,WAAW,KAAK,OAAO;AAAA,EACrE;AACA,MAAI,UAAU,YAAY,MAAM,eAAe,YAAY,GAAG;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,MAAoC;AAAA,IACxC,yBAAyB,QAAQ,SAAS;AAAA,IAC1C,oBAAoB,OAAO,SAAS;AAAA,IACpC,WAAW;AAAA,IACX,SAAS,UAAU,SAAS;AAAA,IAC5B,cAAc,eAAe,SAAS;AAAA,EACxC;AAEA,QAAM,KAAK,QAAQ,IAAI,UAAU,YAAY,GAAG,GAAG;AACnD,SAAO;AACT;AAaA,eAAsB,wBACpB,MACA,QACkB;AAClB,MAAI,CAAC,KAAK,OAAO,cAAc;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,mBAAmB,MAAM,MAAM;AAC9C,QAAM,YAAY,iBAAiB,QAAQ,OAAO,OAAO;AAEzD,QAAM,CAAC,WAAW,cAAc,IAAI,MAAM;AAAA,IACxC,KAAK;AAAA,IACL;AAAA,EACF;AAEA,QAAM,MAAoC;AAAA,IACxC,yBAAyB,eAAe,SAAS;AAAA,IACjD,SAAS,UAAU,SAAS;AAAA,IAC5B,cAAc,eAAe,SAAS;AAAA,EACxC;AAEA,QAAM,KAAK,QAAQ,IAAI,UAAU,YAAY,GAAG,GAAG;AACnD,SAAO;AACT;;;ACzJO,SAAS,iCACd,MACmB;AACnB,SAAO;AAAA,IACL,mBAAmB,SAAO,qCAAqC,MAAM,GAAG;AAAA,EAC1E;AACF;AASA,eAAsB,qCACpB,MACA,KACqC;AACrC,MAAI,IAAI,gBAAgB;AACtB,QAAI,+BAA+B,IAAI,eAAe,OAAO,GAAG;AAC9D,YAAM,QAAQ,IAAI,eAAe,SAAS,CAAC;AAC3C,YAAM,eAAe,MAAM;AAC3B,YAAM,YACJ,OAAO,iBAAiB,YAAY,iBAAiB,QAAQ,eAAe,eACxE,aAAa,YACb;AACN,UAAI,OAAO,cAAc,YAAY,WAAW;AAC9C,cAAM,yBAAyB,KAAK,SAAS,UAAU,YAAY,GAAG,KAAK;AAAA,MAC7E;AACA;AAAA,IACF;AAEA,UAAM,sBAAsB,KAAK,SAAS,IAAI,cAAc;AAC5D;AAAA,EACF;AAEA,MAAI,IAAI,iBAAiB;AACvB,UAAM,YAAY,MAAM,iCAAiC,MAAM,IAAI,eAAe;AAClF,WAAO,YAAY,EAAE,WAAW,KAAK,IAAI;AAAA,EAC3C;AACF;;;ACtDA,SAAS,6BAA6B,+BAAAC,oCAAmC;AACzE,SAAS,YAAY,sBAAsB;AAuB3C,IAAM,gCAAqD,oBAAI,IAAI;AAAA,EAC1D;AAAA,EACA;AACT,CAAC;AAkCD,eAAsB,cACpB,KACA,KACA,SACyB;AACzB,QAAM,YAAY,SAAS,SAAS,WAAW;AAC/C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AAEA,QAAM,eAAe,sBAAsB,SAAS,MAAM;AAC1D,QAAM,QAAQ,MAAM,wBAAwB,KAAK,SAAS;AAC1D,SAAO,cAAc,KAAK,KAAK,OAAO,cAAc,SAAS;AAC/D;AAUA,eAAe,wBACb,KACA,WACkC;AAClC,QAAM,QAAQ,MAAM,UAAU,KAAK,EAAE,QAAQ,MAAM,CAAC;AACpD,MAAI,MAAM,WAAW,KAAK;AACxB,UAAM,IAAI,MAAM,kCAAkC,MAAM,MAAM,EAAE;AAAA,EAClE;AAEA,QAAM,SAAS,MAAM,QAAQ,IAAI,kBAAkB;AACnD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEA,QAAM,kBAAkB,4BAA4B,MAAM;AAC1D,QAAM,eAAe,gBAAgB,QAAQ,KAAK,OAAK,EAAE,WAAW,uBAAuB;AAC3F,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,MAAM,uBAAuB,sBAAsB,GAAG,EAAE;AAAA,EAC1E;AAEA,QAAM,QAAQ,aAAa;AAC3B,MAAI,CAAC,OAAO,oBAAoB;AAC9B,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AAEA,SAAO,EAAE,iBAAiB,aAAa;AACzC;AAYA,eAAe,cACb,KACA,KACA,OACA,cACA,WACyB;AACzB,QAAM,cAAc;AACpB,QAAM,EAAE,iBAAiB,aAAa,IAAI;AAC1C,QAAM,aAAa,uBAAuB,KAAK,YAAY;AAE3D,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW,GAAG;AAC1D,UAAM,iBAAiB,MAAM;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,UAAU,WAAW,6BAA6B,cAAc;AAEtE,UAAM,WAAW,MAAM,UAAU,KAAK,EAAE,QAAQ,OAAO,QAAQ,CAAC;AAEhE,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,iBAAiB,+BAA+B,QAAQ;AAC9D,UAAI,gBAAgB;AAClB,cAAM,IAAI,MAAM,cAAc;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,WAAW;AAAA,MAC9B;AAAA,MACA,UAAQ,SAAS,QAAQ,IAAI,IAAI;AAAA,MACjC,SAAS;AAAA,IACX;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,UAAI,OAAO,aAAa,UAAU,aAAa;AAC7C;AAAA,MACF;AACA,UAAI,OAAO,WAAW;AACpB,cAAM,IAAI,MAAM,4CAA4C,OAAO,aAAa;AAAA,MAClF;AAEA,YAAM,aAAa,yBAAyB,QAAQ;AACpD,YAAM,IAAI,MAAM,kBAAkB,WAAW,SAAS,SAAS,EAAE;AAAA,IACnE;AAEA,QAAI,CAAC,OAAO,gBAAgB;AAC1B,YAAM,IAAI;AAAA,QACR,2DAA2D,SAAS,MAAM;AAAA,MAC5E;AAAA,IACF;AAEA,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,IAAI,MAAM,uCAAuC;AACzD;AAWA,eAAe,0BACb,KACA,iBACA,cACA,cACyB;AACzB,QAAM,SAAS,mBAAmB,KAAK,YAAY;AACnD,QAAM,YAAY,iBAAiB,QAAQ,aAAa,OAAO;AAC/D,QAAM,MAAM,UAAU,YAAY;AAElC,MAAI,UAAU,MAAM,IAAI,QAAQ,IAAI,GAAG;AACvC,MAAI,YAAY,UAAa,IAAI,OAAO,cAAc;AACpD,cAAU,MAAM,eAAe,KAAK,YAAY;AAAA,EAClD;AACA,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAU,QAAQ,2BAA2B;AACnD,MAAI,QAAQ,YAAY,UAAa,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,GAAG;AAC/E,UAAM,IAAI;AAAA,MACR,4DAA4D,QAAQ,OAAO,6BAA6B,OAAO;AAAA,IACjH;AAAA,EACF;AAEA,QAAM,gBAAgB,IAAI,iBAAiB,IAAI;AAC/C,QAAM,UAAU,MAAM,YAAY,eAAe,WAAW,SAAS,aAAa,OAAO;AAEzF,QAAM,UAAwC;AAAA,IAC5C,MAAM;AAAA,IACN,eAAe;AAAA,IACf;AAAA,IACA,GAAI,iBAAiB,SAAY,EAAE,QAAQ,aAAa,IAAI,CAAC;AAAA,EAC/D;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,IACb,UAAU;AAAA,IACV;AAAA,IACA,GAAI,gBAAgB,WAAW,EAAE,UAAU,gBAAgB,SAAS,IAAI,CAAC;AAAA,IACzE,GAAI,gBAAgB,aAAa,EAAE,YAAY,gBAAgB,WAAW,IAAI,CAAC;AAAA,EACjF;AACF;AAUA,SAAS,uBACP,KACA,cACgB;AAChB,QAAM,SAAS,IAAI,WAAW,EAAE,SAAS,aAAa,SAAS;AAAA,IAC7D,QAAQ;AAAA,IACR,aAAa,iCAAiC,GAAG;AAAA,IACjD,sBAAsB,YAAY;AAChC,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAAA,EACF,CAAC;AACD,SAAO,IAAI,eAAe,MAAM;AAClC;AASA,SAAS,+BAA+B,UAAwC;AAC9E,QAAM,eAAe,SAAS,QAAQ,IAAI,kBAAkB;AAC5D,MAAI,cAAc;AAChB,WAAO,oBAAoBC,6BAA4B,YAAY,CAAC;AAAA,EACtE;AAEA,QAAM,kBAAkB,yBAAyB,QAAQ;AACzD,QAAM,YAAY,gBAAgB;AAClC,MAAI,aAAa,8BAA8B,IAAI,SAAS,GAAG;AAC7D,WAAO,kBAAkB,SAAS;AAAA,EACpC;AACF;AASA,SAAS,yBAAyB,UAAqC;AACrE,QAAM,iBAAiB,SAAS,QAAQ,IAAI,kBAAkB;AAC9D,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO,4BAA4B,cAAc;AACnD;AAQA,SAAS,oBAAoB,QAAgC;AAC3D,QAAM,SAAS,OAAO,eAAe;AACrC,QAAM,UAAU,OAAO;AACvB,MAAI,WAAW,YAAY,QAAQ;AACjC,WAAO,kBAAkB,MAAM,KAAK,OAAO;AAAA,EAC7C;AACA,SAAO,kBAAkB,MAAM;AACjC;AAQA,SAAS,sBAAsB,QAAgD;AAC7E,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,CAAC,QAAQ,KAAK,MAAM,KAAK,WAAW,KAAK;AAC3C,UAAM,IAAI,MAAM,0BAA0B,MAAM,sCAAsC;AAAA,EACxF;AACA,SAAO;AACT;;;ACxTA,SAAS,cAAAC,mBAAkB;;;ACR3B,SAAS,cAAAC,mBAAkB;AAqB3B,eAAsB,2CACpB,QACA,aACA,qBACA,eACA,eACA,oBACA,eAC+B;AAC/B,QAAM,UAAU,cAAc,oBAAoB,OAAO;AACzD,QAAM,QAAQ,mBAAmB;AACjC,QAAM,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,MAAO,oBAAoB,iBAAiB,EAAE,SAAS;AAChG,QAAM,YAAY,iBAAiB,eAAe,oBAAoB,OAAO;AAE7E,QAAM,uBAAuB;AAAA,IAC3B,MAAM,OAAO;AAAA,IACb,WAAW;AAAA,MACT,OAAOC,YAAW,oBAAoB,KAAK;AAAA,MAC3C,QAAQ;AAAA,IACV;AAAA,IACA,SAASA,YAAW,iCAAiC;AAAA,IACrD;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,OAAO,cAAc;AAAA,IAC3C,QAAQ,EAAE,MAAM,WAAW,SAAS,mBAAmB,gBAAgB;AAAA,IACvE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP,WAAW;AAAA,QACT,OAAO,qBAAqB,UAAU;AAAA,QACtC,QAAQ,OAAO,qBAAqB,UAAU,MAAM;AAAA,MACtD;AAAA,MACA,SAAS,qBAAqB;AAAA,MAC9B,OAAO,OAAO,qBAAqB,KAAK;AAAA,MACxC,UAAU,OAAO,qBAAqB,QAAQ;AAAA,MAC9C,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM;AAAA,IACpB,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,EACtB;AAEA,QAAM,UAAyC;AAAA,IAC7C,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,eAAe;AAAA,QACb,sBAAsB;AAAA,UACpB,GAAG;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,QAAQ;AAChC;;;AD1BO,IAAM,2BAAN,MAA8D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBnE,YACmB,QACjB,iBACA;AAFiB;AAnBnB,SAAS,SAAS;AAsBhB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,qBAAqB,eAAe;AACxC,SAAK,UAAU;AACf,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AACvB,SAAK,OAAO;AACZ,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AACrB,SAAK,sBAAsB;AAE3B,QACE,oBAAoB,UACpB,kBAAkB,UAClBC,YAAW,eAAe,MAAMA,YAAW,cAAc,OAAO,GAChE;AACA,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC5E;AAEA,0BAAsB,aAAa;AACnC,SAAK,cAAc,iCAAiC,KAAK,KAAK,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,qBACJ,aACA,qBACA,SAC+B;AAC/B,UAAM,OAAO,KAAK,KAAK;AACvB,UAAM,SAAS,mBAAmB,MAAM,mBAAmB;AAC3D,UAAM,YAAY,iBAAiB,QAAQ,oBAAoB,OAAO;AACtE,UAAM,MAAM,UAAU,YAAY;AAElC,QAAI,aAAa,MAAM,KAAK,QAAQ,IAAI,GAAG;AAC3C,QAAI,eAAe,UAAa,KAAK,OAAO,cAAc;AACxD,mBAAa,MAAM,eAAe,MAAM,mBAAmB;AAAA,IAC7D;AACA,iBAAa,cAAc,CAAC;AAE5B,UAAM,sBAAsB,CAAC,WAAW,WAAW,WAAW,YAAY;AAE1E,UAAM,iBAAiB,OAAO,WAAW,2BAA2B,GAAG;AACvE,UAAM,gBAAgB,OAAO,oBAAoB,MAAM;AACvD,UAAM,sBAAsB,iBAAiB,eAAe,SAAS;AAErE,UAAM,iBAAiB,OAAO,WAAW,WAAW,GAAG;AACvD,UAAM,aAAa,CAAC,uBAAuB,OAAO,kBAAkB,IAAI;AAExE,QAAI,uBAAuB,YAAY;AACrC,YAAM,kBAAkB,wBAAwB,KAAK,eAAe,aAAa;AACjF,YAAM,uBAAuB,OAAO,kBAAkB,IAAI;AAC1D,YAAM,gBAAgB,MAAM,KAAK,qBAAqB;AAAA,QACpD;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA,eAAe;AAAA,QACf,eAAe,cAAc,SAAS;AAAA,QACtC;AAAA,QACA,gBAAgB,eAAe,SAAS;AAAA,QACxC,sBAAsB,qBAAqB,SAAS;AAAA,QACpD,eAAe;AAAA,MACjB,CAAC;AACD,UAAI,kBAAkB,OAAO;AAC3B,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA,oBAAoB;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,sBACH,oBAAoB,OAAO,uBAC5B;AAEF,UAAI,wBAAwB,WAAW;AACrC,eAAO;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF;AAEA,UAAI,wBAAwB,WAAW;AACrC,cAAM,IAAI,MAAM,qDAAqD,mBAAmB,EAAE;AAAA,MAC5F;AAEA,YAAM,SAAS,MAAM;AAAA,QACnB,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AAEA,YAAM,oBAAoB,MAAM;AAAA,QAC9B,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,mBAAmB;AACrB,eAAO,EAAE,GAAG,QAAQ,YAAY,kBAAkB;AAAA,MACpD;AAEA,YAAM,kBAAkB,MAAM;AAAA,QAC5B,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,iBAAiB;AACnB,eAAO,EAAE,GAAG,QAAQ,YAAY,gBAAgB;AAAA,MAClD;AAEA,aAAO;AAAA,IACT;AAEA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,KAAa,SAAkD;AAC1E,WAAO,cAAc,KAAK,KAAK,GAAG,KAAK,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,sBAAsB,QAAuC;AACjE,WAAO,sBAAsB,KAAK,SAAS,MAAM;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iCAAiC,iBAAoD;AACzF,WAAO,iCAAiC,KAAK,KAAK,GAAG,eAAe;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,mBAAmB,qBAAyD;AAC1E,WAAO,mBAAmB,KAAK,KAAK,GAAG,mBAAmB;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,qBACZ,SACyB;AACzB,UAAM,iBAAiB,MAAM,KAAK,kBAAkB,OAAO;AAC3D,QAAI,mBAAmB,MAAO,QAAO;AACrC,QAAI,mBAAmB,OAAW,QAAO,QAAQ;AAEjD,UAAM,gBAAgB,KAAK,+BAA+B,cAAc;AACxE,QAAI,OAAO,aAAa,IAAI,OAAO,QAAQ,oBAAoB,GAAG;AAChE,YAAM,IAAI;AAAA,QACR,4BAA4B,aAAa,2BAA2B,QAAQ,oBAAoB;AAAA,MAClG;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,+BAA+B,OAAgC;AACrE,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,SAAS,IAAI;AACf,cAAM,IAAI,MAAM,+DAA+D;AAAA,MACjF;AACA,aAAO,MAAM,SAAS;AAAA,IACxB;AAEA,QAAI,QAAQ,KAAK,KAAK,KAAK,OAAO,KAAK,IAAI,IAAI;AAC7C,aAAO,OAAO,KAAK,EAAE,SAAS;AAAA,IAChC;AAEA,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAc,qBACZ,aACA,WACA,oBACA,SACA,QAC+B;AAC/B,UAAM,gBAAgB,KAAK,iBAAiB,KAAK;AACjD,UAAM,UAAU,MAAM,YAAY,eAAe,WAAW,oBAAoB,OAAO;AAEvF,UAAM,UAAyC;AAAA,MAC7C,MAAM;AAAA,MACN,eAAe;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,OAAkC;AACxC,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,iBAAiB,KAAK;AAAA,MACtB,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AACF;","names":["getAddress","getAddress","getAddress","getAddress","decodePaymentResponseHeader","decodePaymentResponseHeader","getAddress","getAddress","getAddress","getAddress"]}
@@ -1,17 +1,21 @@
1
1
  import {
2
2
  ExactEvmSchemeV12 as ExactEvmSchemeV1,
3
3
  NETWORKS
4
- } from "./chunk-ERK2ZPOY.mjs";
4
+ } from "./chunk-CSQS7ZON.mjs";
5
+ import {
6
+ createPermit2Payload
7
+ } from "./chunk-53USC5VE.mjs";
5
8
  import {
6
- createPermit2Payload,
7
9
  trySignEip2612PermitExtension,
8
10
  trySignErc20ApprovalExtension
9
- } from "./chunk-WKBC5YMI.mjs";
11
+ } from "./chunk-YMQCTKDU.mjs";
12
+ import {
13
+ authorizationTypes
14
+ } from "./chunk-MACPBXCT.mjs";
10
15
  import {
11
- authorizationTypes,
12
16
  createNonce,
13
17
  getEvmChainId
14
- } from "./chunk-C4ZQMS77.mjs";
18
+ } from "./chunk-TW7Z65AO.mjs";
15
19
 
16
20
  // src/exact/client/eip3009.ts
17
21
  import { getAddress } from "viem";
@@ -155,4 +159,4 @@ export {
155
159
  ExactEvmScheme,
156
160
  registerExactEvmScheme
157
161
  };
158
- //# sourceMappingURL=chunk-FQJR4RCF.mjs.map
162
+ //# sourceMappingURL=chunk-R7I3RZFF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exact/client/eip3009.ts","../../src/exact/client/scheme.ts","../../src/exact/client/register.ts"],"sourcesContent":["import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\n\n/**\n * Creates an EIP-3009 (transferWithAuthorization) payload.\n *\n * @param signer - The EVM signer for client operations\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createEIP3009Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEIP3009Payload[\"authorization\"] = {\n from: signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(),\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n const signature = await signEIP3009Authorization(signer, authorization, paymentRequirements);\n\n const payload: ExactEIP3009Payload = {\n authorization,\n signature,\n };\n\n return {\n x402Version,\n payload,\n };\n}\n\n/**\n * Sign the EIP-3009 authorization using EIP-712.\n *\n * @param signer - The EVM signer\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\nasync function signEIP3009Authorization(\n signer: ClientEvmSigner,\n authorization: ExactEIP3009Payload[\"authorization\"],\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n}\n","import {\n SchemeNetworkClient,\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { AssetTransferMethod } from \"../../types\";\nimport { createEIP3009Payload } from \"./eip3009\";\nimport { createPermit2Payload } from \"./permit2\";\nimport {\n trySignEip2612PermitExtension,\n trySignErc20ApprovalExtension,\n} from \"../../shared/extensions\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\n\n/**\n * EVM client implementation for the Exact payment scheme.\n * Supports both EIP-3009 (transferWithAuthorization) and Permit2 flows.\n *\n * Routes to the appropriate authorization method based on\n * `requirements.extra.assetTransferMethod`. Defaults to EIP-3009\n * for backward compatibility with older facilitators.\n *\n * When the server advertises `eip2612GasSponsoring` and the asset transfer\n * method is `permit2`, the scheme automatically signs an EIP-2612 permit\n * if the user lacks Permit2 approval. This requires `readContract` on the signer.\n */\nexport class ExactEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClient instance.\n *\n * @param signer - The EVM signer for client operations.\n * Base flow only requires `address` + `signTypedData`.\n * Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally\n * requires optional capabilities like `readContract` and tx signing helpers.\n * @param options - Optional RPC configuration used to backfill extension capabilities.\n */\n constructor(\n private readonly signer: ClientEvmSigner,\n private readonly options?: ExactEvmSchemeOptions,\n ) {}\n\n /**\n * Creates a payment payload for the Exact scheme.\n * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.\n *\n * For Permit2 flows, if the server advertises `eip2612GasSponsoring` and the\n * signer supports `readContract`, automatically signs an EIP-2612 permit\n * when Permit2 allowance is insufficient.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @param context - Optional context with server-declared extensions\n * @returns Promise resolving to a payment payload result (with optional extensions)\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const assetTransferMethod =\n (paymentRequirements.extra?.assetTransferMethod as AssetTransferMethod) ?? \"eip3009\";\n\n if (assetTransferMethod === \"permit2\") {\n const result = await createPermit2Payload(this.signer, x402Version, paymentRequirements);\n\n const eip2612Extensions = await trySignEip2612PermitExtension(\n this.signer,\n this.options,\n paymentRequirements,\n result,\n context,\n );\n\n if (eip2612Extensions) {\n return {\n ...result,\n extensions: eip2612Extensions,\n };\n }\n\n const erc20Extensions = await trySignErc20ApprovalExtension(\n this.signer,\n this.options,\n paymentRequirements,\n context,\n );\n if (erc20Extensions) {\n return {\n ...result,\n extensions: erc20Extensions,\n };\n }\n\n return result;\n }\n\n return createEIP3009Payload(this.signer, x402Version, paymentRequirements);\n }\n}\n","import { x402Client, SelectPaymentRequirements, PaymentPolicy } from \"@payai/x402/client\";\nimport { Network } from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\nimport { ExactEvmSchemeV1 } from \"../v1/client/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Client\n */\nexport interface EvmClientConfig {\n /**\n * The EVM signer to use for creating payment payloads\n */\n signer: ClientEvmSigner;\n\n /**\n * Optional payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Optional Exact EVM client scheme options.\n * Supports either a single config ({ rpcUrl }) or per-chain configs\n * keyed by EVM chain ID ({ 8453: { rpcUrl: \"...\" } }).\n */\n schemeOptions?: ExactEvmSchemeOptions;\n\n /**\n * Optional specific networks to register.\n * If not provided, registers wildcard support (eip155:*).\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Client instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param client - The x402Client instance to register schemes to\n * @param config - Configuration for EVM client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@payai/x402-evm/exact/client/register\";\n * import { x402Client } from \"@payai/x402/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const account = privateKeyToAccount(\"0x...\");\n * const client = new x402Client();\n * registerExactEvmScheme(client, { signer: account });\n * ```\n */\nexport function registerExactEvmScheme(client: x402Client, config: EvmClientConfig): x402Client {\n const evmScheme = new ExactEvmScheme(config.signer, config.schemeOptions);\n\n // Register V2 scheme\n // EIP-2612 gas sponsoring is handled internally by the scheme when the\n // server advertises support - no separate extension registration needed.\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n client.register(network, evmScheme);\n });\n } else {\n // Register wildcard for all EVM chains\n client.register(\"eip155:*\", evmScheme);\n }\n\n // Register all V1 networks\n NETWORKS.forEach(network => {\n client.registerV1(network as Network, new ExactEvmSchemeV1(config.signer));\n });\n\n // Apply policies if provided\n if (config.policies) {\n config.policies.forEach(policy => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/exact/client/eip3009.ts","../../src/exact/client/scheme.ts","../../src/exact/client/register.ts"],"sourcesContent":["import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\n\n/**\n * Creates an EIP-3009 (transferWithAuthorization) payload.\n *\n * @param signer - The EVM signer for client operations\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createEIP3009Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEIP3009Payload[\"authorization\"] = {\n from: signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(),\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n const signature = await signEIP3009Authorization(signer, authorization, paymentRequirements);\n\n const payload: ExactEIP3009Payload = {\n authorization,\n signature,\n };\n\n return {\n x402Version,\n payload,\n };\n}\n\n/**\n * Sign the EIP-3009 authorization using EIP-712.\n *\n * @param signer - The EVM signer\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\nasync function signEIP3009Authorization(\n signer: ClientEvmSigner,\n authorization: ExactEIP3009Payload[\"authorization\"],\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n}\n","import {\n SchemeNetworkClient,\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { AssetTransferMethod } from \"../../types\";\nimport { createEIP3009Payload } from \"./eip3009\";\nimport { createPermit2Payload } from \"./permit2\";\nimport {\n trySignEip2612PermitExtension,\n trySignErc20ApprovalExtension,\n} from \"../../shared/extensions\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\n\n/**\n * EVM client implementation for the Exact payment scheme.\n * Supports both EIP-3009 (transferWithAuthorization) and Permit2 flows.\n *\n * Routes to the appropriate authorization method based on\n * `requirements.extra.assetTransferMethod`. Defaults to EIP-3009\n * for backward compatibility with older facilitators.\n *\n * When the server advertises `eip2612GasSponsoring` and the asset transfer\n * method is `permit2`, the scheme automatically signs an EIP-2612 permit\n * if the user lacks Permit2 approval. This requires `readContract` on the signer.\n */\nexport class ExactEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClient instance.\n *\n * @param signer - The EVM signer for client operations.\n * Base flow only requires `address` + `signTypedData`.\n * Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally\n * requires optional capabilities like `readContract` and tx signing helpers.\n * @param options - Optional RPC configuration used to backfill extension capabilities.\n */\n constructor(\n private readonly signer: ClientEvmSigner,\n private readonly options?: ExactEvmSchemeOptions,\n ) {}\n\n /**\n * Creates a payment payload for the Exact scheme.\n * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.\n *\n * For Permit2 flows, if the server advertises `eip2612GasSponsoring` and the\n * signer supports `readContract`, automatically signs an EIP-2612 permit\n * when Permit2 allowance is insufficient.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @param context - Optional context with server-declared extensions\n * @returns Promise resolving to a payment payload result (with optional extensions)\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const assetTransferMethod =\n (paymentRequirements.extra?.assetTransferMethod as AssetTransferMethod) ?? \"eip3009\";\n\n if (assetTransferMethod === \"permit2\") {\n const result = await createPermit2Payload(this.signer, x402Version, paymentRequirements);\n\n const eip2612Extensions = await trySignEip2612PermitExtension(\n this.signer,\n this.options,\n paymentRequirements,\n result,\n context,\n );\n\n if (eip2612Extensions) {\n return {\n ...result,\n extensions: eip2612Extensions,\n };\n }\n\n const erc20Extensions = await trySignErc20ApprovalExtension(\n this.signer,\n this.options,\n paymentRequirements,\n context,\n );\n if (erc20Extensions) {\n return {\n ...result,\n extensions: erc20Extensions,\n };\n }\n\n return result;\n }\n\n return createEIP3009Payload(this.signer, x402Version, paymentRequirements);\n }\n}\n","import { x402Client, SelectPaymentRequirements, PaymentPolicy } from \"@payai/x402/client\";\nimport { Network } from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\nimport { ExactEvmSchemeV1 } from \"../v1/client/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Client\n */\nexport interface EvmClientConfig {\n /**\n * The EVM signer to use for creating payment payloads\n */\n signer: ClientEvmSigner;\n\n /**\n * Optional payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Optional Exact EVM client scheme options.\n * Supports either a single config ({ rpcUrl }) or per-chain configs\n * keyed by EVM chain ID ({ 8453: { rpcUrl: \"...\" } }).\n */\n schemeOptions?: ExactEvmSchemeOptions;\n\n /**\n * Optional specific networks to register.\n * If not provided, registers wildcard support (eip155:*).\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Client instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param client - The x402Client instance to register schemes to\n * @param config - Configuration for EVM client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@payai/x402-evm/exact/client/register\";\n * import { x402Client } from \"@payai/x402/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const account = privateKeyToAccount(\"0x...\");\n * const client = new x402Client();\n * registerExactEvmScheme(client, { signer: account });\n * ```\n */\nexport function registerExactEvmScheme(client: x402Client, config: EvmClientConfig): x402Client {\n const evmScheme = new ExactEvmScheme(config.signer, config.schemeOptions);\n\n // Register V2 scheme\n // EIP-2612 gas sponsoring is handled internally by the scheme when the\n // server advertises support - no separate extension registration needed.\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n client.register(network, evmScheme);\n });\n } else {\n // Register wildcard for all EVM chains\n client.register(\"eip155:*\", evmScheme);\n }\n\n // Register all V1 networks\n NETWORKS.forEach(network => {\n client.registerV1(network as Network, new ExactEvmSchemeV1(config.signer));\n });\n\n // Apply policies if provided\n if (config.policies) {\n config.policies.forEach(policy => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ validateEip2612GasSponsoringInfo,
3
+ validateErc20ApprovalGasSponsoringInfo
4
+ } from "./chunk-GD4MKCN7.mjs";
1
5
  import {
2
6
  ErrEip2612AssetMismatch,
3
7
  ErrEip2612DeadlineExpired,
@@ -28,65 +32,25 @@ import {
28
32
  ErrPermit2PaymentTooEarly,
29
33
  ErrPermit2ProxyNotDeployed,
30
34
  ErrPermit2SimulationFailed,
31
- ErrTransactionFailed,
35
+ ErrTransactionFailed
36
+ } from "./chunk-TGFAVNUD.mjs";
37
+ import {
32
38
  PERMIT2_ADDRESS,
33
- createPermit2Nonce,
34
39
  eip3009ABI,
35
40
  erc20AllowanceAbi,
36
41
  erc20ApproveAbi,
37
- getEvmChainId,
38
- multicall,
39
42
  permit2WitnessTypes
40
- } from "./chunk-C4ZQMS77.mjs";
41
-
42
- // src/exact/extensions.ts
43
- var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
44
- var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
45
- var ERC20_APPROVAL_GAS_SPONSORING_VERSION = "1";
46
- function _extractInfo(payload, extensionKey) {
47
- const extensions = payload.extensions;
48
- if (!extensions) return null;
49
- const extension = extensions[extensionKey];
50
- if (!extension?.info) return null;
51
- return extension.info;
52
- }
53
- function extractEip2612GasSponsoringInfo(payload) {
54
- const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);
55
- if (!info) return null;
56
- if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
57
- return null;
58
- }
59
- return info;
60
- }
61
- function validateEip2612GasSponsoringInfo(info) {
62
- const addressPattern = /^0x[a-fA-F0-9]{40}$/;
63
- const numericPattern = /^[0-9]+$/;
64
- const hexPattern = /^0x[a-fA-F0-9]+$/;
65
- const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
66
- return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && numericPattern.test(info.nonce) && numericPattern.test(info.deadline) && hexPattern.test(info.signature) && versionPattern.test(info.version);
67
- }
68
- function extractErc20ApprovalGasSponsoringInfo(payload) {
69
- const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);
70
- if (!info) return null;
71
- if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
72
- return null;
73
- }
74
- return info;
75
- }
76
- function validateErc20ApprovalGasSponsoringInfo(info) {
77
- const addressPattern = /^0x[a-fA-F0-9]{40}$/;
78
- const numericPattern = /^[0-9]+$/;
79
- const hexPattern = /^0x[a-fA-F0-9]+$/;
80
- const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
81
- return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && hexPattern.test(info.signedTransaction) && versionPattern.test(info.version);
82
- }
83
- function resolveErc20ApprovalExtensionSigner(extension, network) {
84
- if (!extension) return void 0;
85
- return extension.signerForNetwork?.(network) ?? extension.signer;
86
- }
43
+ } from "./chunk-MACPBXCT.mjs";
44
+ import {
45
+ multicall
46
+ } from "./chunk-VS3RYAYE.mjs";
47
+ import {
48
+ createPermit2Nonce,
49
+ getEvmChainId
50
+ } from "./chunk-TW7Z65AO.mjs";
87
51
 
88
52
  // src/shared/permit2.ts
89
- import { getAddress as getAddress2, encodeFunctionData } from "viem";
53
+ import { getAddress as getAddress2, encodeFunctionData, parseErc6492Signature } from "viem";
90
54
 
91
55
  // src/shared/erc20approval.ts
92
56
  import {
@@ -401,6 +365,7 @@ async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, am
401
365
  return { isValid: true, invalidReason: void 0, payer };
402
366
  }
403
367
  function buildExactPermit2SettleArgs(permit2Payload) {
368
+ const { signature } = parseErc6492Signature(permit2Payload.signature);
404
369
  return [
405
370
  {
406
371
  permitted: {
@@ -415,10 +380,11 @@ function buildExactPermit2SettleArgs(permit2Payload) {
415
380
  to: getAddress2(permit2Payload.permit2Authorization.witness.to),
416
381
  validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
417
382
  },
418
- permit2Payload.signature
383
+ signature
419
384
  ];
420
385
  }
421
386
  function buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress) {
387
+ const { signature } = parseErc6492Signature(permit2Payload.signature);
422
388
  return [
423
389
  {
424
390
  permitted: {
@@ -435,7 +401,7 @@ function buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitato
435
401
  facilitator: getAddress2(facilitatorAddress),
436
402
  validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
437
403
  },
438
- permit2Payload.signature
404
+ signature
439
405
  ];
440
406
  }
441
407
  function splitEip2612Signature(signature) {
@@ -502,12 +468,6 @@ async function signPermit2Authorization(signer, permit2Authorization, requiremen
502
468
  }
503
469
 
504
470
  export {
505
- EIP2612_GAS_SPONSORING_KEY,
506
- ERC20_APPROVAL_GAS_SPONSORING_KEY,
507
- ERC20_APPROVAL_GAS_SPONSORING_VERSION,
508
- extractEip2612GasSponsoringInfo,
509
- extractErc20ApprovalGasSponsoringInfo,
510
- resolveErc20ApprovalExtensionSigner,
511
471
  validateErc20ApprovalForPayment,
512
472
  ErrUptoInvalidScheme,
513
473
  ErrUptoNetworkMismatch,
@@ -526,4 +486,4 @@ export {
526
486
  splitEip2612Signature,
527
487
  createPermit2PayloadForProxy
528
488
  };
529
- //# sourceMappingURL=chunk-CRT6YNY5.mjs.map
489
+ //# sourceMappingURL=chunk-RWLVVO3B.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/permit2.ts","../../src/shared/erc20approval.ts","../../src/upto/facilitator/errors.ts"],"sourcesContent":["import {\n PaymentPayload,\n PaymentPayloadResult,\n PaymentRequirements,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@payai/x402/types\";\nimport {\n extractEip2612GasSponsoringInfo,\n validateEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../exact/extensions\";\nimport { getAddress, encodeFunctionData, parseErc6492Signature } from \"viem\";\nimport { PERMIT2_ADDRESS, eip3009ABI, erc20AllowanceAbi, permit2WitnessTypes } from \"../constants\";\nimport { multicall, ContractCall } from \"../multicall\";\nimport { createPermit2Nonce, getEvmChainId } from \"../utils\";\nimport {\n ErrPermit2612AmountMismatch,\n ErrPermit2InvalidAmount,\n ErrPermit2InvalidDestination,\n ErrPermit2InvalidNonce,\n ErrPermit2InvalidOwner,\n ErrPermit2InvalidSignature,\n ErrPermit2PaymentTooEarly,\n ErrPermit2AllowanceRequired,\n ErrPermit2SimulationFailed,\n ErrPermit2InsufficientBalance,\n ErrPermit2ProxyNotDeployed,\n ErrInvalidTransactionState,\n ErrTransactionFailed,\n ErrInvalidEip2612ExtensionFormat,\n ErrEip2612FromMismatch,\n ErrEip2612AssetMismatch,\n ErrEip2612SpenderNotPermit2,\n ErrEip2612DeadlineExpired,\n ErrErc20ApprovalTxFailed,\n} from \"../exact/facilitator/errors\";\nimport { ClientEvmSigner, FacilitatorEvmSigner } from \"../signer\";\nimport { ExactPermit2Payload, Permit2Authorization, UptoPermit2Payload } from \"../types\";\nimport { validateErc20ApprovalForPayment } from \"./erc20approval\";\nimport {\n ErrUptoAmountExceedsPermitted,\n ErrUptoUnauthorizedFacilitator,\n} from \"../upto/facilitator/errors\";\n\n/**\n * Base type for Permit2 payloads shared between exact and upto schemes.\n * Both {@link ExactPermit2Payload} and {@link UptoPermit2Payload} satisfy this type.\n */\nexport type Permit2PayloadBase = ExactPermit2Payload | UptoPermit2Payload;\n\n/**\n * Configuration for the Permit2 proxy contract used during settlement.\n * The exact and upto schemes use different proxy addresses and ABIs.\n */\nexport type Permit2ProxyConfig = {\n /** The deployed proxy contract address. */\n proxyAddress: `0x${string}`;\n /** The proxy contract ABI (must include settle and settleWithPermit functions). */\n proxyABI: readonly Record<string, unknown>[];\n};\n\n/**\n * Checks Permit2 allowance and validates gas sponsoring extensions if allowance is insufficient.\n *\n * When the on-chain ERC-20 allowance to the Permit2 contract is below the required amount,\n * this function falls back to validating EIP-2612 or ERC-20 approval gas sponsoring extensions\n * attached to the payment payload.\n *\n * @param signer - The facilitator signer for on-chain reads\n * @param payload - The payment payload\n * @param requirements - The payment requirements\n * @param payer - The payer address\n * @param tokenAddress - The token contract address\n * @param context - Optional facilitator context for extension lookup\n * @returns A VerifyResponse if verification should stop (failure), or null to continue\n */\nexport async function verifyPermit2Allowance(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n context?: FacilitatorContext,\n): Promise<VerifyResponse | null> {\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(requirements.amount)) {\n return null; // Sufficient allowance, continue verification\n }\n\n // Allowance insufficient — try EIP-2612 gas sponsoring first\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null; // EIP-2612 is valid, allowance will be set atomically during settlement\n }\n\n // Try ERC-20 approval gas sponsoring as fallback\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n if (erc20GasSponsorshipExtension) {\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const result = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null; // ERC-20 approval is valid, will be broadcast before settlement\n }\n }\n\n return { isValid: false, invalidReason: \"permit2_allowance_required\", payer };\n } catch {\n // Allowance check failed — validate extensions if present; fail closed if none valid\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null;\n }\n\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n if (erc20GasSponsorshipExtension) {\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const result = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null;\n }\n }\n\n return { isValid: false, invalidReason: \"permit2_allowance_required\", payer };\n }\n}\n\n/**\n * Waits for a transaction receipt and returns the appropriate SettleResponse.\n *\n * @param signer - Signer with waitForTransactionReceipt capability\n * @param tx - The transaction hash to wait for\n * @param payload - The payment payload (for network info)\n * @param payer - The payer address\n * @returns Promise resolving to a settlement response indicating success or failure\n */\nexport async function waitAndReturnSettleResponse(\n signer: Pick<FacilitatorEvmSigner, \"waitForTransactionReceipt\">,\n tx: `0x${string}`,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): Promise<SettleResponse> {\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: ErrInvalidTransactionState,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n}\n\n/**\n * Maps contract revert errors to structured SettleResponse error reasons.\n *\n * Inspects the error message for known contract revert strings and maps them\n * to the corresponding error reason constants. Falls back to a generic\n * \"transaction_failed\" reason with truncated message for unrecognized errors.\n *\n * @param error - The caught error (typically from a contract write)\n * @param payload - The payment payload (for network info)\n * @param payer - The payer address\n * @returns A failed SettleResponse with the mapped error reason\n */\nexport function mapSettleError(\n error: unknown,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): SettleResponse {\n let errorReason: string = ErrTransactionFailed;\n if (error instanceof Error) {\n const message = error.message;\n if (message.includes(\"Permit2612AmountMismatch\")) {\n errorReason = ErrPermit2612AmountMismatch;\n } else if (message.includes(\"InvalidAmount\")) {\n errorReason = ErrPermit2InvalidAmount;\n } else if (message.includes(\"InvalidDestination\")) {\n errorReason = ErrPermit2InvalidDestination;\n } else if (message.includes(\"InvalidOwner\")) {\n errorReason = ErrPermit2InvalidOwner;\n } else if (message.includes(\"PaymentTooEarly\")) {\n errorReason = ErrPermit2PaymentTooEarly;\n } else if (message.includes(\"InvalidSignature\") || message.includes(\"SignatureExpired\")) {\n errorReason = ErrPermit2InvalidSignature;\n } else if (message.includes(\"InvalidNonce\")) {\n errorReason = ErrPermit2InvalidNonce;\n } else if (message.includes(\"erc20_approval_tx_failed\")) {\n errorReason = ErrErc20ApprovalTxFailed;\n } else if (message.includes(\"AmountExceedsPermitted\")) {\n errorReason = ErrUptoAmountExceedsPermitted;\n } else if (message.includes(\"UnauthorizedFacilitator\")) {\n errorReason = ErrUptoUnauthorizedFacilitator;\n } else {\n errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;\n }\n }\n return {\n success: false,\n errorReason,\n transaction: \"\",\n network: payload.accepted.network,\n payer,\n };\n}\n\n/**\n * Validates EIP-2612 permit extension data for a Permit2 payment.\n *\n * Checks that the permit extension has a valid format and that the from address,\n * asset address, spender address, and deadline all match expectations.\n *\n * @param info - The EIP-2612 gas sponsoring info extracted from the payment payload\n * @param payer - The expected payer address\n * @param tokenAddress - The expected token address\n * @returns Validation result with isValid flag and optional invalidReason string\n */\nexport function validateEip2612PermitForPayment(\n info: Eip2612GasSponsoringInfo,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n): { isValid: boolean; invalidReason?: string } {\n if (!validateEip2612GasSponsoringInfo(info)) {\n return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };\n }\n\n if (getAddress(info.from as `0x${string}`) !== getAddress(payer)) {\n return { isValid: false, invalidReason: ErrEip2612FromMismatch };\n }\n\n if (getAddress(info.asset as `0x${string}`) !== tokenAddress) {\n return { isValid: false, invalidReason: ErrEip2612AssetMismatch };\n }\n\n if (getAddress(info.spender as `0x${string}`) !== getAddress(PERMIT2_ADDRESS)) {\n return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(info.deadline) < BigInt(now + 6)) {\n return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };\n }\n\n return { isValid: true };\n}\n\n// ---------------------------------------------------------------------------\n// Simulation helpers (shared across exact and upto)\n// ---------------------------------------------------------------------------\n\n/**\n * Simulates settle() via eth_call (readContract).\n * Returns true if simulation succeeded, false if it failed.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\n * @returns true if simulation succeeded, false if it failed\n */\nexport async function simulatePermit2Settle(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n settleArgs: readonly unknown[],\n): Promise<boolean> {\n try {\n await signer.readContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settle\",\n args: settleArgs,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Simulates settleWithPermit() via eth_call (readContract).\n * The contract atomically calls token.permit() then PERMIT2.permitTransferFrom(),\n * so simulation covers allowance + balance + nonces.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\n * @param eip2612Info - EIP-2612 gas sponsoring info from the payload extension\n * @returns true if simulation succeeded, false if it failed\n */\nexport async function simulatePermit2SettleWithPermit(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n settleArgs: readonly unknown[],\n eip2612Info: Eip2612GasSponsoringInfo,\n): Promise<boolean> {\n try {\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n\n await signer.readContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settleWithPermit\",\n args: [\n {\n value: BigInt(eip2612Info.amount),\n deadline: BigInt(eip2612Info.deadline),\n r,\n s,\n v,\n },\n ...settleArgs,\n ],\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Delegates the full approve+settle simulation flow to the extension signer via simulateTransactions.\n * The signer owns execution strategy.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param extensionSigner - The extension signer with simulateTransactions capability\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\n * @param erc20Info - Object containing the signed approval transaction\n * @param erc20Info.signedTransaction - The RLP-encoded signed ERC-20 approve transaction hex string\n * @returns true if the bundle simulation succeeded, false otherwise\n */\nexport async function simulatePermit2SettleWithErc20Approval(\n config: Permit2ProxyConfig,\n extensionSigner: Erc20ApprovalGasSponsoringSigner,\n settleArgs: readonly unknown[],\n erc20Info: { signedTransaction: string },\n): Promise<boolean> {\n if (!extensionSigner.simulateTransactions) {\n return false;\n }\n\n try {\n const settleData = encodeFunctionData({\n abi: config.proxyABI,\n functionName: \"settle\",\n args: settleArgs,\n });\n\n return await extensionSigner.simulateTransactions([\n erc20Info.signedTransaction as `0x${string}`,\n { to: config.proxyAddress, data: settleData, gas: BigInt(300_000) },\n ]);\n } catch {\n return false;\n }\n}\n\n/**\n * Diagnoses a Permit2 simulation failure by performing a multicall to check the proxy deployment, balance and allowance.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param tokenAddress - ERC-20 token contract address\n * @param permit2Payload - The Permit2 authorization payload\n * @param amountRequired - Required payment amount (as string)\n * @returns VerifyResponse with the most specific failure reason\n */\nexport async function diagnosePermit2SimulationFailure(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n permit2Payload: Permit2PayloadBase,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const diagnosticCalls: ContractCall[] = [\n {\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"PERMIT2\",\n },\n {\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n },\n {\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [payer, PERMIT2_ADDRESS],\n },\n ];\n\n try {\n const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);\n\n const [proxyResult, balanceResult, allowanceResult] = results;\n\n if (proxyResult.status === \"failure\") {\n return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };\n }\n\n if (balanceResult.status === \"success\") {\n const balance = balanceResult.result as bigint;\n if (balance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };\n }\n }\n\n if (allowanceResult.status === \"success\") {\n const allowance = allowanceResult.result as bigint;\n if (allowance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: ErrPermit2AllowanceRequired, payer };\n }\n }\n } catch {\n // Diagnostic multicall itself failed — fall through to generic error\n }\n\n return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };\n}\n\n/**\n * Targeted multicall for the ERC-20 approval path where simulation cannot be used\n * (the approval hasn't been broadcast yet, so settle() would fail for expected reasons).\n * Checks proxy deployment, payer token balance and payer ETH balance for gas.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param tokenAddress - ERC-20 token contract address\n * @param payer - The payer address\n * @param amountRequired - Required payment amount (as string)\n * @returns VerifyResponse — valid if checks pass, otherwise the most specific failure\n */\nexport async function checkPermit2Prerequisites(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n payer: `0x${string}`,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const diagnosticCalls: ContractCall[] = [\n {\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"PERMIT2\",\n },\n {\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n },\n ];\n\n try {\n const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);\n\n const [proxyResult, balanceResult] = results;\n\n if (proxyResult.status === \"failure\") {\n return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };\n }\n\n if (balanceResult.status === \"success\") {\n const balance = balanceResult.result as bigint;\n if (balance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };\n }\n }\n } catch {\n // Multicall failed — fall through to valid (fail open for prerequisites-only check)\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n}\n\n/**\n * Builds args for exact settle(permit, owner, witness, signature).\n *\n * @param permit2Payload - The Permit2 payload containing authorization and signature data\n * @returns Tuple of contract call arguments for the exact settle function\n */\nexport function buildExactPermit2SettleArgs(permit2Payload: Permit2PayloadBase) {\n const { signature } = parseErc6492Signature(permit2Payload.signature);\n\n return [\n {\n permitted: {\n token: getAddress(permit2Payload.permit2Authorization.permitted.token),\n amount: BigInt(permit2Payload.permit2Authorization.permitted.amount),\n },\n nonce: BigInt(permit2Payload.permit2Authorization.nonce),\n deadline: BigInt(permit2Payload.permit2Authorization.deadline),\n },\n getAddress(permit2Payload.permit2Authorization.from),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n signature,\n ] as const;\n}\n\n/**\n * Builds args for upto settle(permit, amount, owner, witness, signature).\n * The upto contract's settle() takes an additional `amount` parameter and the witness\n * includes a `facilitator` field.\n *\n * @param permit2Payload - The upto Permit2 payload containing authorization and signature data\n * @param settlementAmount - The amount to settle on-chain\n * @param facilitatorAddress - The facilitator address authorized in the witness\n * @returns Tuple of contract call arguments for the upto settle function\n */\nexport function buildUptoPermit2SettleArgs(\n permit2Payload: UptoPermit2Payload,\n settlementAmount: bigint,\n facilitatorAddress: `0x${string}`,\n) {\n const { signature } = parseErc6492Signature(permit2Payload.signature);\n\n return [\n {\n permitted: {\n token: getAddress(permit2Payload.permit2Authorization.permitted.token),\n amount: BigInt(permit2Payload.permit2Authorization.permitted.amount),\n },\n nonce: BigInt(permit2Payload.permit2Authorization.nonce),\n deadline: BigInt(permit2Payload.permit2Authorization.deadline),\n },\n settlementAmount,\n getAddress(permit2Payload.permit2Authorization.from),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n facilitator: getAddress(facilitatorAddress),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n signature,\n ] as const;\n}\n\n/**\n * Splits a 65-byte EIP-2612 signature into v, r, s components.\n *\n * @param signature - The hex-encoded 65-byte signature (with or without 0x prefix)\n * @returns Object with v (uint8), r (bytes32 hex), s (bytes32 hex)\n * @throws Error if the signature is not exactly 65 bytes (130 hex chars)\n */\nexport function splitEip2612Signature(signature: string): {\n v: number;\n r: `0x${string}`;\n s: `0x${string}`;\n} {\n const sig = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sig.length !== 130) {\n throw new Error(\n `invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`,\n );\n }\n\n const r = `0x${sig.slice(0, 64)}` as `0x${string}`;\n const s = `0x${sig.slice(64, 128)}` as `0x${string}`;\n const v = parseInt(sig.slice(128, 130), 16);\n\n return { v, r, s };\n}\n\n// ---------------------------------------------------------------------------\n// Client-side helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a Permit2 payload for any scheme (exact or upto).\n * The only scheme-specific input is the proxy address used as the spender.\n *\n * @param proxyAddress - The x402 proxy contract address to set as spender\n * @param signer - The EVM client signer\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createPermit2PayloadForProxy(\n proxyAddress: `0x${string}`,\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const now = Math.floor(Date.now() / 1000);\n const nonce = createPermit2Nonce();\n\n // Lower time bound - allow some clock skew\n const validAfter = (now - 600).toString();\n // Upper time bound is enforced by Permit2's deadline field\n const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();\n\n const permit2Authorization: Permit2Authorization & { from: `0x${string}` } = {\n from: signer.address,\n permitted: {\n token: getAddress(paymentRequirements.asset),\n amount: paymentRequirements.amount,\n },\n spender: proxyAddress,\n nonce,\n deadline,\n witness: {\n to: getAddress(paymentRequirements.payTo),\n validAfter,\n },\n };\n\n const signature = await signPermit2Authorization(\n signer,\n permit2Authorization,\n paymentRequirements,\n );\n\n return {\n x402Version,\n payload: { signature, permit2Authorization },\n };\n}\n\n/**\n * Signs a Permit2 authorization using EIP-712 with witness data.\n * The signature authorizes the proxy contract to transfer tokens on behalf of the signer.\n *\n * @param signer - The EVM client signer\n * @param permit2Authorization - The Permit2 authorization parameters\n * @param requirements - The payment requirements\n * @returns Promise resolving to the hex-encoded signature\n */\nasync function signPermit2Authorization(\n signer: ClientEvmSigner,\n permit2Authorization: Permit2Authorization & { from: `0x${string}` },\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n return await signer.signTypedData({\n domain: { name: \"Permit2\", chainId, verifyingContract: PERMIT2_ADDRESS },\n types: permit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message: {\n permitted: {\n token: getAddress(permit2Authorization.permitted.token),\n amount: BigInt(permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Authorization.spender),\n nonce: BigInt(permit2Authorization.nonce),\n deadline: BigInt(permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Authorization.witness.to),\n validAfter: BigInt(permit2Authorization.witness.validAfter),\n },\n },\n });\n}\n","import {\n getAddress,\n parseTransaction,\n decodeFunctionData,\n recoverTransactionAddress,\n type TransactionSerialized,\n} from \"viem\";\nimport type { VerifyResponse } from \"@payai/x402/types\";\nimport {\n validateErc20ApprovalGasSponsoringInfo,\n type Erc20ApprovalGasSponsoringInfo,\n} from \"../exact/extensions\";\nimport { PERMIT2_ADDRESS, erc20ApproveAbi } from \"../constants\";\nimport {\n ErrErc20ApprovalInvalidFormat,\n ErrErc20ApprovalFromMismatch,\n ErrErc20ApprovalAssetMismatch,\n ErrErc20ApprovalSpenderNotPermit2,\n ErrErc20ApprovalTxWrongTarget,\n ErrErc20ApprovalTxWrongSelector,\n ErrErc20ApprovalTxWrongSpender,\n ErrErc20ApprovalTxInvalidCalldata,\n ErrErc20ApprovalTxSignerMismatch,\n ErrErc20ApprovalTxInvalidSignature,\n ErrErc20ApprovalTxParseFailed,\n} from \"../exact/facilitator/errors\";\n\n/** The approve(address,uint256) function selector */\nconst APPROVE_SELECTOR = \"0x095ea7b3\";\n\n/**\n * Validates ERC-20 approval extension data for a Permit2 payment.\n *\n * Performs comprehensive validation:\n * - Format validation via validateErc20ApprovalGasSponsoringInfo (JSON Schema)\n * - `from` matches payer\n * - `asset` matches token\n * - `spender` is PERMIT2_ADDRESS\n * - Transaction `to` matches token address\n * - Transaction calldata is a valid approve(PERMIT2_ADDRESS, ...) call\n * - Recovered transaction signer matches `from`\n *\n * @param info - The ERC-20 approval gas sponsoring info\n * @param payer - The expected payer address\n * @param tokenAddress - The expected token address\n * @returns Validation result with invalidReason and invalidMessage on failure\n */\nexport async function validateErc20ApprovalForPayment(\n info: Erc20ApprovalGasSponsoringInfo,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n): Promise<Pick<VerifyResponse, \"isValid\" | \"invalidReason\" | \"invalidMessage\">> {\n if (!validateErc20ApprovalGasSponsoringInfo(info)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalInvalidFormat,\n invalidMessage: \"ERC-20 approval extension info failed schema validation\",\n };\n }\n\n if (getAddress(info.from) !== getAddress(payer)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalFromMismatch,\n invalidMessage: `Expected from=${payer}, got ${info.from}`,\n };\n }\n\n if (getAddress(info.asset) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalAssetMismatch,\n invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`,\n };\n }\n\n if (getAddress(info.spender) !== getAddress(PERMIT2_ADDRESS)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalSpenderNotPermit2,\n invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`,\n };\n }\n\n try {\n const serializedTx = info.signedTransaction as TransactionSerialized;\n const tx = parseTransaction(serializedTx);\n\n if (!tx.to || getAddress(tx.to) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongTarget,\n invalidMessage: `Transaction targets ${tx.to ?? \"null\"}, expected ${tokenAddress}`,\n };\n }\n\n const data = tx.data ?? \"0x\";\n if (!data.startsWith(APPROVE_SELECTOR)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongSelector,\n invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`,\n };\n }\n\n try {\n const decoded = decodeFunctionData({\n abi: erc20ApproveAbi,\n data: data as `0x${string}`,\n });\n const calldataSpender = getAddress(decoded.args[0] as `0x${string}`);\n if (calldataSpender !== getAddress(PERMIT2_ADDRESS)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongSpender,\n invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxInvalidCalldata,\n invalidMessage: \"Failed to decode approve() calldata from the signed transaction\",\n };\n }\n\n try {\n const recoveredAddress = await recoverTransactionAddress({\n serializedTransaction: serializedTx,\n });\n if (getAddress(recoveredAddress) !== getAddress(payer)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxSignerMismatch,\n invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxInvalidSignature,\n invalidMessage: \"Failed to recover signer from the signed transaction\",\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxParseFailed,\n invalidMessage: \"Failed to parse the signed transaction\",\n };\n }\n\n return { isValid: true };\n}\n","/**\n * Named error reason constants for the upto EVM facilitator.\n *\n * Shared Permit2 errors are re-exported from exact/facilitator/errors.ts.\n * Upto-specific errors are defined here.\n *\n * These strings must be character-for-character identical to the Go constants\n * to maintain cross-SDK parity.\n */\n\n// Re-export shared Permit2 errors\nexport {\n ErrPermit2InvalidSpender,\n ErrPermit2RecipientMismatch,\n ErrPermit2DeadlineExpired,\n ErrPermit2NotYetValid,\n ErrPermit2AmountMismatch,\n ErrPermit2TokenMismatch,\n ErrPermit2InvalidSignature,\n ErrPermit2AllowanceRequired,\n ErrPermit2InvalidAmount,\n ErrPermit2InvalidDestination,\n ErrPermit2InvalidOwner,\n ErrPermit2PaymentTooEarly,\n ErrPermit2InvalidNonce,\n ErrPermit2612AmountMismatch,\n ErrErc20ApprovalInvalidFormat,\n ErrErc20ApprovalFromMismatch,\n ErrErc20ApprovalAssetMismatch,\n ErrErc20ApprovalSpenderNotPermit2,\n ErrErc20ApprovalTxWrongTarget,\n ErrErc20ApprovalTxWrongSelector,\n ErrErc20ApprovalTxWrongSpender,\n ErrErc20ApprovalTxInvalidCalldata,\n ErrErc20ApprovalTxSignerMismatch,\n ErrErc20ApprovalTxInvalidSignature,\n ErrErc20ApprovalTxParseFailed,\n} from \"../../exact/facilitator/errors\";\n\n// Upto-specific errors\nexport const ErrUptoInvalidScheme = \"invalid_upto_evm_scheme\";\nexport const ErrUptoNetworkMismatch = \"invalid_upto_evm_network_mismatch\";\nexport const ErrUptoSettlementExceedsAmount = \"invalid_upto_evm_payload_settlement_exceeds_amount\";\nexport const ErrUptoAmountExceedsPermitted = \"upto_amount_exceeds_permitted\";\nexport const ErrUptoUnauthorizedFacilitator = \"upto_unauthorized_facilitator\";\nexport const ErrUptoFacilitatorMismatch = \"upto_facilitator_mismatch\";\n"],"mappings":"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","names":["getAddress","getAddress"]}
@@ -0,0 +1,111 @@
1
+ // src/exact/facilitator/errors.ts
2
+ var ErrInvalidScheme = "invalid_exact_evm_scheme";
3
+ var ErrNetworkMismatch = "invalid_exact_evm_network_mismatch";
4
+ var ErrMissingEip712Domain = "invalid_exact_evm_missing_eip712_domain";
5
+ var ErrRecipientMismatch = "invalid_exact_evm_recipient_mismatch";
6
+ var ErrInvalidSignature = "invalid_exact_evm_signature";
7
+ var ErrValidBeforeExpired = "invalid_exact_evm_payload_authorization_valid_before";
8
+ var ErrValidAfterInFuture = "invalid_exact_evm_payload_authorization_valid_after";
9
+ var ErrInvalidAuthorizationValue = "invalid_exact_evm_authorization_value";
10
+ var ErrUndeployedSmartWallet = "invalid_exact_evm_payload_undeployed_smart_wallet";
11
+ var ErrTransactionFailed = "invalid_exact_evm_transaction_failed";
12
+ var ErrEip3009TokenNameMismatch = "invalid_exact_evm_token_name_mismatch";
13
+ var ErrEip3009TokenVersionMismatch = "invalid_exact_evm_token_version_mismatch";
14
+ var ErrEip3009NotSupported = "invalid_exact_evm_eip3009_not_supported";
15
+ var ErrEip3009NonceAlreadyUsed = "invalid_exact_evm_nonce_already_used";
16
+ var ErrEip3009InsufficientBalance = "invalid_exact_evm_insufficient_balance";
17
+ var ErrEip3009SimulationFailed = "invalid_exact_evm_transaction_simulation_failed";
18
+ var ErrPermit2InvalidSpender = "invalid_permit2_spender";
19
+ var ErrPermit2RecipientMismatch = "invalid_permit2_recipient_mismatch";
20
+ var ErrPermit2DeadlineExpired = "permit2_deadline_expired";
21
+ var ErrPermit2NotYetValid = "permit2_not_yet_valid";
22
+ var ErrPermit2AmountMismatch = "permit2_amount_mismatch";
23
+ var ErrPermit2TokenMismatch = "permit2_token_mismatch";
24
+ var ErrPermit2InvalidSignature = "invalid_permit2_signature";
25
+ var ErrPermit2AllowanceRequired = "permit2_allowance_required";
26
+ var ErrPermit2SimulationFailed = "permit2_simulation_failed";
27
+ var ErrPermit2InsufficientBalance = "permit2_insufficient_balance";
28
+ var ErrPermit2ProxyNotDeployed = "permit2_proxy_not_deployed";
29
+ var ErrPermit2InvalidAmount = "permit2_invalid_amount";
30
+ var ErrPermit2InvalidDestination = "permit2_invalid_destination";
31
+ var ErrPermit2InvalidOwner = "permit2_invalid_owner";
32
+ var ErrPermit2PaymentTooEarly = "permit2_payment_too_early";
33
+ var ErrPermit2InvalidNonce = "permit2_invalid_nonce";
34
+ var ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch";
35
+ var ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format";
36
+ var ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch";
37
+ var ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch";
38
+ var ErrErc20ApprovalSpenderNotPermit2 = "erc20_approval_spender_not_permit2";
39
+ var ErrErc20ApprovalTxWrongTarget = "erc20_approval_tx_wrong_target";
40
+ var ErrErc20ApprovalTxWrongSelector = "erc20_approval_tx_wrong_selector";
41
+ var ErrErc20ApprovalTxWrongSpender = "erc20_approval_tx_wrong_spender";
42
+ var ErrErc20ApprovalTxInvalidCalldata = "erc20_approval_tx_invalid_calldata";
43
+ var ErrErc20ApprovalTxSignerMismatch = "erc20_approval_tx_signer_mismatch";
44
+ var ErrErc20ApprovalTxInvalidSignature = "erc20_approval_tx_invalid_signature";
45
+ var ErrErc20ApprovalTxParseFailed = "erc20_approval_tx_parse_failed";
46
+ var ErrErc20ApprovalTxFailed = "erc20_approval_tx_failed";
47
+ var ErrInvalidEip2612ExtensionFormat = "invalid_eip2612_extension_format";
48
+ var ErrEip2612FromMismatch = "eip2612_from_mismatch";
49
+ var ErrEip2612AssetMismatch = "eip2612_asset_mismatch";
50
+ var ErrEip2612SpenderNotPermit2 = "eip2612_spender_not_permit2";
51
+ var ErrEip2612DeadlineExpired = "eip2612_deadline_expired";
52
+ var ErrUnsupportedPayloadType = "unsupported_payload_type";
53
+ var ErrInvalidTransactionState = "invalid_transaction_state";
54
+ var ErrFactoryNotAllowed = "eip6492_factory_not_allowed";
55
+
56
+ export {
57
+ ErrInvalidScheme,
58
+ ErrNetworkMismatch,
59
+ ErrMissingEip712Domain,
60
+ ErrRecipientMismatch,
61
+ ErrInvalidSignature,
62
+ ErrValidBeforeExpired,
63
+ ErrValidAfterInFuture,
64
+ ErrInvalidAuthorizationValue,
65
+ ErrUndeployedSmartWallet,
66
+ ErrTransactionFailed,
67
+ ErrEip3009TokenNameMismatch,
68
+ ErrEip3009TokenVersionMismatch,
69
+ ErrEip3009NotSupported,
70
+ ErrEip3009NonceAlreadyUsed,
71
+ ErrEip3009InsufficientBalance,
72
+ ErrEip3009SimulationFailed,
73
+ ErrPermit2InvalidSpender,
74
+ ErrPermit2RecipientMismatch,
75
+ ErrPermit2DeadlineExpired,
76
+ ErrPermit2NotYetValid,
77
+ ErrPermit2AmountMismatch,
78
+ ErrPermit2TokenMismatch,
79
+ ErrPermit2InvalidSignature,
80
+ ErrPermit2AllowanceRequired,
81
+ ErrPermit2SimulationFailed,
82
+ ErrPermit2InsufficientBalance,
83
+ ErrPermit2ProxyNotDeployed,
84
+ ErrPermit2InvalidAmount,
85
+ ErrPermit2InvalidDestination,
86
+ ErrPermit2InvalidOwner,
87
+ ErrPermit2PaymentTooEarly,
88
+ ErrPermit2InvalidNonce,
89
+ ErrPermit2612AmountMismatch,
90
+ ErrErc20ApprovalInvalidFormat,
91
+ ErrErc20ApprovalFromMismatch,
92
+ ErrErc20ApprovalAssetMismatch,
93
+ ErrErc20ApprovalSpenderNotPermit2,
94
+ ErrErc20ApprovalTxWrongTarget,
95
+ ErrErc20ApprovalTxWrongSelector,
96
+ ErrErc20ApprovalTxWrongSpender,
97
+ ErrErc20ApprovalTxInvalidCalldata,
98
+ ErrErc20ApprovalTxSignerMismatch,
99
+ ErrErc20ApprovalTxInvalidSignature,
100
+ ErrErc20ApprovalTxParseFailed,
101
+ ErrErc20ApprovalTxFailed,
102
+ ErrInvalidEip2612ExtensionFormat,
103
+ ErrEip2612FromMismatch,
104
+ ErrEip2612AssetMismatch,
105
+ ErrEip2612SpenderNotPermit2,
106
+ ErrEip2612DeadlineExpired,
107
+ ErrUnsupportedPayloadType,
108
+ ErrInvalidTransactionState,
109
+ ErrFactoryNotAllowed
110
+ };
111
+ //# sourceMappingURL=chunk-TGFAVNUD.mjs.map