@x402/evm 2.4.0 → 2.5.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 (48) hide show
  1. package/dist/cjs/exact/client/index.d.ts +2 -2
  2. package/dist/cjs/exact/client/index.js +284 -192
  3. package/dist/cjs/exact/client/index.js.map +1 -1
  4. package/dist/cjs/exact/facilitator/index.d.ts +18 -18
  5. package/dist/cjs/exact/facilitator/index.js +454 -234
  6. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  7. package/dist/cjs/exact/v1/client/index.d.ts +1 -1
  8. package/dist/cjs/exact/v1/client/index.js +17 -18
  9. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  10. package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
  11. package/dist/cjs/exact/v1/facilitator/index.js +7 -8
  12. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  13. package/dist/cjs/index.d.ts +3 -390
  14. package/dist/cjs/index.js +225 -132
  15. package/dist/cjs/index.js.map +1 -1
  16. package/dist/cjs/permit2-CQbXqCMC.d.ts +517 -0
  17. package/dist/cjs/{signer-3KGwtdNT.d.ts → signer-DC81R8wQ.d.ts} +37 -0
  18. package/dist/cjs/v1/index.d.ts +11 -2
  19. package/dist/cjs/v1/index.js +14 -11
  20. package/dist/cjs/v1/index.js.map +1 -1
  21. package/dist/esm/{chunk-GSU4DHTC.mjs → chunk-7KHQD5KT.mjs} +72 -37
  22. package/dist/esm/chunk-7KHQD5KT.mjs.map +1 -0
  23. package/dist/esm/{chunk-CJHYX7BQ.mjs → chunk-GY6X5A3G.mjs} +119 -56
  24. package/dist/esm/chunk-GY6X5A3G.mjs.map +1 -0
  25. package/dist/esm/{chunk-PFULIQAE.mjs → chunk-TKN5V2BV.mjs} +1 -1
  26. package/dist/esm/chunk-TKN5V2BV.mjs.map +1 -0
  27. package/dist/esm/exact/client/index.d.mts +2 -2
  28. package/dist/esm/exact/client/index.mjs +4 -3
  29. package/dist/esm/exact/facilitator/index.d.mts +18 -18
  30. package/dist/esm/exact/facilitator/index.mjs +385 -176
  31. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  32. package/dist/esm/exact/v1/client/index.d.mts +1 -1
  33. package/dist/esm/exact/v1/client/index.mjs +2 -2
  34. package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
  35. package/dist/esm/exact/v1/facilitator/index.mjs +2 -2
  36. package/dist/esm/index.d.mts +3 -390
  37. package/dist/esm/index.mjs +18 -5
  38. package/dist/esm/index.mjs.map +1 -1
  39. package/dist/esm/permit2-CGOcN7Et.d.mts +517 -0
  40. package/dist/esm/{signer-3KGwtdNT.d.mts → signer-DC81R8wQ.d.mts} +37 -0
  41. package/dist/esm/v1/index.d.mts +11 -2
  42. package/dist/esm/v1/index.mjs +6 -4
  43. package/package.json +3 -3
  44. package/dist/cjs/permit2-CzKPU5By.d.ts +0 -130
  45. package/dist/esm/chunk-CJHYX7BQ.mjs.map +0 -1
  46. package/dist/esm/chunk-GSU4DHTC.mjs.map +0 -1
  47. package/dist/esm/chunk-PFULIQAE.mjs.map +0 -1
  48. package/dist/esm/permit2-C2FkNEHT.d.mts +0 -130
@@ -1,7 +1,7 @@
1
- export { E as ExactEvmScheme, P as Permit2AllowanceParams, c as createPermit2ApprovalTx, e as erc20AllowanceAbi, g as getPermit2AllowanceReadParams } from '../../permit2-CzKPU5By.js';
1
+ export { E as ExactEvmScheme, a as Permit2AllowanceParams, c as createPermit2ApprovalTx, d as erc20AllowanceAbi, g as getPermit2AllowanceReadParams } from '../../permit2-CQbXqCMC.js';
2
2
  import { SelectPaymentRequirements, PaymentPolicy, x402Client } from '@x402/core/client';
