@x402/evm 2.6.0 → 2.8.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 (46) hide show
  1. package/README.md +29 -4
  2. package/dist/cjs/exact/client/index.d.ts +12 -5
  3. package/dist/cjs/exact/client/index.js +127 -28
  4. package/dist/cjs/exact/client/index.js.map +1 -1
  5. package/dist/cjs/exact/facilitator/index.d.ts +13 -1
  6. package/dist/cjs/exact/facilitator/index.js +987 -606
  7. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  8. package/dist/cjs/exact/v1/client/index.d.ts +1 -1
  9. package/dist/cjs/exact/v1/client/index.js +11 -5
  10. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  11. package/dist/cjs/exact/v1/facilitator/index.d.ts +16 -1
  12. package/dist/cjs/exact/v1/facilitator/index.js +414 -177
  13. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  14. package/dist/cjs/index.d.ts +2 -2
  15. package/dist/cjs/index.js +143 -30
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/{permit2-DHAq6FTe.d.ts → permit2-U9Zolx3O.d.ts} +38 -5
  18. package/dist/{esm/signer-DC81R8wQ.d.mts → cjs/signer-D912R4mq.d.ts} +9 -3
  19. package/dist/cjs/v1/index.d.ts +1 -1
  20. package/dist/cjs/v1/index.js +6 -0
  21. package/dist/cjs/v1/index.js.map +1 -1
  22. package/dist/esm/chunk-GD4MKCN7.mjs +57 -0
  23. package/dist/esm/chunk-GD4MKCN7.mjs.map +1 -0
  24. package/dist/esm/{chunk-XL6IFXCP.mjs → chunk-IZEI7JTG.mjs} +516 -178
  25. package/dist/esm/chunk-IZEI7JTG.mjs.map +1 -0
  26. package/dist/esm/{chunk-LBIJBD7Q.mjs → chunk-WJWNS4G4.mjs} +113 -20
  27. package/dist/esm/chunk-WJWNS4G4.mjs.map +1 -0
  28. package/dist/esm/exact/client/index.d.mts +12 -5
  29. package/dist/esm/exact/client/index.mjs +3 -2
  30. package/dist/esm/exact/facilitator/index.d.mts +13 -1
  31. package/dist/esm/exact/facilitator/index.mjs +498 -391
  32. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  33. package/dist/esm/exact/v1/client/index.d.mts +1 -1
  34. package/dist/esm/exact/v1/client/index.mjs +1 -1
  35. package/dist/esm/exact/v1/facilitator/index.d.mts +16 -1
  36. package/dist/esm/exact/v1/facilitator/index.mjs +1 -1
  37. package/dist/esm/index.d.mts +2 -2
  38. package/dist/esm/index.mjs +7 -9
  39. package/dist/esm/index.mjs.map +1 -1
  40. package/dist/esm/{permit2-BuAhWvNC.d.mts → permit2-Bbh3a8_h.d.mts} +38 -5
  41. package/dist/{cjs/signer-DC81R8wQ.d.ts → esm/signer-D912R4mq.d.mts} +9 -3
  42. package/dist/esm/v1/index.d.mts +1 -1
  43. package/dist/esm/v1/index.mjs +1 -1
  44. package/package.json +2 -3
  45. package/dist/esm/chunk-LBIJBD7Q.mjs.map +0 -1
  46. package/dist/esm/chunk-XL6IFXCP.mjs.map +0 -1
