@bankofai/x402-evm 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +172 -0
  2. package/dist/cjs/auth-capture/client/index.d.ts +44 -0
  3. package/dist/cjs/auth-capture/client/index.js +298 -0
  4. package/dist/cjs/auth-capture/client/index.js.map +1 -0
  5. package/dist/cjs/batch-settlement/client/file-storage.d.ts +47 -0
  6. package/dist/cjs/batch-settlement/client/file-storage.js +116 -0
  7. package/dist/cjs/batch-settlement/client/file-storage.js.map +1 -0
  8. package/dist/cjs/batch-settlement/client/index.d.ts +111 -0
  9. package/dist/cjs/batch-settlement/client/index.js +1565 -0
  10. package/dist/cjs/batch-settlement/client/index.js.map +1 -0
  11. package/dist/cjs/batch-settlement/facilitator/index.d.ts +72 -0
  12. package/dist/cjs/batch-settlement/facilitator/index.js +2102 -0
  13. package/dist/cjs/batch-settlement/facilitator/index.js.map +1 -0
  14. package/dist/cjs/batch-settlement/server/file-storage.d.ts +53 -0
  15. package/dist/cjs/batch-settlement/server/file-storage.js +181 -0
  16. package/dist/cjs/batch-settlement/server/file-storage.js.map +1 -0
  17. package/dist/cjs/batch-settlement/server/index.d.ts +491 -0
  18. package/dist/cjs/batch-settlement/server/index.js +1978 -0
  19. package/dist/cjs/batch-settlement/server/index.js.map +1 -0
  20. package/dist/cjs/batch-settlement/server/redis-storage.d.ts +87 -0
  21. package/dist/cjs/batch-settlement/server/redis-storage.js +181 -0
  22. package/dist/cjs/batch-settlement/server/redis-storage.js.map +1 -0
  23. package/dist/cjs/client/agent-wallet.d.ts +69 -0
  24. package/dist/cjs/client/agent-wallet.js +84 -0
  25. package/dist/cjs/client/agent-wallet.js.map +1 -0
  26. package/dist/cjs/exact/client/index.d.ts +63 -0
  27. package/dist/cjs/exact/client/index.js +739 -0
  28. package/dist/cjs/exact/client/index.js.map +1 -0
  29. package/dist/cjs/exact/facilitator/index.d.ts +141 -0
  30. package/dist/cjs/exact/facilitator/index.js +1989 -0
  31. package/dist/cjs/exact/facilitator/index.js.map +1 -0
  32. package/dist/cjs/exact/server/index.d.ts +118 -0
  33. package/dist/cjs/exact/server/index.js +326 -0
  34. package/dist/cjs/exact/server/index.js.map +1 -0
  35. package/dist/cjs/exact/v1/client/index.d.ts +38 -0
  36. package/dist/cjs/exact/v1/client/index.js +193 -0
  37. package/dist/cjs/exact/v1/client/index.js.map +1 -0
  38. package/dist/cjs/exact/v1/facilitator/index.d.ts +84 -0
  39. package/dist/cjs/exact/v1/facilitator/index.js +739 -0
  40. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -0
  41. package/dist/cjs/facilitator/agent-wallet.d.ts +109 -0
  42. package/dist/cjs/facilitator/agent-wallet.js +105 -0
  43. package/dist/cjs/facilitator/agent-wallet.js.map +1 -0
  44. package/dist/cjs/index.d.ts +338 -0
  45. package/dist/cjs/index.js +2860 -0
  46. package/dist/cjs/index.js.map +1 -0
  47. package/dist/cjs/permit2-DK5A8alk.d.ts +729 -0
  48. package/dist/cjs/permit2-DhJRUcgY.d.ts +729 -0
  49. package/dist/cjs/rpc-DULZzRne.d.ts +13 -0
  50. package/dist/cjs/scheme-7ehldYoO.d.ts +307 -0
  51. package/dist/cjs/scheme-BjBJzHF7.d.ts +307 -0
  52. package/dist/cjs/scheme-DWgpkDgz.d.ts +47 -0
  53. package/dist/cjs/signer-BFelv8DL.d.ts +170 -0
  54. package/dist/cjs/storage-6W5MO46W.d.ts +50 -0
  55. package/dist/cjs/storage-CHNote8s.d.ts +81 -0
  56. package/dist/cjs/storage-DjCv5IPh.d.ts +81 -0
  57. package/dist/cjs/types-CKd3Xoi1.d.ts +180 -0
  58. package/dist/cjs/types-DIt9uAUy.d.ts +180 -0
  59. package/dist/cjs/upto/client/index.d.ts +34 -0
  60. package/dist/cjs/upto/client/index.js +509 -0
  61. package/dist/cjs/upto/client/index.js.map +1 -0
  62. package/dist/cjs/upto/facilitator/index.d.ts +54 -0
  63. package/dist/cjs/upto/facilitator/index.js +1313 -0
  64. package/dist/cjs/upto/facilitator/index.js.map +1 -0
  65. package/dist/cjs/upto/server/index.d.ts +69 -0
  66. package/dist/cjs/upto/server/index.js +296 -0
  67. package/dist/cjs/upto/server/index.js.map +1 -0
  68. package/dist/cjs/v1/index.d.ts +40 -0
  69. package/dist/cjs/v1/index.js +199 -0
  70. package/dist/cjs/v1/index.js.map +1 -0
  71. package/dist/esm/auth-capture/client/index.d.mts +44 -0
  72. package/dist/esm/auth-capture/client/index.mjs +8 -0
  73. package/dist/esm/auth-capture/client/index.mjs.map +1 -0
  74. package/dist/esm/batch-settlement/client/file-storage.d.mts +47 -0
  75. package/dist/esm/batch-settlement/client/file-storage.mjs +63 -0
  76. package/dist/esm/batch-settlement/client/file-storage.mjs.map +1 -0
  77. package/dist/esm/batch-settlement/client/index.d.mts +111 -0
  78. package/dist/esm/batch-settlement/client/index.mjs +58 -0
  79. package/dist/esm/batch-settlement/client/index.mjs.map +1 -0
  80. package/dist/esm/batch-settlement/facilitator/index.d.mts +72 -0
  81. package/dist/esm/batch-settlement/facilitator/index.mjs +1252 -0
  82. package/dist/esm/batch-settlement/facilitator/index.mjs.map +1 -0
  83. package/dist/esm/batch-settlement/server/file-storage.d.mts +53 -0
  84. package/dist/esm/batch-settlement/server/file-storage.mjs +128 -0
  85. package/dist/esm/batch-settlement/server/file-storage.mjs.map +1 -0
  86. package/dist/esm/batch-settlement/server/index.d.mts +491 -0
  87. package/dist/esm/batch-settlement/server/index.mjs +1640 -0
  88. package/dist/esm/batch-settlement/server/index.mjs.map +1 -0
  89. package/dist/esm/batch-settlement/server/redis-storage.d.mts +87 -0
  90. package/dist/esm/batch-settlement/server/redis-storage.mjs +156 -0
  91. package/dist/esm/batch-settlement/server/redis-storage.mjs.map +1 -0
  92. package/dist/esm/chunk-2EUQTNJO.mjs +38 -0
  93. package/dist/esm/chunk-2EUQTNJO.mjs.map +1 -0
  94. package/dist/esm/chunk-3WZF6722.mjs +36 -0
  95. package/dist/esm/chunk-3WZF6722.mjs.map +1 -0
  96. package/dist/esm/chunk-E4Z7PNXC.mjs +275 -0
  97. package/dist/esm/chunk-E4Z7PNXC.mjs.map +1 -0
  98. package/dist/esm/chunk-GQVMVP4N.mjs +911 -0
  99. package/dist/esm/chunk-GQVMVP4N.mjs.map +1 -0
  100. package/dist/esm/chunk-H2EYJIZL.mjs +489 -0
  101. package/dist/esm/chunk-H2EYJIZL.mjs.map +1 -0
  102. package/dist/esm/chunk-H3KPLYGI.mjs +152 -0
  103. package/dist/esm/chunk-H3KPLYGI.mjs.map +1 -0
  104. package/dist/esm/chunk-HYABYUBD.mjs +432 -0
  105. package/dist/esm/chunk-HYABYUBD.mjs.map +1 -0
  106. package/dist/esm/chunk-I2DVUHM5.mjs +123 -0
  107. package/dist/esm/chunk-I2DVUHM5.mjs.map +1 -0
  108. package/dist/esm/chunk-JK7SLLF7.mjs +34 -0
  109. package/dist/esm/chunk-JK7SLLF7.mjs.map +1 -0
  110. package/dist/esm/chunk-JNT7C46S.mjs +352 -0
  111. package/dist/esm/chunk-JNT7C46S.mjs.map +1 -0
  112. package/dist/esm/chunk-MACPBXCT.mjs +415 -0
  113. package/dist/esm/chunk-MACPBXCT.mjs.map +1 -0
  114. package/dist/esm/chunk-P3QOX3QZ.mjs +113 -0
  115. package/dist/esm/chunk-P3QOX3QZ.mjs.map +1 -0
  116. package/dist/esm/chunk-QVATVA3J.mjs +47 -0
  117. package/dist/esm/chunk-QVATVA3J.mjs.map +1 -0
  118. package/dist/esm/chunk-SHJFA25H.mjs +159 -0
  119. package/dist/esm/chunk-SHJFA25H.mjs.map +1 -0
  120. package/dist/esm/chunk-TW7Z65AO.mjs +34 -0
  121. package/dist/esm/chunk-TW7Z65AO.mjs.map +1 -0
  122. package/dist/esm/chunk-U4HCGTLU.mjs +35 -0
  123. package/dist/esm/chunk-U4HCGTLU.mjs.map +1 -0
  124. package/dist/esm/chunk-VS3RYAYE.mjs +80 -0
  125. package/dist/esm/chunk-VS3RYAYE.mjs.map +1 -0
  126. package/dist/esm/chunk-W6ON4LG2.mjs +39 -0
  127. package/dist/esm/chunk-W6ON4LG2.mjs.map +1 -0
  128. package/dist/esm/chunk-XG2JLZVJ.mjs +627 -0
  129. package/dist/esm/chunk-XG2JLZVJ.mjs.map +1 -0
  130. package/dist/esm/chunk-ZCJRY5LQ.mjs +162 -0
  131. package/dist/esm/chunk-ZCJRY5LQ.mjs.map +1 -0
  132. package/dist/esm/client/agent-wallet.d.mts +69 -0
  133. package/dist/esm/client/agent-wallet.mjs +36 -0
  134. package/dist/esm/client/agent-wallet.mjs.map +1 -0
  135. package/dist/esm/exact/client/index.d.mts +63 -0
  136. package/dist/esm/exact/client/index.mjs +25 -0
  137. package/dist/esm/exact/client/index.mjs.map +1 -0
  138. package/dist/esm/exact/facilitator/index.d.mts +141 -0
  139. package/dist/esm/exact/facilitator/index.mjs +694 -0
  140. package/dist/esm/exact/facilitator/index.mjs.map +1 -0
  141. package/dist/esm/exact/server/index.d.mts +118 -0
  142. package/dist/esm/exact/server/index.mjs +153 -0
  143. package/dist/esm/exact/server/index.mjs.map +1 -0
  144. package/dist/esm/exact/v1/client/index.d.mts +38 -0
  145. package/dist/esm/exact/v1/client/index.mjs +12 -0
  146. package/dist/esm/exact/v1/client/index.mjs.map +1 -0
  147. package/dist/esm/exact/v1/facilitator/index.d.mts +84 -0
  148. package/dist/esm/exact/v1/facilitator/index.mjs +12 -0
  149. package/dist/esm/exact/v1/facilitator/index.mjs.map +1 -0
  150. package/dist/esm/facilitator/agent-wallet.d.mts +109 -0
  151. package/dist/esm/facilitator/agent-wallet.mjs +74 -0
  152. package/dist/esm/facilitator/agent-wallet.mjs.map +1 -0
  153. package/dist/esm/index.d.mts +338 -0
  154. package/dist/esm/index.mjs +144 -0
  155. package/dist/esm/index.mjs.map +1 -0
  156. package/dist/esm/permit2-DhJRUcgY.d.mts +729 -0
  157. package/dist/esm/rpc-DULZzRne.d.mts +13 -0
  158. package/dist/esm/scheme-CkNhpXrG.d.mts +307 -0
  159. package/dist/esm/scheme-D8ZbykGV.d.mts +47 -0
  160. package/dist/esm/signer-BFelv8DL.d.mts +170 -0
  161. package/dist/esm/storage-6W5MO46W.d.mts +50 -0
  162. package/dist/esm/storage-BEzTEiUr.d.mts +81 -0
  163. package/dist/esm/types-DIt9uAUy.d.mts +180 -0
  164. package/dist/esm/upto/client/index.d.mts +34 -0
  165. package/dist/esm/upto/client/index.mjs +22 -0
  166. package/dist/esm/upto/client/index.mjs.map +1 -0
  167. package/dist/esm/upto/facilitator/index.d.mts +54 -0
  168. package/dist/esm/upto/facilitator/index.mjs +507 -0
  169. package/dist/esm/upto/facilitator/index.mjs.map +1 -0
  170. package/dist/esm/upto/server/index.d.mts +69 -0
  171. package/dist/esm/upto/server/index.mjs +124 -0
  172. package/dist/esm/upto/server/index.mjs.map +1 -0
  173. package/dist/esm/v1/index.d.mts +40 -0
  174. package/dist/esm/v1/index.mjs +18 -0
  175. package/dist/esm/v1/index.mjs.map +1 -0
  176. package/package.json +250 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts"],"sourcesContent":["/**\n * Asset transfer methods for the exact EVM scheme.\n * - eip3009: Uses transferWithAuthorization (USDC, etc.) - recommended for compatible tokens\n * - permit2: Uses Permit2 + x402Permit2Proxy - universal fallback for any ERC-20\n */\nexport type AssetTransferMethod = \"eip3009\" | \"permit2\";\n\n/**\n * EIP-3009 payload for tokens with native transferWithAuthorization support.\n */\nexport type ExactEIP3009Payload = {\n signature?: `0x${string}`;\n authorization: {\n from: `0x${string}`;\n to: `0x${string}`;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: `0x${string}`;\n };\n};\n\n/**\n * Permit2 witness data structure.\n * Matches the Witness struct in x402Permit2Proxy contract.\n * Note: Upper time bound is enforced by Permit2's `deadline` field, not a witness field.\n */\nexport type Permit2Witness = {\n to: `0x${string}`;\n validAfter: string;\n};\n\n/**\n * Permit2 authorization parameters.\n * Used to reconstruct the signed message for verification.\n */\nexport type Permit2Authorization = {\n permitted: {\n token: `0x${string}`;\n amount: string;\n };\n spender: `0x${string}`;\n nonce: string;\n deadline: string;\n witness: Permit2Witness;\n};\n\n/**\n * Permit2 payload for tokens using the Permit2 + x402Permit2Proxy flow.\n */\nexport type ExactPermit2Payload = {\n signature: `0x${string}`;\n permit2Authorization: Permit2Authorization & {\n from: `0x${string}`;\n };\n};\n\nexport type ExactEvmPayloadV1 = ExactEIP3009Payload;\n\nexport type ExactEvmPayloadV2 = ExactEIP3009Payload | ExactPermit2Payload;\n\n/**\n * Type guard to check if a payload is a Permit2 payload.\n * Permit2 payloads have a `permit2Authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is a Permit2 payload, false otherwise.\n */\nexport function isPermit2Payload(payload: ExactEvmPayloadV2): payload is ExactPermit2Payload {\n return \"permit2Authorization\" in payload;\n}\n\n/**\n * Type guard to check if a payload is an EIP-3009 payload.\n * EIP-3009 payloads have an `authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is an EIP-3009 payload, false otherwise.\n */\nexport function isEIP3009Payload(payload: ExactEvmPayloadV2): payload is ExactEIP3009Payload {\n return \"authorization\" in payload;\n}\n\n/**\n * Upto Permit2 witness — includes `facilitator` field absent from exact witness.\n * Only the address matching `witness.facilitator` can call settle() on-chain.\n */\nexport type UptoPermit2Witness = {\n to: `0x${string}`;\n facilitator: `0x${string}`;\n validAfter: string;\n};\n\nexport type UptoPermit2Authorization = {\n permitted: {\n token: `0x${string}`;\n amount: string;\n };\n spender: `0x${string}`;\n nonce: string;\n deadline: string;\n witness: UptoPermit2Witness;\n};\n\nexport type UptoPermit2Payload = {\n signature: `0x${string}`;\n permit2Authorization: UptoPermit2Authorization & {\n from: `0x${string}`;\n };\n};\n\n// Batch-settlement EVM scheme payload types\nexport type {\n AuthorizerSigner,\n ChannelConfig,\n ChannelState,\n BatchSettlementDepositPayload,\n BatchSettlementVoucherPayload,\n BatchSettlementRefundPayload,\n BatchSettlementVoucherFields,\n BatchSettlementErc3009Authorization,\n BatchSettlementPermit2Authorization,\n BatchSettlementDepositAuthorization,\n BatchSettlementAssetTransferMethod,\n BatchSettlementClaimPayload,\n BatchSettlementEnrichedRefundPayload,\n BatchSettlementVoucherClaim,\n BatchSettlementPayload,\n BatchSettlementSettlePayload,\n BatchSettlementFacilitatorSettlePayload,\n BatchSettlementPaymentRequirementsExtra,\n BatchSettlementPaymentResponseExtra,\n} from \"./batch-settlement/types\";\nexport {\n isBatchSettlementDepositPayload,\n isBatchSettlementVoucherPayload,\n isBatchSettlementRefundPayload,\n isBatchSettlementClaimPayload,\n isBatchSettlementSettlePayload,\n isBatchSettlementEnrichedRefundPayload,\n} from \"./batch-settlement/types\";\n\n/**\n * Type guard to check if a payload is an upto Permit2 payload.\n * Validates structural presence of all required fields: signature, permit2Authorization\n * (with from, permitted, spender, nonce, deadline), and a witness containing facilitator.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is an upto Permit2 payload, false otherwise.\n */\nexport function isUptoPermit2Payload(\n payload: Record<string, unknown>,\n): payload is UptoPermit2Payload {\n if (typeof payload.signature !== \"string\") return false;\n if (!(\"permit2Authorization\" in payload)) return false;\n\n const auth = payload.permit2Authorization;\n if (typeof auth !== \"object\" || auth === null) return false;\n\n const a = auth as Record<string, unknown>;\n if (typeof a.from !== \"string\") return false;\n if (typeof a.spender !== \"string\") return false;\n if (typeof a.nonce !== \"string\") return false;\n if (typeof a.deadline !== \"string\") return false;\n\n const permitted = a.permitted;\n if (typeof permitted !== \"object\" || permitted === null) return false;\n const p = permitted as Record<string, unknown>;\n if (typeof p.token !== \"string\") return false;\n if (typeof p.amount !== \"string\") return false;\n\n const witness = a.witness;\n if (typeof witness !== \"object\" || witness === null) return false;\n const w = witness as Record<string, unknown>;\n return (\n typeof w.facilitator === \"string\" &&\n typeof w.to === \"string\" &&\n typeof w.validAfter === \"string\"\n );\n}\n"],"mappings":";AAoEO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,0BAA0B;AACnC;AASO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,mBAAmB;AAC5B;AAqEO,SAAS,qBACd,SAC+B;AAC/B,MAAI,OAAO,QAAQ,cAAc,SAAU,QAAO;AAClD,MAAI,EAAE,0BAA0B,SAAU,QAAO;AAEjD,QAAM,OAAO,QAAQ;AACrB,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AAEtD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,SAAU,QAAO;AACvC,MAAI,OAAO,EAAE,YAAY,SAAU,QAAO;AAC1C,MAAI,OAAO,EAAE,UAAU,SAAU,QAAO;AACxC,MAAI,OAAO,EAAE,aAAa,SAAU,QAAO;AAE3C,QAAM,YAAY,EAAE;AACpB,MAAI,OAAO,cAAc,YAAY,cAAc,KAAM,QAAO;AAChE,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,UAAU,SAAU,QAAO;AACxC,MAAI,OAAO,EAAE,WAAW,SAAU,QAAO;AAEzC,QAAM,UAAU,EAAE;AAClB,MAAI,OAAO,YAAY,YAAY,YAAY,KAAM,QAAO;AAC5D,QAAM,IAAI;AACV,SACE,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,eAAe;AAE5B;","names":[]}