3
3
  import { Network } from '@x402/core/types';
4
- import { C as ClientEvmSigner } from '../../signer-3KGwtdNT.js';
4
+ import { C as ClientEvmSigner } from '../../signer-DC81R8wQ.js';
5
5
 
6
6
  /**
7
7
  * Configuration options for registering EVM schemes to an x402Client
@@ -29,7 +29,7 @@ __export(client_exports, {
29
29
  module.exports = __toCommonJS(client_exports);
30
30
 
31
31
  // src/exact/client/scheme.ts
32
- var import_extensions = require("@x402/extensions");
32
+ var import_extensions2 = require("@x402/extensions");
33
33
 
34
34
  // src/constants.ts
35
35
  var authorizationTypes = {
@@ -56,8 +56,7 @@ var permit2WitnessTypes = {
56
56
  ],
57
57
  Witness: [
58
58
  { name: "to", type: "address" },
59
- { name: "validAfter", type: "uint256" },
60
- { name: "extra", type: "bytes" }
59
+ { name: "validAfter", type: "uint256" }
61
60
  ]
62
61
  };
63
62
  var eip2612PermitTypes = {
@@ -78,133 +77,51 @@ var eip2612NoncesAbi = [
78
77
  stateMutability: "view"
79
78
  }
80
79
  ];
80
+ var erc20ApproveAbi = [
81
+ {
82
+ type: "function",
83
+ name: "approve",
84
+ inputs: [
85
+ { name: "spender", type: "address" },
86
+ { name: "amount", type: "uint256" }
87
+ ],
88
+ outputs: [{ type: "bool" }],
89
+ stateMutability: "nonpayable"
90
+ }
91
+ ];
92
+ var erc20AllowanceAbi = [
93
+ {
94
+ type: "function",
95
+ name: "allowance",
96
+ inputs: [
97
+ { name: "owner", type: "address" },
98
+ { name: "spender", type: "address" }
99
+ ],
100
+ outputs: [{ type: "uint256" }],
101
+ stateMutability: "view"
102
+ }
103
+ ];
104
+ var ERC20_APPROVE_GAS_LIMIT = 70000n;
105
+ var DEFAULT_MAX_FEE_PER_GAS = 1000000000n;
106
+ var DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 100000000n;
81
107
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
82
- var x402ExactPermit2ProxyAddress = "0x4020615294c913F045dc10f0a5cdEbd86c280001";
108
+ var x402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
83
109
 
84
110
  // src/exact/client/scheme.ts
85
- var import_viem7 = require("viem");
86
-
87
- // src/exact/client/eip3009.ts
88
- var import_viem4 = require("viem");
111
+ var import_viem6 = require("viem");
89
112
 
90
113
  // src/utils.ts
91
- var import_viem3 = require("viem");
92
-
93
- // src/exact/v1/client/scheme.ts
94
114
  var import_viem = require("viem");
95
- var ExactEvmSchemeV1 = class {
96
- /**
97
- * Creates a new ExactEvmClientV1 instance.
98
- *
99
- * @param signer - The EVM signer for client operations
100
- */
101
- constructor(signer) {
102
- this.signer = signer;
103
- this.scheme = "exact";
104
- }
105
- /**
106
- * Creates a payment payload for the Exact scheme (V1).
107
- *
108
- * @param x402Version - The x402 protocol version
109
- * @param paymentRequirements - The payment requirements
110
- * @returns Promise resolving to a payment payload
111
- */
112
- async createPaymentPayload(x402Version, paymentRequirements) {
113
- const selectedV1 = paymentRequirements;
114
- const nonce = createNonce();
115
- const now = Math.floor(Date.now() / 1e3);
116
- const authorization = {
117
- from: this.signer.address,
118
- to: (0, import_viem.getAddress)(selectedV1.payTo),
119
- value: selectedV1.maxAmountRequired,
120
- validAfter: (now - 600).toString(),
121
- // 10 minutes before
122
- validBefore: (now + selectedV1.maxTimeoutSeconds).toString(),
123
- nonce
124
- };
125
- const signature = await this.signAuthorization(authorization, selectedV1);
126
- const payload = {
127
- authorization,
128
- signature
129
- };
130
- return {
131
- x402Version,
132
- scheme: selectedV1.scheme,
133
- network: selectedV1.network,
134
- payload
135
- };
136
- }
137
- /**
138
- * Sign the EIP-3009 authorization using EIP-712
139
- *
140
- * @param authorization - The authorization to sign
141
- * @param requirements - The payment requirements
142
- * @returns Promise resolving to the signature
143
- */
144
- async signAuthorization(authorization, requirements) {
145
- const chainId = getEvmChainId(requirements.network);
146
- if (!requirements.extra?.name || !requirements.extra?.version) {
147
- throw new Error(
148
- `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
149
- );
150
- }
151
- const { name, version } = requirements.extra;
152
- const domain = {
153
- name,
154
- version,
155
- chainId,
156
- verifyingContract: (0, import_viem.getAddress)(requirements.asset)
157
- };
158
- const message = {
159
- from: (0, import_viem.getAddress)(authorization.from),
160
- to: (0, import_viem.getAddress)(authorization.to),
161
- value: BigInt(authorization.value),
162
- validAfter: BigInt(authorization.validAfter),
163
- validBefore: BigInt(authorization.validBefore),
164
- nonce: authorization.nonce
165
- };
166
- return await this.signer.signTypedData({
167
- domain,
168
- types: authorizationTypes,
169
- primaryType: "TransferWithAuthorization",
170
- message
171
- });
172
- }
173
- };
174
-
175
- // src/exact/v1/facilitator/scheme.ts
176
- var import_viem2 = require("viem");
177
-
178
- // src/v1/index.ts
179
- var EVM_NETWORK_CHAIN_ID_MAP = {
180
- ethereum: 1,
181
- sepolia: 11155111,
182
- abstract: 2741,
183
- "abstract-testnet": 11124,
184
- "base-sepolia": 84532,
185
- base: 8453,
186
- "avalanche-fuji": 43113,
187
- avalanche: 43114,
188
- iotex: 4689,
189
- sei: 1329,
190
- "sei-testnet": 1328,
191
- polygon: 137,
192
- "polygon-amoy": 80002,
193
- peaq: 3338,
194
- story: 1514,
195
- educhain: 41923,
196
- "skale-base-sepolia": 324705682,
197
- megaeth: 4326
198
- };
199
- var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
200
-
201
- // src/utils.ts
202
115
  function getEvmChainId(network) {
203
- const chainId = EVM_NETWORK_CHAIN_ID_MAP[network];
204
- if (!chainId) {
205
- throw new Error(`Unsupported network: ${network}`);
116
+ if (network.startsWith("eip155:")) {
117
+ const idStr = network.split(":")[1];
118
+ const chainId = parseInt(idStr, 10);
119
+ if (isNaN(chainId)) {
120
+ throw new Error(`Invalid CAIP-2 chain ID: ${network}`);
121
+ }
122
+ return chainId;
206
123
  }
207
- return chainId;
124
+ throw new Error(`Unsupported network format: ${network} (expected eip155:CHAIN_ID)`);
208
125
  }
209
126
  function getCrypto() {
210
127
  const cryptoObj = globalThis.crypto;
@@ -214,20 +131,21 @@ function getCrypto() {
214
131
  return cryptoObj;
215
132
  }
216
133
  function createNonce() {
217
- return (0, import_viem3.toHex)(getCrypto().getRandomValues(new Uint8Array(32)));
134
+ return (0, import_viem.toHex)(getCrypto().getRandomValues(new Uint8Array(32)));
218
135
  }
219
136
  function createPermit2Nonce() {
220
137
  const randomBytes = getCrypto().getRandomValues(new Uint8Array(32));
221
- return BigInt((0, import_viem3.toHex)(randomBytes)).toString();
138
+ return BigInt((0, import_viem.toHex)(randomBytes)).toString();
222
139
  }
223
140
 
224
141
  // src/exact/client/eip3009.ts
142
+ var import_viem2 = require("viem");
225
143
  async function createEIP3009Payload(signer, x402Version, paymentRequirements) {
226
144
  const nonce = createNonce();
227
145
  const now = Math.floor(Date.now() / 1e3);
228
146
  const authorization = {
229
147
  from: signer.address,
230
- to: (0, import_viem4.getAddress)(paymentRequirements.payTo),
148
+ to: (0, import_viem2.getAddress)(paymentRequirements.payTo),
231
149
  value: paymentRequirements.amount,
232
150
  validAfter: (now - 600).toString(),
233
151
  validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),
@@ -244,7 +162,7 @@ async function createEIP3009Payload(signer, x402Version, paymentRequirements) {
244
162
  };
245
163
  }
246
164
  async function signEIP3009Authorization(signer, authorization, requirements) {
247
- const chainId = parseInt(requirements.network.split(":")[1]);
165
+ const chainId = getEvmChainId(requirements.network);
248
166
  if (!requirements.extra?.name || !requirements.extra?.version) {
249
167
  throw new Error(
250
168
  `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
@@ -255,11 +173,11 @@ async function signEIP3009Authorization(signer, authorization, requirements) {
255
173
  name,
256
174
  version,
257
175
  chainId,
258
- verifyingContract: (0, import_viem4.getAddress)(requirements.asset)
176
+ verifyingContract: (0, import_viem2.getAddress)(requirements.asset)
259
177
  };
260
178
  const message = {
261
- from: (0, import_viem4.getAddress)(authorization.from),
262
- to: (0, import_viem4.getAddress)(authorization.to),
179
+ from: (0, import_viem2.getAddress)(authorization.from),
180
+ to: (0, import_viem2.getAddress)(authorization.to),
263
181
  value: BigInt(authorization.value),
264
182
  validAfter: BigInt(authorization.validAfter),
265
183
  validBefore: BigInt(authorization.validBefore),
@@ -274,7 +192,7 @@ async function signEIP3009Authorization(signer, authorization, requirements) {
274
192
  }
275
193
 
276
194
  // src/exact/client/permit2.ts
277
- var import_viem5 = require("viem");
195
+ var import_viem3 = require("viem");
278
196
  var MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
279
197
  async function createPermit2Payload(signer, x402Version, paymentRequirements) {
280
198
  const now = Math.floor(Date.now() / 1e3);
@@ -284,16 +202,15 @@ async function createPermit2Payload(signer, x402Version, paymentRequirements) {
284
202
  const permit2Authorization = {
285
203
  from: signer.address,
286
204
  permitted: {
287
- token: (0, import_viem5.getAddress)(paymentRequirements.asset),
205
+ token: (0, import_viem3.getAddress)(paymentRequirements.asset),
288
206
  amount: paymentRequirements.amount
289
207
  },
290
208
  spender: x402ExactPermit2ProxyAddress,
291
209
  nonce,
292
210
  deadline,
293
211
  witness: {
294
- to: (0, import_viem5.getAddress)(paymentRequirements.payTo),
295
- validAfter,
296
- extra: "0x"
212
+ to: (0, import_viem3.getAddress)(paymentRequirements.payTo),
213
+ validAfter
297
214
  }
298
215
  };
299
216
  const signature = await signPermit2Authorization(
@@ -311,7 +228,7 @@ async function createPermit2Payload(signer, x402Version, paymentRequirements) {
311
228
  };
312
229
  }
313
230
  async function signPermit2Authorization(signer, permit2Authorization, requirements) {
314
- const chainId = parseInt(requirements.network.split(":")[1]);
231
+ const chainId = getEvmChainId(requirements.network);
315
232
  const domain = {
316
233
  name: "Permit2",
317
234
  chainId,
@@ -319,16 +236,15 @@ async function signPermit2Authorization(signer, permit2Authorization, requiremen
319
236
  };
320
237
  const message = {
321
238
  permitted: {
322
- token: (0, import_viem5.getAddress)(permit2Authorization.permitted.token),
239
+ token: (0, import_viem3.getAddress)(permit2Authorization.permitted.token),
323
240
  amount: BigInt(permit2Authorization.permitted.amount)
324
241
  },
325
- spender: (0, import_viem5.getAddress)(permit2Authorization.spender),
242
+ spender: (0, import_viem3.getAddress)(permit2Authorization.spender),
326
243
  nonce: BigInt(permit2Authorization.nonce),
327
244
  deadline: BigInt(permit2Authorization.deadline),
328
245
  witness: {
329
- to: (0, import_viem5.getAddress)(permit2Authorization.witness.to),
330
- validAfter: BigInt(permit2Authorization.witness.validAfter),
331
- extra: permit2Authorization.witness.extra
246
+ to: (0, import_viem3.getAddress)(permit2Authorization.witness.to),
247
+ validAfter: BigInt(permit2Authorization.witness.validAfter)
332
248
  }
333
249
  };
334
250
  return await signer.signTypedData({
@@ -338,56 +254,31 @@ async function signPermit2Authorization(signer, permit2Authorization, requiremen
338
254
  message
339
255
  });
340
256
  }
341
- var erc20ApproveAbi = [
342
- {
343
- type: "function",
344
- name: "approve",
345
- inputs: [
346
- { name: "spender", type: "address" },
347
- { name: "amount", type: "uint256" }
348
- ],
349
- outputs: [{ type: "bool" }],
350
- stateMutability: "nonpayable"
351
- }
352
- ];
353
- var erc20AllowanceAbi = [
354
- {
355
- type: "function",
356
- name: "allowance",
357
- inputs: [
358
- { name: "owner", type: "address" },
359
- { name: "spender", type: "address" }
360
- ],
361
- outputs: [{ type: "uint256" }],
362
- stateMutability: "view"
363
- }
364
- ];
365
257
  function createPermit2ApprovalTx(tokenAddress) {
366
- const data = (0, import_viem5.encodeFunctionData)({
258
+ const data = (0, import_viem3.encodeFunctionData)({
367
259
  abi: erc20ApproveAbi,
368
260
  functionName: "approve",
369
261
  args: [PERMIT2_ADDRESS, MAX_UINT256]
370
262
  });
371
263
  return {
372
- to: (0, import_viem5.getAddress)(tokenAddress),
264
+ to: (0, import_viem3.getAddress)(tokenAddress),
373
265
  data
374
266
  };
375
267
  }
376
268
  function getPermit2AllowanceReadParams(params) {
377
269
  return {
378
- address: (0, import_viem5.getAddress)(params.tokenAddress),
270
+ address: (0, import_viem3.getAddress)(params.tokenAddress),
379
271
  abi: erc20AllowanceAbi,
380
272
  functionName: "allowance",
381
- args: [(0, import_viem5.getAddress)(params.ownerAddress), PERMIT2_ADDRESS]
273
+ args: [(0, import_viem3.getAddress)(params.ownerAddress), PERMIT2_ADDRESS]
382
274
  };
383
275
  }
384
276
 
385
277
  // src/exact/client/eip2612.ts
386
- var import_viem6 = require("viem");
387
- var MAX_UINT2562 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
388
- async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline) {
278
+ var import_viem4 = require("viem");
279
+ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline, permittedAmount) {
389
280
  const owner = signer.address;
390
- const spender = (0, import_viem6.getAddress)(PERMIT2_ADDRESS);
281
+ const spender = (0, import_viem4.getAddress)(PERMIT2_ADDRESS);
391
282
  const nonce = await signer.readContract({
392
283
  address: tokenAddress,
393
284
  abi: eip2612NoncesAbi,
@@ -400,10 +291,11 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
400
291
  chainId,
401
292
  verifyingContract: tokenAddress
402
293
  };
294
+ const approvalAmount = BigInt(permittedAmount);
403
295
  const message = {
404
296
  owner,
405
297
  spender,
406
- value: MAX_UINT2562,
298
+ value: approvalAmount,
407
299
  nonce,
408
300
  deadline: BigInt(deadline)
409
301
  };
@@ -417,7 +309,7 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
417
309
  from: owner,
418
310
  asset: tokenAddress,
419
311
  spender,
420
- amount: MAX_UINT2562.toString(),
312
+ amount: approvalAmount.toString(),
421
313
  nonce: nonce.toString(),
422
314
  deadline,
423
315
  signature,
@@ -425,19 +317,48 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
425
317
  };
426
318
  }
427
319
 
428
- // src/exact/client/scheme.ts
429
- var erc20AllowanceAbi2 = [
430
- {
431
- type: "function",
432
- name: "allowance",
433
- inputs: [
434
- { name: "owner", type: "address" },
435
- { name: "spender", type: "address" }
436
- ],
437
- outputs: [{ type: "uint256" }],
438
- stateMutability: "view"
320
+ // src/exact/client/erc20approval.ts
321
+ var import_viem5 = require("viem");
322
+ var import_extensions = require("@x402/extensions");
323
+ async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
324
+ const from = signer.address;
325
+ const spender = (0, import_viem5.getAddress)(PERMIT2_ADDRESS);
326
+ const data = (0, import_viem5.encodeFunctionData)({
327
+ abi: erc20ApproveAbi,
328
+ functionName: "approve",
329
+ args: [spender, import_viem5.maxUint256]
330
+ });
331
+ const nonce = await signer.getTransactionCount({ address: from });
332
+ let maxFeePerGas;
333
+ let maxPriorityFeePerGas;
334
+ try {
335
+ const fees = await signer.estimateFeesPerGas();
336
+ maxFeePerGas = fees.maxFeePerGas;
337
+ maxPriorityFeePerGas = fees.maxPriorityFeePerGas;
338
+ } catch {
339
+ maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;
340
+ maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;
439
341
  }
440
- ];
342
+ const signedTransaction = await signer.signTransaction({
343
+ to: tokenAddress,
344
+ data,
345
+ nonce,
346
+ gas: ERC20_APPROVE_GAS_LIMIT,
347
+ maxFeePerGas,
348
+ maxPriorityFeePerGas,
349
+ chainId
350
+ });
351
+ return {
352
+ from,
353
+ asset: tokenAddress,
354
+ spender,
355
+ amount: import_viem5.maxUint256.toString(),
356
+ signedTransaction,
357
+ version: import_extensions.ERC20_APPROVAL_GAS_SPONSORING_VERSION
358
+ };
359
+ }
360
+
361
+ // src/exact/client/scheme.ts
441
362
  var ExactEvmScheme = class {
442
363
  /**
443
364
  * Creates a new ExactEvmClient instance.
@@ -478,6 +399,13 @@ var ExactEvmScheme = class {
478
399
  extensions: eip2612Extensions
479
400
  };
480
401
  }
402
+ const erc20Extensions = await this.trySignErc20Approval(paymentRequirements, result, context);
403
+ if (erc20Extensions) {
404
+ return {
405
+ ...result,
406
+ extensions: erc20Extensions
407
+ };
408
+ }
481
409
  return result;
482
410
  }
483
411
  return createEIP3009Payload(this.signer, x402Version, paymentRequirements);
@@ -498,7 +426,7 @@ var ExactEvmScheme = class {
498
426
  * @returns Extension data for EIP-2612 gas sponsoring, or undefined if not applicable
499
427
  */
500
428
  async trySignEip2612Permit(requirements, result, context) {
501
- if (!context?.extensions?.[import_extensions.EIP2612_GAS_SPONSORING.key]) {
429
+ if (!context?.extensions?.[import_extensions2.EIP2612_GAS_SPONSORING.key]) {
502
430
  return void 0;
503
431
  }
504
432
  const tokenName = requirements.extra?.name;
@@ -506,12 +434,12 @@ var ExactEvmScheme = class {
506
434
  if (!tokenName || !tokenVersion) {
507
435
  return void 0;
508
436
  }
509
- const chainId = parseInt(requirements.network.split(":")[1]);
510
- const tokenAddress = (0, import_viem7.getAddress)(requirements.asset);
437
+ const chainId = getEvmChainId(requirements.network);
438
+ const tokenAddress = (0, import_viem6.getAddress)(requirements.asset);
511
439
  try {
512
440
  const allowance = await this.signer.readContract({
513
441
  address: tokenAddress,
514
- abi: erc20AllowanceAbi2,
442
+ abi: erc20AllowanceAbi,
515
443
  functionName: "allowance",
516
444
  args: [this.signer.address, PERMIT2_ADDRESS]
517
445
  });
@@ -528,12 +456,176 @@ var ExactEvmScheme = class {
528
456
  tokenName,
529
457
  tokenVersion,
530
458
  chainId,
531
- deadline
459
+ deadline,
460
+ requirements.amount
532
461
  );
533
462
  return {
534
- [import_extensions.EIP2612_GAS_SPONSORING.key]: { info }
463
+ [import_extensions2.EIP2612_GAS_SPONSORING.key]: { info }
535
464
  };
536
465
  }
466
+ /**
467
+ * Attempts to sign an ERC-20 approval transaction for gasless Permit2 approval.
468
+ *
469
+ * This is the fallback path when the token does not support EIP-2612. The client
470
+ * signs (but does not broadcast) a raw `approve(Permit2, MaxUint256)` transaction.
471
+ * The facilitator broadcasts it atomically before settling.
472
+ *
473
+ * Returns extension data if:
474
+ * 1. Server advertises erc20ApprovalGasSponsoring
475
+ * 2. Signer has signTransaction + getTransactionCount capabilities
476
+ * 3. Current Permit2 allowance is insufficient
477
+ *
478
+ * Returns undefined if the extension should not be used.
479
+ *
480
+ * @param requirements - The payment requirements from the server
481
+ * @param _result - The payment payload result from the scheme (unused)
482
+ * @param context - Optional context containing server extensions and metadata
483
+ * @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable
484
+ */
485
+ async trySignErc20Approval(requirements, _result, context) {
486
+ if (!context?.extensions?.[import_extensions2.ERC20_APPROVAL_GAS_SPONSORING.key]) {
487
+ return void 0;
488
+ }
489
+ if (!this.signer.signTransaction || !this.signer.getTransactionCount) {
490
+ return void 0;
491
+ }
492
+ const chainId = getEvmChainId(requirements.network);
493
+ const tokenAddress = (0, import_viem6.getAddress)(requirements.asset);
494
+ try {
495
+ const allowance = await this.signer.readContract({
496
+ address: tokenAddress,
497
+ abi: erc20AllowanceAbi,
498
+ functionName: "allowance",
499
+ args: [this.signer.address, PERMIT2_ADDRESS]
500
+ });
501
+ if (allowance >= BigInt(requirements.amount)) {
502
+ return void 0;
503
+ }
504
+ } catch {
505
+ }
506
+ const info = await signErc20ApprovalTransaction(this.signer, tokenAddress, chainId);
507
+ return {
508
+ [import_extensions2.ERC20_APPROVAL_GAS_SPONSORING.key]: { info }
509
+ };
510
+ }
511
+ };
512
+
513
+ // src/exact/v1/client/scheme.ts
514
+ var import_viem8 = require("viem");
515
+
516
+ // src/exact/v1/facilitator/scheme.ts
517
+ var import_viem7 = require("viem");
518
+
519
+ // src/v1/index.ts
520
+ var EVM_NETWORK_CHAIN_ID_MAP = {
521
+ ethereum: 1,
522
+ sepolia: 11155111,
523
+ abstract: 2741,
524
+ "abstract-testnet": 11124,
525
+ "base-sepolia": 84532,
526
+ base: 8453,
527
+ "avalanche-fuji": 43113,
528
+ avalanche: 43114,
529
+ iotex: 4689,
530
+ sei: 1329,
531
+ "sei-testnet": 1328,
532
+ polygon: 137,
533
+ "polygon-amoy": 80002,
534
+ peaq: 3338,
535
+ story: 1514,
536
+ educhain: 41923,
537
+ "skale-base-sepolia": 324705682,
538
+ megaeth: 4326,
539
+ monad: 143
540
+ };
541
+ var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
542
+ function getEvmChainIdV1(network) {
543
+ const chainId = EVM_NETWORK_CHAIN_ID_MAP[network];
544
+ if (!chainId) {
545
+ throw new Error(`Unsupported v1 network: ${network}`);
546
+ }
547
+ return chainId;
548
+ }
549
+
550
+ // src/exact/v1/client/scheme.ts
551
+ var ExactEvmSchemeV1 = class {
552
+ /**
553
+ * Creates a new ExactEvmClientV1 instance.
554
+ *
555
+ * @param signer - The EVM signer for client operations
556
+ */
557
+ constructor(signer) {
558
+ this.signer = signer;
559
+ this.scheme = "exact";
560
+ }
561
+ /**
562
+ * Creates a payment payload for the Exact scheme (V1).
563
+ *
564
+ * @param x402Version - The x402 protocol version
565
+ * @param paymentRequirements - The payment requirements
566
+ * @returns Promise resolving to a payment payload
567
+ */
568
+ async createPaymentPayload(x402Version, paymentRequirements) {
569
+ const selectedV1 = paymentRequirements;
570
+ const nonce = createNonce();
571
+ const now = Math.floor(Date.now() / 1e3);
572
+ const authorization = {
573
+ from: this.signer.address,
574
+ to: (0, import_viem8.getAddress)(selectedV1.payTo),
575
+ value: selectedV1.maxAmountRequired,
576
+ validAfter: (now - 600).toString(),
577
+ // 10 minutes before
578
+ validBefore: (now + selectedV1.maxTimeoutSeconds).toString(),
579
+ nonce
580
+ };
581
+ const signature = await this.signAuthorization(authorization, selectedV1);
582
+ const payload = {
583
+ authorization,
584
+ signature
585
+ };
586
+ return {
587
+ x402Version,
588
+ scheme: selectedV1.scheme,
589
+ network: selectedV1.network,
590
+ payload
591
+ };
592
+ }
593
+ /**
594
+ * Sign the EIP-3009 authorization using EIP-712
595
+ *
596
+ * @param authorization - The authorization to sign
597
+ * @param requirements - The payment requirements
598
+ * @returns Promise resolving to the signature
599
+ */
600
+ async signAuthorization(authorization, requirements) {
601
+ const chainId = getEvmChainIdV1(requirements.network);
602
+ if (!requirements.extra?.name || !requirements.extra?.version) {
603
+ throw new Error(
604
+ `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
605
+ );
606
+ }
607
+ const { name, version } = requirements.extra;
608
+ const domain = {
609
+ name,
610
+ version,
611
+ chainId,
612
+ verifyingContract: (0, import_viem8.getAddress)(requirements.asset)
613
+ };
614
+ const message = {
615
+ from: (0, import_viem8.getAddress)(authorization.from),
616
+ to: (0, import_viem8.getAddress)(authorization.to),
617
+ value: BigInt(authorization.value),
618
+ validAfter: BigInt(authorization.validAfter),
619
+ validBefore: BigInt(authorization.validBefore),
620
+ nonce: authorization.nonce
621
+ };
622
+ return await this.signer.signTypedData({
623
+ domain,
624
+ types: authorizationTypes,
625
+ primaryType: "TransferWithAuthorization",
626
+ message
627
+ });
628
+ }
537
629
  };
538
630
 
539
631
  // src/exact/client/register.ts