@@ -25,7 +25,7 @@ __export(facilitator_exports, {
25
25
  module.exports = __toCommonJS(facilitator_exports);
26
26
 
27
27
  // src/exact/v1/facilitator/scheme.ts
28
- var import_viem3 = require("viem");
28
+ var import_viem5 = require("viem");
29
29
 
30
30
  // src/constants.ts
31
31
  var authorizationTypes = {
@@ -84,6 +84,23 @@ var eip3009ABI = [
84
84
  outputs: [{ name: "", type: "string" }],
85
85
  stateMutability: "view",
86
86
  type: "function"
87
+ },
88
+ {
89
+ inputs: [],
90
+ name: "name",
91
+ outputs: [{ name: "", type: "string" }],
92
+ stateMutability: "view",
93
+ type: "function"
94
+ },
95
+ {
96
+ inputs: [
97
+ { name: "authorizer", type: "address" },
98
+ { name: "nonce", type: "bytes32" }
99
+ ],
100
+ name: "authorizationState",
101
+ outputs: [{ name: "", type: "bool" }],
102
+ stateMutability: "view",
103
+ type: "function"
87
104
  }
88
105
  ];
89
106
 
@@ -124,6 +141,257 @@ function getEvmChainIdV1(network) {
124
141
  return chainId;
125
142
  }
126
143
 
144
+ // src/exact/facilitator/errors.ts
145
+ var ErrInvalidScheme = "invalid_exact_evm_scheme";
146
+ var ErrNetworkMismatch = "invalid_exact_evm_network_mismatch";
147
+ var ErrMissingEip712Domain = "invalid_exact_evm_missing_eip712_domain";
148
+ var ErrRecipientMismatch = "invalid_exact_evm_recipient_mismatch";
149
+ var ErrInvalidSignature = "invalid_exact_evm_signature";
150
+ var ErrValidBeforeExpired = "invalid_exact_evm_payload_authorization_valid_before";
151
+ var ErrValidAfterInFuture = "invalid_exact_evm_payload_authorization_valid_after";
152
+ var ErrInvalidAuthorizationValue = "invalid_exact_evm_authorization_value";
153
+ var ErrUndeployedSmartWallet = "invalid_exact_evm_payload_undeployed_smart_wallet";
154
+ var ErrTransactionFailed = "invalid_exact_evm_transaction_failed";
155
+ var ErrEip3009TokenNameMismatch = "invalid_exact_evm_token_name_mismatch";
156
+ var ErrEip3009TokenVersionMismatch = "invalid_exact_evm_token_version_mismatch";
157
+ var ErrEip3009NotSupported = "invalid_exact_evm_eip3009_not_supported";
158
+ var ErrEip3009NonceAlreadyUsed = "invalid_exact_evm_nonce_already_used";
159
+ var ErrEip3009InsufficientBalance = "invalid_exact_evm_insufficient_balance";
160
+ var ErrEip3009SimulationFailed = "invalid_exact_evm_transaction_simulation_failed";
161
+
162
+ // src/exact/facilitator/eip3009-utils.ts
163
+ var import_viem4 = require("viem");
164
+
165
+ // src/multicall.ts
166
+ var import_viem3 = require("viem");
167
+ var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
168
+ var multicall3ABI = [
169
+ {
170
+ inputs: [
171
+ { name: "requireSuccess", type: "bool" },
172
+ {
173
+ name: "calls",
174
+ type: "tuple[]",
175
+ components: [
176
+ { name: "target", type: "address" },
177
+ { name: "callData", type: "bytes" }
178
+ ]
179
+ }
180
+ ],
181
+ name: "tryAggregate",
182
+ outputs: [
183
+ {
184
+ name: "returnData",
185
+ type: "tuple[]",
186
+ components: [
187
+ { name: "success", type: "bool" },
188
+ { name: "returnData", type: "bytes" }
189
+ ]
190
+ }
191
+ ],
192
+ stateMutability: "payable",
193
+ type: "function"
194
+ }
195
+ ];
196
+ async function multicall(readContract, calls) {
197
+ const aggregateCalls = calls.map((call) => {
198
+ if ("callData" in call) {
199
+ return { target: call.address, callData: call.callData };
200
+ }
201
+ const callData = (0, import_viem3.encodeFunctionData)({
202
+ abi: call.abi,
203
+ functionName: call.functionName,
204
+ args: call.args
205
+ });
206
+ return { target: call.address, callData };
207
+ });
208
+ const rawResults = await readContract({
209
+ address: MULTICALL3_ADDRESS,
210
+ abi: multicall3ABI,
211
+ functionName: "tryAggregate",
212
+ args: [false, aggregateCalls]
213
+ });
214
+ return rawResults.map((raw, i) => {
215
+ if (!raw.success) {
216
+ return {
217
+ status: "failure",
218
+ error: new Error(`multicall: call reverted (returnData: ${raw.returnData})`)
219
+ };
220
+ }
221
+ const call = calls[i];
222
+ if ("callData" in call) {
223
+ return { status: "success", result: void 0 };
224
+ }
225
+ try {
226
+ const decoded = (0, import_viem3.decodeFunctionResult)({
227
+ abi: call.abi,
228
+ functionName: call.functionName,
229
+ data: raw.returnData
230
+ });
231
+ return { status: "success", result: decoded };
232
+ } catch (err) {
233
+ return {
234
+ status: "failure",
235
+ error: err instanceof Error ? err : new Error(String(err))
236
+ };
237
+ }
238
+ });
239
+ }
240
+
241
+ // src/exact/facilitator/eip3009-utils.ts
242
+ async function simulateEip3009Transfer(signer, erc20Address, payload, eip6492Deployment) {
243
+ const auth = payload.authorization;
244
+ const transferArgs = [
245
+ (0, import_viem4.getAddress)(auth.from),
246
+ (0, import_viem4.getAddress)(auth.to),
247
+ BigInt(auth.value),
248
+ BigInt(auth.validAfter),
249
+ BigInt(auth.validBefore),
250
+ auth.nonce
251
+ ];
252
+ if (eip6492Deployment) {
253
+ const { signature: innerSignature } = (0, import_viem4.parseErc6492Signature)(payload.signature);
254
+ const transferCalldata = (0, import_viem4.encodeFunctionData)({
255
+ abi: eip3009ABI,
256
+ functionName: "transferWithAuthorization",
257
+ args: [...transferArgs, innerSignature]
258
+ });
259
+ try {
260
+ const results = await multicall(signer.readContract.bind(signer), [
261
+ {
262
+ address: (0, import_viem4.getAddress)(eip6492Deployment.factoryAddress),
263
+ callData: eip6492Deployment.factoryCalldata
264
+ },
265
+ {
266
+ address: erc20Address,
267
+ callData: transferCalldata
268
+ }
269
+ ]);
270
+ return results[1]?.status === "success";
271
+ } catch {
272
+ return false;
273
+ }
274
+ }
275
+ const sig = payload.signature;
276
+ const sigLength = sig.startsWith("0x") ? sig.length - 2 : sig.length;
277
+ const isECDSA = sigLength === 130;
278
+ try {
279
+ if (isECDSA) {
280
+ const parsedSig = (0, import_viem4.parseSignature)(sig);
281
+ await signer.readContract({
282
+ address: erc20Address,
283
+ abi: eip3009ABI,
284
+ functionName: "transferWithAuthorization",
285
+ args: [
286
+ ...transferArgs,
287
+ parsedSig.v ?? parsedSig.yParity,
288
+ parsedSig.r,
289
+ parsedSig.s
290
+ ]
291
+ });
292
+ } else {
293
+ await signer.readContract({
294
+ address: erc20Address,
295
+ abi: eip3009ABI,
296
+ functionName: "transferWithAuthorization",
297
+ args: [...transferArgs, sig]
298
+ });
299
+ }
300
+ return true;
301
+ } catch {
302
+ return false;
303
+ }
304
+ }
305
+ async function diagnoseEip3009SimulationFailure(signer, erc20Address, payload, requirements, amountRequired) {
306
+ const payer = payload.authorization.from;
307
+ const diagnosticCalls = [
308
+ {
309
+ address: erc20Address,
310
+ abi: eip3009ABI,
311
+ functionName: "balanceOf",
312
+ args: [payload.authorization.from]
313
+ },
314
+ {
315
+ address: erc20Address,
316
+ abi: eip3009ABI,
317
+ functionName: "name"
318
+ },
319
+ {
320
+ address: erc20Address,
321
+ abi: eip3009ABI,
322
+ functionName: "version"
323
+ },
324
+ {
325
+ address: erc20Address,
326
+ abi: eip3009ABI,
327
+ functionName: "authorizationState",
328
+ args: [payload.authorization.from, payload.authorization.nonce]
329
+ }
330
+ ];
331
+ try {
332
+ const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
333
+ const [balanceResult, nameResult, versionResult, authStateResult] = results;
334
+ if (authStateResult.status === "failure") {
335
+ return { isValid: false, invalidReason: ErrEip3009NotSupported, payer };
336
+ }
337
+ if (authStateResult.status === "success" && authStateResult.result === true) {
338
+ return { isValid: false, invalidReason: ErrEip3009NonceAlreadyUsed, payer };
339
+ }
340
+ if (nameResult.status === "success" && requirements.extra?.name && nameResult.result !== requirements.extra.name) {
341
+ return { isValid: false, invalidReason: ErrEip3009TokenNameMismatch, payer };
342
+ }
343
+ if (versionResult.status === "success" && requirements.extra?.version && versionResult.result !== requirements.extra.version) {
344
+ return { isValid: false, invalidReason: ErrEip3009TokenVersionMismatch, payer };
345
+ }
346
+ if (balanceResult.status === "success") {
347
+ const balance = balanceResult.result;
348
+ if (balance < BigInt(amountRequired)) {
349
+ return {
350
+ isValid: false,
351
+ invalidReason: ErrEip3009InsufficientBalance,
352
+ payer
353
+ };
354
+ }
355
+ }
356
+ } catch {
357
+ }
358
+ return { isValid: false, invalidReason: ErrEip3009SimulationFailed, payer };
359
+ }
360
+ async function executeTransferWithAuthorization(signer, erc20Address, payload) {
361
+ const { signature } = (0, import_viem4.parseErc6492Signature)(payload.signature);
362
+ const signatureLength = signature.startsWith("0x") ? signature.length - 2 : signature.length;
363
+ const isECDSA = signatureLength === 130;
364
+ const auth = payload.authorization;
365
+ const baseArgs = [
366
+ (0, import_viem4.getAddress)(auth.from),
367
+ (0, import_viem4.getAddress)(auth.to),
368
+ BigInt(auth.value),
369
+ BigInt(auth.validAfter),
370
+ BigInt(auth.validBefore),
371
+ auth.nonce
372
+ ];
373
+ if (isECDSA) {
374
+ const parsedSig = (0, import_viem4.parseSignature)(signature);
375
+ return signer.writeContract({
376
+ address: erc20Address,
377
+ abi: eip3009ABI,
378
+ functionName: "transferWithAuthorization",
379
+ args: [
380
+ ...baseArgs,
381
+ parsedSig.v || parsedSig.yParity,
382
+ parsedSig.r,
383
+ parsedSig.s
384
+ ]
385
+ });
386
+ }
387
+ return signer.writeContract({
388
+ address: erc20Address,
389
+ abi: eip3009ABI,
390
+ functionName: "transferWithAuthorization",
391
+ args: [...baseArgs, signature]
392
+ });
393
+ }
394
+
127
395
  // src/exact/v1/facilitator/scheme.ts
128
396
  var ExactEvmSchemeV12 = class {
129
397
  /**
@@ -137,7 +405,8 @@ var ExactEvmSchemeV12 = class {
137
405
  this.scheme = "exact";
138
406
  this.caipFamily = "eip155:*";
139
407
  this.config = {
140
- deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false
408
+ deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,
409
+ simulateInSettle: config?.simulateInSettle ?? false
141
410
  };
142
411
  }
143
412
  /**
@@ -168,14 +437,95 @@ var ExactEvmSchemeV12 = class {
168
437
  * @returns Promise resolving to verification response
169
438
  */
170
439
  async verify(payload, requirements) {
440
+ return this._verify(payload, requirements);
441
+ }
442
+ /**
443
+ * Settles a payment by executing the transfer (V1).
444
+ *
445
+ * @param payload - The payment payload to settle
446
+ * @param requirements - The payment requirements
447
+ * @returns Promise resolving to settlement response
448
+ */
449
+ async settle(payload, requirements) {
450
+ const payloadV1 = payload;
451
+ const exactEvmPayload = payload.payload;
452
+ const valid = await this._verify(payload, requirements, {
453
+ simulate: this.config.simulateInSettle ?? false
454
+ });
455
+ if (!valid.isValid) {
456
+ return {
457
+ success: false,
458
+ network: payloadV1.network,
459
+ transaction: "",
460
+ errorReason: valid.invalidReason ?? ErrInvalidScheme,
461
+ payer: exactEvmPayload.authorization.from
462
+ };
463
+ }
464
+ try {
465
+ const { address: factoryAddress, data: factoryCalldata } = (0, import_viem5.parseErc6492Signature)(
466
+ exactEvmPayload.signature
467
+ );
468
+ if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0, import_viem5.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
469
+ const payerAddress = exactEvmPayload.authorization.from;
470
+ const bytecode = await this.signer.getCode({ address: payerAddress });
471
+ if (!bytecode || bytecode === "0x") {
472
+ const deployTx = await this.signer.sendTransaction({
473
+ to: factoryAddress,
474
+ data: factoryCalldata
475
+ });
476
+ await this.signer.waitForTransactionReceipt({ hash: deployTx });
477
+ }
478
+ }
479
+ const tx = await executeTransferWithAuthorization(
480
+ this.signer,
481
+ (0, import_viem5.getAddress)(requirements.asset),
482
+ exactEvmPayload
483
+ );
484
+ const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });
485
+ if (receipt.status !== "success") {
486
+ return {
487
+ success: false,
488
+ errorReason: ErrTransactionFailed,
489
+ transaction: tx,
490
+ network: payloadV1.network,
491
+ payer: exactEvmPayload.authorization.from
492
+ };
493
+ }
494
+ return {
495
+ success: true,
496
+ transaction: tx,
497
+ network: payloadV1.network,
498
+ payer: exactEvmPayload.authorization.from
499
+ };
500
+ } catch (error) {
501
+ return {
502
+ success: false,
503
+ errorReason: error instanceof Error ? error.message : ErrTransactionFailed,
504
+ transaction: "",
505
+ network: payloadV1.network,
506
+ payer: exactEvmPayload.authorization.from
507
+ };
508
+ }
509
+ }
510
+ /**
511
+ * Internal verify with optional simulation control.
512
+ *
513
+ * @param payload - The payment payload to verify
514
+ * @param requirements - The payment requirements
515
+ * @param options - Verification options (e.g. simulate)
516
+ * @returns Promise resolving to verification response
517
+ */
518
+ async _verify(payload, requirements, options) {
171
519
  const requirementsV1 = requirements;
172
520
  const payloadV1 = payload;
173
521
  const exactEvmPayload = payload.payload;
522
+ const payer = exactEvmPayload.authorization.from;
523
+ let eip6492Deployment;
174
524
  if (payloadV1.scheme !== "exact" || requirements.scheme !== "exact") {
175
525
  return {
176
526
  isValid: false,
177
- invalidReason: "unsupported_scheme",
178
- payer: exactEvmPayload.authorization.from
527
+ invalidReason: ErrInvalidScheme,
528
+ payer
179
529
  };
180
530
  }
181
531
  let chainId;
@@ -184,24 +534,24 @@ var ExactEvmSchemeV12 = class {
184
534
  } catch {
185
535
  return {
186
536
  isValid: false,
187
- invalidReason: `invalid_network`,
188
- payer: exactEvmPayload.authorization.from
537
+ invalidReason: ErrNetworkMismatch,
538
+ payer
189
539
  };
190
540
  }
191
541
  if (!requirements.extra?.name || !requirements.extra?.version) {
192
542
  return {
193
543
  isValid: false,
194
- invalidReason: "missing_eip712_domain",
195
- payer: exactEvmPayload.authorization.from
544
+ invalidReason: ErrMissingEip712Domain,
545
+ payer
196
546
  };
197
547
  }
198
548
  const { name, version } = requirements.extra;
199
- const erc20Address = (0, import_viem3.getAddress)(requirements.asset);
549
+ const erc20Address = (0, import_viem5.getAddress)(requirements.asset);
200
550
  if (payloadV1.network !== requirements.network) {
201
551
  return {
202
552
  isValid: false,
203
- invalidReason: "network_mismatch",
204
- payer: exactEvmPayload.authorization.from
553
+ invalidReason: ErrNetworkMismatch,
554
+ payer
205
555
  };
206
556
  }
207
557
  const permitTypedData = {
@@ -222,210 +572,97 @@ var ExactEvmSchemeV12 = class {
222
572
  nonce: exactEvmPayload.authorization.nonce
223
573
  }
224
574
  };
575
+ let isValid = false;
225
576
  try {
226
- const recoveredAddress = await this.signer.verifyTypedData({
227
- address: exactEvmPayload.authorization.from,
577
+ isValid = await this.signer.verifyTypedData({
578
+ address: payer,
228
579
  ...permitTypedData,
229
580
  signature: exactEvmPayload.signature
230
581
  });
231
- if (!recoveredAddress) {
582
+ } catch {
583
+ isValid = false;
584
+ }
585
+ const signature = exactEvmPayload.signature;
586
+ const sigLen = signature.startsWith("0x") ? signature.length - 2 : signature.length;
587
+ const erc6492Data = (0, import_viem5.parseErc6492Signature)(signature);
588
+ const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem5.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
589
+ if (hasDeploymentInfo) {
590
+ eip6492Deployment = {
591
+ factoryAddress: erc6492Data.address,
592
+ factoryCalldata: erc6492Data.data
593
+ };
594
+ }
595
+ if (!isValid) {
596
+ const isSmartWallet = sigLen > 130;
597
+ if (!isSmartWallet) {
232
598
  return {
233
599
  isValid: false,
234
- invalidReason: "invalid_exact_evm_payload_signature",
235
- payer: exactEvmPayload.authorization.from
600
+ invalidReason: ErrInvalidSignature,
601
+ payer
236
602
  };
237
603
  }
238
- } catch {
239
- const signature = exactEvmPayload.signature;
240
- const signatureLength = signature.startsWith("0x") ? signature.length - 2 : signature.length;
241
- const isSmartWallet = signatureLength > 130;
242
- if (isSmartWallet) {
243
- const payerAddress = exactEvmPayload.authorization.from;
244
- const bytecode = await this.signer.getCode({ address: payerAddress });
245
- if (!bytecode || bytecode === "0x") {
246
- const erc6492Data = (0, import_viem3.parseErc6492Signature)(signature);
247
- const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem3.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
248
- if (!hasDeploymentInfo) {
249
- return {
250
- isValid: false,
251
- invalidReason: "invalid_exact_evm_payload_undeployed_smart_wallet",
252
- payer: payerAddress
253
- };
254
- }
255
- } else {
256
- return {
257
- isValid: false,
258
- invalidReason: "invalid_exact_evm_payload_signature",
259
- payer: exactEvmPayload.authorization.from
260
- };
261
- }
262
- } else {
604
+ const bytecode = await this.signer.getCode({ address: payer });
605
+ const isDeployed = bytecode && bytecode !== "0x";
606
+ if (!isDeployed && !hasDeploymentInfo) {
263
607
  return {
264
608
  isValid: false,
265
- invalidReason: "invalid_exact_evm_payload_signature",
266
- payer: exactEvmPayload.authorization.from
609
+ invalidReason: ErrUndeployedSmartWallet,
610
+ payer
267
611
  };
268
612
  }
269
613
  }
270
- if ((0, import_viem3.getAddress)(exactEvmPayload.authorization.to) !== (0, import_viem3.getAddress)(requirements.payTo)) {
614
+ if ((0, import_viem5.getAddress)(exactEvmPayload.authorization.to) !== (0, import_viem5.getAddress)(requirements.payTo)) {
271
615
  return {
272
616
  isValid: false,
273
- invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
274
- payer: exactEvmPayload.authorization.from
617
+ invalidReason: ErrRecipientMismatch,
618
+ payer
275
619
  };
276
620
  }
277
621
  const now = Math.floor(Date.now() / 1e3);
278
622
  if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) {
279
623
  return {
280
624
  isValid: false,
281
- invalidReason: "invalid_exact_evm_payload_authorization_valid_before",
282
- payer: exactEvmPayload.authorization.from
625
+ invalidReason: ErrValidBeforeExpired,
626
+ payer
283
627
  };
284
628
  }
285
629
  if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) {
286
630
  return {
287
631
  isValid: false,
288
- invalidReason: "invalid_exact_evm_payload_authorization_valid_after",
289
- payer: exactEvmPayload.authorization.from
632
+ invalidReason: ErrValidAfterInFuture,
633
+ payer
290
634
  };
291
635
  }
292
- try {
293
- const balance = await this.signer.readContract({
294
- address: erc20Address,
295
- abi: eip3009ABI,
296
- functionName: "balanceOf",
297
- args: [exactEvmPayload.authorization.from]
298
- });
299
- if (BigInt(balance) < BigInt(requirementsV1.maxAmountRequired)) {
300
- return {
301
- isValid: false,
302
- invalidReason: "insufficient_funds",
303
- invalidMessage: `Insufficient funds to complete the payment. Required: ${requirementsV1.maxAmountRequired} ${requirements.asset}, Available: ${balance.toString()} ${requirements.asset}. Please add funds to your wallet and try again.`,
304
- payer: exactEvmPayload.authorization.from
305
- };
306
- }
307
- } catch {
308
- }
309
636
  if (BigInt(exactEvmPayload.authorization.value) !== BigInt(requirementsV1.maxAmountRequired)) {
310
637
  return {
311
638
  isValid: false,
312
- invalidReason: "invalid_exact_evm_payload_authorization_value_mismatch",
313
- payer: exactEvmPayload.authorization.from
639
+ invalidReason: ErrInvalidAuthorizationValue,
640
+ payer
314
641
  };
315
642
  }
643
+ if (options?.simulate !== false) {
644
+ const simulationSucceeded = await simulateEip3009Transfer(
645
+ this.signer,
646
+ erc20Address,
647
+ exactEvmPayload,
648
+ eip6492Deployment
649
+ );
650
+ if (!simulationSucceeded) {
651
+ return diagnoseEip3009SimulationFailure(
652
+ this.signer,
653
+ erc20Address,
654
+ exactEvmPayload,
655
+ requirements,
656
+ requirementsV1.maxAmountRequired
657
+ );
658
+ }
659
+ }
316
660
  return {
317
661
  isValid: true,
318
662
  invalidReason: void 0,
319
- payer: exactEvmPayload.authorization.from
663
+ payer
320
664
  };
321
665
  }
322
- /**
323
- * Settles a payment by executing the transfer (V1).
324
- *
325
- * @param payload - The payment payload to settle
326
- * @param requirements - The payment requirements
327
- * @returns Promise resolving to settlement response
328
- */
329
- async settle(payload, requirements) {
330
- const payloadV1 = payload;
331
- const exactEvmPayload = payload.payload;
332
- const valid = await this.verify(payload, requirements);
333
- if (!valid.isValid) {
334
- return {
335
- success: false,
336
- network: payloadV1.network,
337
- transaction: "",
338
- errorReason: valid.invalidReason ?? "invalid_scheme",
339
- payer: exactEvmPayload.authorization.from
340
- };
341
- }
342
- try {
343
- const parseResult = (0, import_viem3.parseErc6492Signature)(exactEvmPayload.signature);
344
- const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;
345
- if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0, import_viem3.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
346
- const payerAddress = exactEvmPayload.authorization.from;
347
- const bytecode = await this.signer.getCode({ address: payerAddress });
348
- if (!bytecode || bytecode === "0x") {
349
- try {
350
- console.log(`Deploying ERC-4337 smart wallet for ${payerAddress} via EIP-6492`);
351
- const deployTx = await this.signer.sendTransaction({
352
- to: factoryAddress,
353
- data: factoryCalldata
354
- });
355
- await this.signer.waitForTransactionReceipt({ hash: deployTx });
356
- console.log(`Successfully deployed smart wallet for ${payerAddress}`);
357
- } catch (deployError) {
358
- console.error("Smart wallet deployment failed:", deployError);
359
- throw deployError;
360
- }
361
- } else {
362
- console.log(`Smart wallet for ${payerAddress} already deployed, skipping deployment`);
363
- }
364
- }
365
- const signatureLength = signature.startsWith("0x") ? signature.length - 2 : signature.length;
366
- const isECDSA = signatureLength === 130;
367
- let tx;
368
- if (isECDSA) {
369
- const parsedSig = (0, import_viem3.parseSignature)(signature);
370
- tx = await this.signer.writeContract({
371
- address: (0, import_viem3.getAddress)(requirements.asset),
372
- abi: eip3009ABI,
373
- functionName: "transferWithAuthorization",
374
- args: [
375
- (0, import_viem3.getAddress)(exactEvmPayload.authorization.from),
376
- (0, import_viem3.getAddress)(exactEvmPayload.authorization.to),
377
- BigInt(exactEvmPayload.authorization.value),
378
- BigInt(exactEvmPayload.authorization.validAfter),
379
- BigInt(exactEvmPayload.authorization.validBefore),
380
- exactEvmPayload.authorization.nonce,
381
- parsedSig.v || parsedSig.yParity,
382
- parsedSig.r,
383
- parsedSig.s
384
- ]
385
- });
386
- } else {
387
- tx = await this.signer.writeContract({
388
- address: (0, import_viem3.getAddress)(requirements.asset),
389
- abi: eip3009ABI,
390
- functionName: "transferWithAuthorization",
391
- args: [
392
- (0, import_viem3.getAddress)(exactEvmPayload.authorization.from),
393
- (0, import_viem3.getAddress)(exactEvmPayload.authorization.to),
394
- BigInt(exactEvmPayload.authorization.value),
395
- BigInt(exactEvmPayload.authorization.validAfter),
396
- BigInt(exactEvmPayload.authorization.validBefore),
397
- exactEvmPayload.authorization.nonce,
398
- signature
399
- ]
400
- });
401
- }
402
- const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });
403
- if (receipt.status !== "success") {
404
- return {
405
- success: false,
406
- errorReason: "invalid_transaction_state",
407
- transaction: tx,
408
- network: payloadV1.network,
409
- payer: exactEvmPayload.authorization.from
410
- };
411
- }
412
- return {
413
- success: true,
414
- transaction: tx,
415
- network: payloadV1.network,
416
- payer: exactEvmPayload.authorization.from
417
- };
418
- } catch (error) {
419
- console.error("Failed to settle transaction:", error);
420
- return {
421
- success: false,
422
- errorReason: "transaction_failed",
423
- transaction: "",
424
- network: payloadV1.network,
425
- payer: exactEvmPayload.authorization.from
426
- };
427
- }
428
- }
429
666
  };
430
667
  // Annotate the CommonJS export names for ESM import in node:
431
668
  0 && (module.exports = {