@@ -0,0 +1,352 @@
1
+ import {
2
+ DEFAULT_MAX_FEE_PER_GAS,
3
+ DEFAULT_MAX_PRIORITY_FEE_PER_GAS,
4
+ ERC20_APPROVE_GAS_LIMIT,
5
+ PERMIT2_ADDRESS,
6
+ eip2612NoncesAbi,
7
+ eip2612PermitTypes,
8
+ erc20AllowanceAbi,
9
+ erc20ApproveAbi
10
+ } from "./chunk-MACPBXCT.mjs";
11
+ import {
12
+ getEvmChainId
13
+ } from "./chunk-TW7Z65AO.mjs";
14
+
15
+ // src/shared/extensions/builderCode.ts
16
+ var BUILDER_CODE_KEY = "builder-code";
17
+ var BUILDER_CODE_RESOLVER = async (context, ctx) => {
18
+ const ext = context.getExtension(BUILDER_CODE_KEY);
19
+ if (!ext?.buildDataSuffix) {
20
+ return void 0;
21
+ }
22
+ return ext.buildDataSuffix(ctx);
23
+ };
24
+ var DATA_SUFFIX_RESOLVERS = [BUILDER_CODE_RESOLVER];
25
+ async function resolveDataSuffix(context, ctx) {
26
+ if (!context) {
27
+ return void 0;
28
+ }
29
+ const parts = [];
30
+ for (const resolver of DATA_SUFFIX_RESOLVERS) {
31
+ const suffix = await resolver(context, ctx);
32
+ if (suffix && suffix !== "0x" && suffix.length > 2) {
33
+ parts.push(suffix);
34
+ }
35
+ }
36
+ if (parts.length === 0) {
37
+ return void 0;
38
+ }
39
+ if (parts.length === 1) {
40
+ return parts[0];
41
+ }
42
+ return parts.reduce((acc, part, index) => {
43
+ if (index === 0) {
44
+ return part;
45
+ }
46
+ const stripped = part.startsWith("0x") ? part.slice(2) : part;
47
+ return `${acc}${stripped}`;
48
+ });
49
+ }
50
+ function appendDataSuffix(calldata, suffix) {
51
+ if (!suffix || suffix === "0x" || suffix.length <= 2) {
52
+ return calldata;
53
+ }
54
+ const suffixHex = suffix.startsWith("0x") ? suffix.slice(2) : suffix;
55
+ return `${calldata}${suffixHex}`;
56
+ }
57
+
58
+ // src/exact/extensions.ts
59
+ var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
60
+ var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
61
+ var ERC20_APPROVAL_GAS_SPONSORING_VERSION = "1";
62
+ function _extractInfo(payload, extensionKey) {
63
+ const extensions = payload.extensions;
64
+ if (!extensions) return null;
65
+ const extension = extensions[extensionKey];
66
+ if (!extension?.info) return null;
67
+ return extension.info;
68
+ }
69
+ function extractEip2612GasSponsoringInfo(payload) {
70
+ const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);
71
+ if (!info) return null;
72
+ if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
73
+ return null;
74
+ }
75
+ return info;
76
+ }
77
+ function validateEip2612GasSponsoringInfo(info) {
78
+ const addressPattern = /^0x[a-fA-F0-9]{40}$/;
79
+ const numericPattern = /^[0-9]+$/;
80
+ const hexPattern = /^0x[a-fA-F0-9]+$/;
81
+ const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
82
+ 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);
83
+ }
84
+ function extractErc20ApprovalGasSponsoringInfo(payload) {
85
+ const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);
86
+ if (!info) return null;
87
+ if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
88
+ return null;
89
+ }
90
+ return info;
91
+ }
92
+ function validateErc20ApprovalGasSponsoringInfo(info) {
93
+ const addressPattern = /^0x[a-fA-F0-9]{40}$/;
94
+ const numericPattern = /^[0-9]+$/;
95
+ const hexPattern = /^0x[a-fA-F0-9]+$/;
96
+ const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
97
+ 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);
98
+ }
99
+ function resolveErc20ApprovalExtensionSigner(extension, network) {
100
+ if (!extension) return void 0;
101
+ return extension.signerForNetwork?.(network) ?? extension.signer;
102
+ }
103
+
104
+ // src/shared/extensions/gasSponsoring.ts
105
+ import { getAddress as getAddress3 } from "viem";
106
+
107
+ // src/exact/client/eip2612.ts
108
+ import { getAddress } from "viem";
109
+ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline, permittedAmount) {
110
+ const owner = signer.address;
111
+ const spender = getAddress(PERMIT2_ADDRESS);
112
+ const nonce = await signer.readContract({
113
+ address: tokenAddress,
114
+ abi: eip2612NoncesAbi,
115
+ functionName: "nonces",
116
+ args: [owner]
117
+ });
118
+ const domain = {
119
+ name: tokenName,
120
+ version: tokenVersion,
121
+ chainId,
122
+ verifyingContract: tokenAddress
123
+ };
124
+ const approvalAmount = BigInt(permittedAmount);
125
+ const message = {
126
+ owner,
127
+ spender,
128
+ value: approvalAmount,
129
+ nonce,
130
+ deadline: BigInt(deadline)
131
+ };
132
+ const signature = await signer.signTypedData({
133
+ domain,
134
+ types: eip2612PermitTypes,
135
+ primaryType: "Permit",
136
+ message
137
+ });
138
+ return {
139
+ from: owner,
140
+ asset: tokenAddress,
141
+ spender,
142
+ amount: approvalAmount.toString(),
143
+ nonce: nonce.toString(),
144
+ deadline,
145
+ signature,
146
+ version: "1"
147
+ };
148
+ }
149
+
150
+ // src/exact/client/erc20approval.ts
151
+ import { encodeFunctionData, getAddress as getAddress2, maxUint256 } from "viem";
152
+ async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
153
+ const from = signer.address;
154
+ const spender = getAddress2(PERMIT2_ADDRESS);
155
+ const data = encodeFunctionData({
156
+ abi: erc20ApproveAbi,
157
+ functionName: "approve",
158
+ args: [spender, maxUint256]
159
+ });
160
+ const nonce = await signer.getTransactionCount({ address: from });
161
+ let maxFeePerGas;
162
+ let maxPriorityFeePerGas;
163
+ try {
164
+ const fees = await signer.estimateFeesPerGas?.();
165
+ if (!fees) {
166
+ throw new Error("no fee estimates available");
167
+ }
168
+ maxFeePerGas = fees.maxFeePerGas;
169
+ maxPriorityFeePerGas = fees.maxPriorityFeePerGas;
170
+ } catch {
171
+ maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;
172
+ maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;
173
+ }
174
+ const signedTransaction = await signer.signTransaction({
175
+ to: tokenAddress,
176
+ data,
177
+ nonce,
178
+ gas: ERC20_APPROVE_GAS_LIMIT,
179
+ maxFeePerGas,
180
+ maxPriorityFeePerGas,
181
+ chainId
182
+ });
183
+ return {
184
+ from,
185
+ asset: tokenAddress,
186
+ spender,
187
+ amount: maxUint256.toString(),
188
+ signedTransaction,
189
+ version: ERC20_APPROVAL_GAS_SPONSORING_VERSION
190
+ };
191
+ }
192
+
193
+ // src/shared/rpc.ts
194
+ import { createPublicClient, http } from "viem";
195
+ var rpcClientCache = /* @__PURE__ */ new Map();
196
+ function isConfigByChainId(options) {
197
+ const keys = Object.keys(options);
198
+ return keys.length > 0 && keys.every((key) => /^\d+$/.test(key));
199
+ }
200
+ function getRpcClient(rpcUrl) {
201
+ const existing = rpcClientCache.get(rpcUrl);
202
+ if (existing) {
203
+ return existing;
204
+ }
205
+ const client = createPublicClient({
206
+ transport: http(rpcUrl)
207
+ });
208
+ rpcClientCache.set(rpcUrl, client);
209
+ return client;
210
+ }
211
+ function resolveRpcUrl(network, options) {
212
+ if (!options) {
213
+ return void 0;
214
+ }
215
+ if (isConfigByChainId(options)) {
216
+ const chainId = getEvmChainId(network);
217
+ const optionsByChainId = options;
218
+ return optionsByChainId[chainId]?.rpcUrl;
219
+ }
220
+ return options.rpcUrl;
221
+ }
222
+ function resolveExtensionRpcCapabilities(network, signer, options) {
223
+ const capabilities = {
224
+ signTransaction: signer.signTransaction,
225
+ readContract: signer.readContract,
226
+ getTransactionCount: signer.getTransactionCount,
227
+ estimateFeesPerGas: signer.estimateFeesPerGas
228
+ };
229
+ const needsRpcBackfill = !capabilities.readContract || !capabilities.getTransactionCount || !capabilities.estimateFeesPerGas;
230
+ if (!needsRpcBackfill) {
231
+ return capabilities;
232
+ }
233
+ const rpcUrl = resolveRpcUrl(network, options);
234
+ if (!rpcUrl) {
235
+ return capabilities;
236
+ }
237
+ const rpcClient = getRpcClient(rpcUrl);
238
+ if (!capabilities.readContract) {
239
+ capabilities.readContract = (args) => rpcClient.readContract(args);
240
+ }
241
+ if (!capabilities.getTransactionCount) {
242
+ capabilities.getTransactionCount = async (args) => rpcClient.getTransactionCount({ address: args.address });
243
+ }
244
+ if (!capabilities.estimateFeesPerGas) {
245
+ capabilities.estimateFeesPerGas = async () => rpcClient.estimateFeesPerGas();
246
+ }
247
+ return capabilities;
248
+ }
249
+
250
+ // src/shared/extensions/gasSponsoring.ts
251
+ async function trySignEip2612PermitExtension(signer, options, requirements, result, context, approvalAmount) {
252
+ const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);
253
+ if (!capabilities.readContract) {
254
+ return void 0;
255
+ }
256
+ if (!context?.extensions?.[EIP2612_GAS_SPONSORING_KEY]) {
257
+ return void 0;
258
+ }
259
+ const tokenName = requirements.extra?.name;
260
+ const tokenVersion = requirements.extra?.version;
261
+ if (!tokenName || !tokenVersion) {
262
+ return void 0;
263
+ }
264
+ const chainId = getEvmChainId(requirements.network);
265
+ const tokenAddress = getAddress3(requirements.asset);
266
+ const requiredAllowance = approvalAmount ?? requirements.amount;
267
+ try {
268
+ const allowance = await capabilities.readContract({
269
+ address: tokenAddress,
270
+ abi: erc20AllowanceAbi,
271
+ functionName: "allowance",
272
+ args: [signer.address, PERMIT2_ADDRESS]
273
+ });
274
+ if (allowance >= BigInt(requiredAllowance)) {
275
+ return void 0;
276
+ }
277
+ } catch {
278
+ }
279
+ const permit2Auth = result.payload?.permit2Authorization;
280
+ const deadline = permit2Auth?.deadline ?? Math.floor(Date.now() / 1e3 + requirements.maxTimeoutSeconds).toString();
281
+ const info = await signEip2612Permit(
282
+ {
283
+ address: signer.address,
284
+ signTypedData: (msg) => signer.signTypedData(msg),
285
+ readContract: capabilities.readContract
286
+ },
287
+ tokenAddress,
288
+ tokenName,
289
+ tokenVersion,
290
+ chainId,
291
+ deadline,
292
+ requiredAllowance
293
+ );
294
+ return {
295
+ [EIP2612_GAS_SPONSORING_KEY]: { info }
296
+ };
297
+ }
298
+ async function trySignErc20ApprovalExtension(signer, options, requirements, context, approvalAmount) {
299
+ const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);
300
+ if (!capabilities.readContract) {
301
+ return void 0;
302
+ }
303
+ if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING_KEY]) {
304
+ return void 0;
305
+ }
306
+ if (!capabilities.signTransaction || !capabilities.getTransactionCount) {
307
+ return void 0;
308
+ }
309
+ const chainId = getEvmChainId(requirements.network);
310
+ const tokenAddress = getAddress3(requirements.asset);
311
+ const requiredAllowance = approvalAmount ?? requirements.amount;
312
+ try {
313
+ const allowance = await capabilities.readContract({
314
+ address: tokenAddress,
315
+ abi: erc20AllowanceAbi,
316
+ functionName: "allowance",
317
+ args: [signer.address, PERMIT2_ADDRESS]
318
+ });
319
+ if (allowance >= BigInt(requiredAllowance)) {
320
+ return void 0;
321
+ }
322
+ } catch {
323
+ }
324
+ const info = await signErc20ApprovalTransaction(
325
+ {
326
+ address: signer.address,
327
+ signTransaction: capabilities.signTransaction,
328
+ getTransactionCount: capabilities.getTransactionCount,
329
+ estimateFeesPerGas: capabilities.estimateFeesPerGas
330
+ },
331
+ tokenAddress,
332
+ chainId
333
+ );
334
+ return {
335
+ [ERC20_APPROVAL_GAS_SPONSORING_KEY]: { info }
336
+ };
337
+ }
338
+
339
+ export {
340
+ ERC20_APPROVAL_GAS_SPONSORING_KEY,
341
+ extractEip2612GasSponsoringInfo,
342
+ validateEip2612GasSponsoringInfo,
343
+ extractErc20ApprovalGasSponsoringInfo,
344
+ validateErc20ApprovalGasSponsoringInfo,
345
+ resolveErc20ApprovalExtensionSigner,
346
+ trySignEip2612PermitExtension,
347
+ trySignErc20ApprovalExtension,
348
+ BUILDER_CODE_KEY,
349
+ resolveDataSuffix,
350
+ appendDataSuffix
351
+ };
352
+ //# sourceMappingURL=chunk-JNT7C46S.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/extensions/builderCode.ts","../../src/exact/extensions.ts","../../src/shared/extensions/gasSponsoring.ts","../../src/exact/client/eip2612.ts","../../src/exact/client/erc20approval.ts","../../src/shared/rpc.ts"],"sourcesContent":["import type {\n FacilitatorContext,\n FacilitatorExtension,\n PaymentPayload,\n PaymentRequirements,\n} from \"@bankofai/x402-core/types\";\nimport type { Hex } from \"viem\";\n\nexport const BUILDER_CODE_KEY = \"builder-code\" as const;\n\nexport interface DataSuffixContext {\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n}\n\nexport interface BuilderCodeFacilitatorExtension extends FacilitatorExtension {\n key: typeof BUILDER_CODE_KEY;\n buildDataSuffix?(ctx: DataSuffixContext): Hex | undefined | Promise<Hex | undefined>;\n}\n\ntype DataSuffixResolver = (\n context: FacilitatorContext,\n ctx: DataSuffixContext,\n) => Promise<Hex | undefined>;\n\nconst BUILDER_CODE_RESOLVER: DataSuffixResolver = async (context, ctx) => {\n const ext = context.getExtension<BuilderCodeFacilitatorExtension>(BUILDER_CODE_KEY);\n if (!ext?.buildDataSuffix) {\n return undefined;\n }\n\n return ext.buildDataSuffix(ctx);\n};\n\nconst DATA_SUFFIX_RESOLVERS: DataSuffixResolver[] = [BUILDER_CODE_RESOLVER];\n\n/**\n * Resolves and concatenates data suffixes from registered extensions.\n *\n * @param context - Facilitator context with registered extensions\n * @param ctx - Data suffix context passed to extension resolvers\n * @returns Hex-encoded suffix to append to settlement calldata, or undefined if none\n */\nexport async function resolveDataSuffix(\n context: FacilitatorContext | undefined,\n ctx: DataSuffixContext,\n): Promise<Hex | undefined> {\n if (!context) {\n return undefined;\n }\n\n const parts: Hex[] = [];\n for (const resolver of DATA_SUFFIX_RESOLVERS) {\n const suffix = await resolver(context, ctx);\n if (suffix && suffix !== \"0x\" && suffix.length > 2) {\n parts.push(suffix);\n }\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n\n if (parts.length === 1) {\n return parts[0];\n }\n\n return parts.reduce((acc, part, index) => {\n if (index === 0) {\n return part;\n }\n const stripped = part.startsWith(\"0x\") ? part.slice(2) : part;\n return `${acc}${stripped}` as Hex;\n });\n}\n\n/**\n * Appends a hex data suffix to encoded contract calldata.\n *\n * @param calldata - Base encoded function calldata\n * @param suffix - Optional hex suffix (with or without 0x prefix)\n * @returns Calldata with suffix appended, or the original calldata when suffix is empty\n */\nexport function appendDataSuffix(calldata: Hex, suffix?: Hex): Hex {\n if (!suffix || suffix === \"0x\" || suffix.length <= 2) {\n return calldata;\n }\n const suffixHex = suffix.startsWith(\"0x\") ? suffix.slice(2) : suffix;\n return `${calldata}${suffixHex}` as Hex;\n}\n","import type { PaymentPayload } from \"@bankofai/x402-core/types\";\nimport type { FacilitatorEvmSigner } from \"../signer\";\n\nexport const EIP2612_GAS_SPONSORING_KEY = \"eip2612GasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_KEY = \"erc20ApprovalGasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_VERSION = \"1\" as const;\n\nexport interface Eip2612GasSponsoringInfo {\n [key: string]: unknown;\n from: string;\n asset: string;\n spender: string;\n amount: string;\n nonce: string;\n deadline: string;\n signature: string;\n version: string;\n}\n\nexport interface Erc20ApprovalGasSponsoringInfo {\n [key: string]: unknown;\n from: `0x${string}`;\n asset: `0x${string}`;\n spender: `0x${string}`;\n amount: string;\n signedTransaction: `0x${string}`;\n version: string;\n}\n\n/**\n * A single transaction to be executed by the signer.\n * - `0x${string}`: a pre-signed serialized transaction (broadcast as-is via sendRawTransaction)\n * - `{ to, data, gas? }`: an unsigned call intent (signer signs and broadcasts)\n */\nexport type TransactionRequest =\n | `0x${string}`\n | { to: `0x${string}`; data: `0x${string}`; gas?: bigint };\n\nexport type Erc20ApprovalGasSponsoringSigner = FacilitatorEvmSigner & {\n sendTransactions(transactions: TransactionRequest[]): Promise<`0x${string}`[]>;\n simulateTransactions?(transactions: TransactionRequest[]): Promise<boolean>;\n};\n\nexport interface Erc20ApprovalGasSponsoringFacilitatorExtension {\n key: typeof ERC20_APPROVAL_GAS_SPONSORING_KEY;\n signer?: Erc20ApprovalGasSponsoringSigner;\n signerForNetwork?: (network: string) => Erc20ApprovalGasSponsoringSigner | undefined;\n}\n\n/**\n * Extracts a typed `info` payload from an extension entry.\n *\n * @param payload - Payment payload containing optional extensions.\n * @param extensionKey - Extension key to extract.\n * @returns The extension `info` object when present; otherwise null.\n */\nfunction _extractInfo(\n payload: PaymentPayload,\n extensionKey: string,\n): Record<string, unknown> | null {\n const extensions = payload.extensions;\n if (!extensions) return null;\n const extension = extensions[extensionKey] as { info?: Record<string, unknown> } | undefined;\n if (!extension?.info) return null;\n return extension.info;\n}\n\n/**\n * Extracts and validates required EIP-2612 gas sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed EIP-2612 gas sponsoring info when available and complete.\n */\nexport function extractEip2612GasSponsoringInfo(\n payload: PaymentPayload,\n): Eip2612GasSponsoringInfo | null {\n const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);\n if (!info) return null;\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.nonce ||\n !info.deadline ||\n !info.signature ||\n !info.version\n ) {\n return null;\n }\n return info as unknown as Eip2612GasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of EIP-2612 sponsoring info.\n *\n * @param info - EIP-2612 extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateEip2612GasSponsoringInfo(info: Eip2612GasSponsoringInfo): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n numericPattern.test(info.nonce) &&\n numericPattern.test(info.deadline) &&\n hexPattern.test(info.signature) &&\n versionPattern.test(info.version)\n );\n}\n\n/**\n * Extracts and validates required ERC-20 approval sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed ERC-20 approval sponsoring info when available and complete.\n */\nexport function extractErc20ApprovalGasSponsoringInfo(\n payload: PaymentPayload,\n): Erc20ApprovalGasSponsoringInfo | null {\n const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);\n if (!info) return null;\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.signedTransaction ||\n !info.version\n ) {\n return null;\n }\n return info as unknown as Erc20ApprovalGasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of ERC-20 approval sponsoring info.\n *\n * @param info - ERC-20 approval extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateErc20ApprovalGasSponsoringInfo(\n info: Erc20ApprovalGasSponsoringInfo,\n): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n hexPattern.test(info.signedTransaction) &&\n versionPattern.test(info.version)\n );\n}\n\n/**\n * Resolves the ERC-20 approval extension signer for a specific network.\n *\n * @param extension - Optional facilitator extension config.\n * @param network - CAIP-2 network identifier.\n * @returns A network-specific signer when available, else the default signer.\n */\nexport function resolveErc20ApprovalExtensionSigner(\n extension: Erc20ApprovalGasSponsoringFacilitatorExtension | undefined,\n network: string,\n): Erc20ApprovalGasSponsoringSigner | undefined {\n if (!extension) return undefined;\n return extension.signerForNetwork?.(network) ?? extension.signer;\n}\n","import type {\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@bankofai/x402-core/types\";\nimport {\n EIP2612_GAS_SPONSORING_KEY,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n} from \"../../exact/extensions\";\nimport { getAddress } from \"viem\";\nimport { PERMIT2_ADDRESS, erc20AllowanceAbi } from \"../../constants\";\nimport { getEvmChainId } from \"../../utils\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { signEip2612Permit } from \"../../exact/client/eip2612\";\nimport { signErc20ApprovalTransaction } from \"../../exact/client/erc20approval\";\nimport { resolveExtensionRpcCapabilities, type ExactEvmSchemeOptions } from \"../rpc\";\n\n/**\n * Attempts to sign an EIP-2612 permit for gasless Permit2 approval.\n *\n * @param signer - The EVM client signer\n * @param options - Optional RPC configuration for backfilling capabilities\n * @param requirements - The payment requirements from the server\n * @param result - The payment payload result from the scheme\n * @param context - Optional context containing server extensions and metadata\n * @param approvalAmount - Optional amount to approve instead of `requirements.amount`\n * @returns Extension data for EIP-2612 gas sponsoring, or undefined if not applicable\n */\nexport async function trySignEip2612PermitExtension(\n signer: ClientEvmSigner,\n options: ExactEvmSchemeOptions | undefined,\n requirements: PaymentRequirements,\n result: PaymentPayloadResult,\n context?: PaymentPayloadContext,\n approvalAmount?: string,\n): Promise<Record<string, unknown> | undefined> {\n const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);\n\n if (!capabilities.readContract) {\n return undefined;\n }\n\n if (!context?.extensions?.[EIP2612_GAS_SPONSORING_KEY]) {\n return undefined;\n }\n\n const tokenName = requirements.extra?.name as string | undefined;\n const tokenVersion = requirements.extra?.version as string | undefined;\n if (!tokenName || !tokenVersion) {\n return undefined;\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n const requiredAllowance = approvalAmount ?? requirements.amount;\n\n try {\n const allowance = (await capabilities.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [signer.address, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance >= BigInt(requiredAllowance)) {\n return undefined;\n }\n } catch {\n // Allowance check failed, proceed with signing\n }\n\n const permit2Auth = result.payload?.permit2Authorization as Record<string, unknown> | undefined;\n const deadline =\n (permit2Auth?.deadline as string) ??\n Math.floor(Date.now() / 1000 + requirements.maxTimeoutSeconds).toString();\n\n const info = await signEip2612Permit(\n {\n address: signer.address,\n signTypedData: msg => signer.signTypedData(msg),\n readContract: capabilities.readContract,\n },\n tokenAddress,\n tokenName,\n tokenVersion,\n chainId,\n deadline,\n requiredAllowance,\n );\n\n return {\n [EIP2612_GAS_SPONSORING_KEY]: { info },\n };\n}\n\n/**\n * Attempts to sign an ERC-20 approval transaction for gasless Permit2 approval.\n *\n * @param signer - The EVM client signer\n * @param options - Optional RPC configuration for backfilling capabilities\n * @param requirements - The payment requirements from the server\n * @param context - Optional context containing server extensions and metadata\n * @param approvalAmount - Optional amount to check for Permit2 allowance\n * @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable\n */\nexport async function trySignErc20ApprovalExtension(\n signer: ClientEvmSigner,\n options: ExactEvmSchemeOptions | undefined,\n requirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n approvalAmount?: string,\n): Promise<Record<string, unknown> | undefined> {\n const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);\n\n if (!capabilities.readContract) {\n return undefined;\n }\n\n if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING_KEY]) {\n return undefined;\n }\n\n if (!capabilities.signTransaction || !capabilities.getTransactionCount) {\n return undefined;\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n const requiredAllowance = approvalAmount ?? requirements.amount;\n\n try {\n const allowance = (await capabilities.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [signer.address, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance >= BigInt(requiredAllowance)) {\n return undefined;\n }\n } catch {\n // Allowance check failed, proceed with signing\n }\n\n const info = await signErc20ApprovalTransaction(\n {\n address: signer.address,\n signTransaction: capabilities.signTransaction,\n getTransactionCount: capabilities.getTransactionCount,\n estimateFeesPerGas: capabilities.estimateFeesPerGas,\n },\n tokenAddress,\n chainId,\n );\n\n return {\n [ERC20_APPROVAL_GAS_SPONSORING_KEY]: { info },\n };\n}\n","import { getAddress } from \"viem\";\nimport { eip2612PermitTypes, eip2612NoncesAbi, PERMIT2_ADDRESS } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport type { Eip2612GasSponsoringInfo } from \"../extensions\";\n\nexport type Eip2612PermitSigner = Pick<ClientEvmSigner, \"address\" | \"signTypedData\"> & {\n readContract: NonNullable<ClientEvmSigner[\"readContract\"]>;\n};\n\n/**\n * Signs an EIP-2612 permit authorizing the Permit2 contract to spend tokens.\n *\n * This creates a gasless off-chain signature that the facilitator can submit\n * on-chain via `x402Permit2Proxy.settleWithPermit()`.\n *\n * The `permittedAmount` must match the Permit2 `permitted.amount` exactly, as the\n * proxy contract enforces `permit2612.value == permittedAmount`.\n *\n * @param signer - The client EVM signer (must support readContract for nonce query)\n * @param tokenAddress - The ERC-20 token contract address\n * @param tokenName - The token name (from paymentRequirements.extra.name)\n * @param tokenVersion - The token version (from paymentRequirements.extra.version)\n * @param chainId - The chain ID\n * @param deadline - The deadline for the permit (unix timestamp as string)\n * @param permittedAmount - The Permit2 permitted amount (must match exactly)\n * @returns The EIP-2612 gas sponsoring info object\n */\nexport async function signEip2612Permit(\n signer: Eip2612PermitSigner,\n tokenAddress: `0x${string}`,\n tokenName: string,\n tokenVersion: string,\n chainId: number,\n deadline: string,\n permittedAmount: string,\n): Promise<Eip2612GasSponsoringInfo> {\n const owner = signer.address;\n const spender = getAddress(PERMIT2_ADDRESS);\n\n // Query the current EIP-2612 nonce from the token contract\n const nonce = (await signer.readContract({\n address: tokenAddress,\n abi: eip2612NoncesAbi,\n functionName: \"nonces\",\n args: [owner],\n })) as bigint;\n\n // Construct EIP-712 domain for the token's permit function\n const domain = {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: tokenAddress,\n };\n\n const approvalAmount = BigInt(permittedAmount);\n\n const message = {\n owner,\n spender,\n value: approvalAmount,\n nonce,\n deadline: BigInt(deadline),\n };\n\n // Sign the EIP-2612 permit\n const signature = await signer.signTypedData({\n domain,\n types: eip2612PermitTypes,\n primaryType: \"Permit\",\n message,\n });\n\n return {\n from: owner,\n asset: tokenAddress,\n spender,\n amount: approvalAmount.toString(),\n nonce: nonce.toString(),\n deadline,\n signature,\n version: \"1\",\n };\n}\n","import { encodeFunctionData, getAddress, maxUint256 } from \"viem\";\nimport {\n PERMIT2_ADDRESS,\n erc20ApproveAbi,\n ERC20_APPROVE_GAS_LIMIT,\n DEFAULT_MAX_FEE_PER_GAS,\n DEFAULT_MAX_PRIORITY_FEE_PER_GAS,\n} from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport {\n ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n type Erc20ApprovalGasSponsoringInfo,\n} from \"../extensions\";\n\nexport type Erc20ApprovalTxSigner = Pick<ClientEvmSigner, \"address\"> & {\n signTransaction: NonNullable<ClientEvmSigner[\"signTransaction\"]>;\n getTransactionCount: NonNullable<ClientEvmSigner[\"getTransactionCount\"]>;\n estimateFeesPerGas?: NonNullable<ClientEvmSigner[\"estimateFeesPerGas\"]>;\n};\n\n/**\n * Signs an EIP-1559 `approve(Permit2, MaxUint256)` transaction for the given token.\n *\n * The signed transaction is NOT broadcast here — the facilitator broadcasts it\n * atomically before settling the Permit2 payment. This enables Permit2 payments\n * for generic ERC-20 tokens that do NOT implement EIP-2612.\n *\n * Always approves MaxUint256 regardless of the payment amount.\n *\n * @param signer - The client EVM signer (must support signTransaction, getTransactionCount)\n * @param tokenAddress - The ERC-20 token contract address\n * @param chainId - The chain ID\n * @returns The ERC-20 approval gas sponsoring info object\n */\nexport async function signErc20ApprovalTransaction(\n signer: Erc20ApprovalTxSigner,\n tokenAddress: `0x${string}`,\n chainId: number,\n): Promise<Erc20ApprovalGasSponsoringInfo> {\n const from = signer.address;\n const spender = getAddress(PERMIT2_ADDRESS);\n\n // Encode approve(PERMIT2_ADDRESS, MaxUint256) calldata\n const data = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: \"approve\",\n args: [spender, maxUint256],\n });\n\n // Get current nonce for the sender\n const nonce = await signer.getTransactionCount({ address: from });\n\n // Get current fee estimates, with fallback values\n let maxFeePerGas: bigint;\n let maxPriorityFeePerGas: bigint;\n try {\n const fees = await signer.estimateFeesPerGas?.();\n if (!fees) {\n throw new Error(\"no fee estimates available\");\n }\n maxFeePerGas = fees.maxFeePerGas;\n maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n } catch {\n maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;\n maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;\n }\n\n // Sign the EIP-1559 transaction (not broadcast)\n const signedTransaction = await signer.signTransaction({\n to: tokenAddress,\n data,\n nonce,\n gas: ERC20_APPROVE_GAS_LIMIT,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chainId,\n });\n\n return {\n from,\n asset: tokenAddress,\n spender,\n amount: maxUint256.toString(),\n signedTransaction,\n version: ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n };\n}\n","import { createPublicClient, http } from \"viem\";\nimport type { ClientEvmSigner } from \"../signer\";\nimport { getEvmChainId } from \"../utils\";\n\nexport type EvmSchemeConfig = {\n rpcUrl?: string;\n};\n\nexport type EvmSchemeConfigByChainId = Record<number, EvmSchemeConfig>;\n\nexport type EvmSchemeOptions = EvmSchemeConfig | EvmSchemeConfigByChainId;\n\n/** @deprecated Use EvmSchemeConfig */\nexport type ExactEvmSchemeConfig = EvmSchemeConfig;\n/** @deprecated Use EvmSchemeConfigByChainId */\nexport type ExactEvmSchemeConfigByChainId = EvmSchemeConfigByChainId;\n/** @deprecated Use EvmSchemeOptions */\nexport type ExactEvmSchemeOptions = EvmSchemeOptions;\n\ntype ExtensionRpcCapabilities = Pick<\n ClientEvmSigner,\n \"readContract\" | \"signTransaction\" | \"getTransactionCount\" | \"estimateFeesPerGas\"\n>;\n\nconst rpcClientCache = new Map<string, ReturnType<typeof createPublicClient>>();\n\n/**\n * Check if options is a per-chain-id configuration map.\n *\n * @param options - The EVM scheme options to check\n * @returns True if the options are keyed by chain ID\n */\nfunction isConfigByChainId(options: EvmSchemeOptions): options is EvmSchemeConfigByChainId {\n const keys = Object.keys(options);\n return keys.length > 0 && keys.every(key => /^\\d+$/.test(key));\n}\n\n/**\n * Get or create a cached viem public client for the given RPC URL.\n *\n * @param rpcUrl - The JSON-RPC endpoint URL\n * @returns A viem PublicClient instance\n */\nfunction getRpcClient(rpcUrl: string): ReturnType<typeof createPublicClient> {\n const existing = rpcClientCache.get(rpcUrl);\n if (existing) {\n return existing;\n }\n\n const client = createPublicClient({\n transport: http(rpcUrl),\n });\n rpcClientCache.set(rpcUrl, client);\n return client;\n}\n\n/**\n * Resolve an RPC URL from scheme options for the given network.\n *\n * @param network - The CAIP-2 network identifier\n * @param options - Optional EVM scheme options (flat or per-chain-id)\n * @returns The resolved RPC URL, or undefined if not configured\n */\nexport function resolveRpcUrl(network: string, options?: EvmSchemeOptions): string | undefined {\n if (!options) {\n return undefined;\n }\n\n if (isConfigByChainId(options)) {\n const chainId = getEvmChainId(network);\n const optionsByChainId = options as EvmSchemeConfigByChainId;\n return optionsByChainId[chainId]?.rpcUrl;\n }\n\n return (options as EvmSchemeConfig).rpcUrl;\n}\n\n/**\n * Resolve RPC capabilities for extensions, backfilling from a public RPC client when the signer lacks them.\n *\n * @param network - The CAIP-2 network identifier\n * @param signer - The client EVM signer\n * @param options - Optional EVM scheme options for RPC URL resolution\n * @returns Extension RPC capabilities (readContract, signTransaction, etc.)\n */\nexport function resolveExtensionRpcCapabilities(\n network: string,\n signer: ClientEvmSigner,\n options?: EvmSchemeOptions,\n): ExtensionRpcCapabilities {\n const capabilities: ExtensionRpcCapabilities = {\n signTransaction: signer.signTransaction,\n readContract: signer.readContract,\n getTransactionCount: signer.getTransactionCount,\n estimateFeesPerGas: signer.estimateFeesPerGas,\n };\n\n const needsRpcBackfill =\n !capabilities.readContract ||\n !capabilities.getTransactionCount ||\n !capabilities.estimateFeesPerGas;\n if (!needsRpcBackfill) {\n return capabilities;\n }\n\n const rpcUrl = resolveRpcUrl(network, options);\n if (!rpcUrl) {\n return capabilities;\n }\n const rpcClient = getRpcClient(rpcUrl);\n if (!capabilities.readContract) {\n capabilities.readContract = args => rpcClient.readContract(args as never) as Promise<unknown>;\n }\n if (!capabilities.getTransactionCount) {\n capabilities.getTransactionCount = async args =>\n rpcClient.getTransactionCount({ address: args.address });\n }\n if (!capabilities.estimateFeesPerGas) {\n capabilities.estimateFeesPerGas = async () => rpcClient.estimateFeesPerGas();\n }\n\n return capabilities;\n}\n"],"mappings":"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","names":["getAddress","getAddress","getAddress","getAddress"]}