@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.
- package/dist/cjs/exact/client/index.d.ts +2 -2
- package/dist/cjs/exact/client/index.js +284 -192
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.d.ts +18 -18
- package/dist/cjs/exact/facilitator/index.js +454 -234
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.d.ts +1 -1
- package/dist/cjs/exact/v1/client/index.js +17 -18
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +7 -8
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +3 -390
- package/dist/cjs/index.js +225 -132
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/permit2-CQbXqCMC.d.ts +517 -0
- package/dist/cjs/{signer-3KGwtdNT.d.ts → signer-DC81R8wQ.d.ts} +37 -0
- package/dist/cjs/v1/index.d.ts +11 -2
- package/dist/cjs/v1/index.js +14 -11
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/{chunk-GSU4DHTC.mjs → chunk-7KHQD5KT.mjs} +72 -37
- package/dist/esm/chunk-7KHQD5KT.mjs.map +1 -0
- package/dist/esm/{chunk-CJHYX7BQ.mjs → chunk-GY6X5A3G.mjs} +119 -56
- package/dist/esm/chunk-GY6X5A3G.mjs.map +1 -0
- package/dist/esm/{chunk-PFULIQAE.mjs → chunk-TKN5V2BV.mjs} +1 -1
- package/dist/esm/chunk-TKN5V2BV.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +2 -2
- package/dist/esm/exact/client/index.mjs +4 -3
- package/dist/esm/exact/facilitator/index.d.mts +18 -18
- package/dist/esm/exact/facilitator/index.mjs +385 -176
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.d.mts +1 -1
- package/dist/esm/exact/v1/client/index.mjs +2 -2
- package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +2 -2
- package/dist/esm/index.d.mts +3 -390
- package/dist/esm/index.mjs +18 -5
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/permit2-CGOcN7Et.d.mts +517 -0
- package/dist/esm/{signer-3KGwtdNT.d.mts → signer-DC81R8wQ.d.mts} +37 -0
- package/dist/esm/v1/index.d.mts +11 -2
- package/dist/esm/v1/index.mjs +6 -4
- package/package.json +3 -3
- package/dist/cjs/permit2-CzKPU5By.d.ts +0 -130
- package/dist/esm/chunk-CJHYX7BQ.mjs.map +0 -1
- package/dist/esm/chunk-GSU4DHTC.mjs.map +0 -1
- package/dist/esm/chunk-PFULIQAE.mjs.map +0 -1
- package/dist/esm/permit2-C2FkNEHT.d.mts +0 -130
|
@@ -31,7 +31,7 @@ function isPermit2Payload(payload) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// src/exact/facilitator/eip3009.ts
|
|
34
|
-
var
|
|
34
|
+
var import_viem2 = require("viem");
|
|
35
35
|
|
|
36
36
|
// src/constants.ts
|
|
37
37
|
var authorizationTypes = {
|
|
@@ -58,8 +58,7 @@ var permit2WitnessTypes = {
|
|
|
58
58
|
],
|
|
59
59
|
Witness: [
|
|
60
60
|
{ name: "to", type: "address" },
|
|
61
|
-
{ name: "validAfter", type: "uint256" }
|
|
62
|
-
{ name: "extra", type: "bytes" }
|
|
61
|
+
{ name: "validAfter", type: "uint256" }
|
|
63
62
|
]
|
|
64
63
|
};
|
|
65
64
|
var eip3009ABI = [
|
|
@@ -110,8 +109,36 @@ var eip3009ABI = [
|
|
|
110
109
|
type: "function"
|
|
111
110
|
}
|
|
112
111
|
];
|
|
112
|
+
var erc20ApproveAbi = [
|
|
113
|
+
{
|
|
114
|
+
type: "function",
|
|
115
|
+
name: "approve",
|
|
116
|
+
inputs: [
|
|
117
|
+
{ name: "spender", type: "address" },
|
|
118
|
+
{ name: "amount", type: "uint256" }
|
|
119
|
+
],
|
|
120
|
+
outputs: [{ type: "bool" }],
|
|
121
|
+
stateMutability: "nonpayable"
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
var erc20AllowanceAbi = [
|
|
125
|
+
{
|
|
126
|
+
type: "function",
|
|
127
|
+
name: "allowance",
|
|
128
|
+
inputs: [
|
|
129
|
+
{ name: "owner", type: "address" },
|
|
130
|
+
{ name: "spender", type: "address" }
|
|
131
|
+
],
|
|
132
|
+
outputs: [{ type: "uint256" }],
|
|
133
|
+
stateMutability: "view"
|
|
134
|
+
}
|
|
135
|
+
];
|
|
113
136
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
114
|
-
var x402ExactPermit2ProxyAddress = "
|
|
137
|
+
var x402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
138
|
+
var permit2WitnessABIComponents = [
|
|
139
|
+
{ name: "to", type: "address", internalType: "address" },
|
|
140
|
+
{ name: "validAfter", type: "uint256", internalType: "uint256" }
|
|
141
|
+
];
|
|
115
142
|
var x402ExactPermit2ProxyABI = [
|
|
116
143
|
{
|
|
117
144
|
type: "function",
|
|
@@ -134,13 +161,6 @@ var x402ExactPermit2ProxyABI = [
|
|
|
134
161
|
outputs: [{ name: "", type: "string", internalType: "string" }],
|
|
135
162
|
stateMutability: "view"
|
|
136
163
|
},
|
|
137
|
-
{
|
|
138
|
-
type: "function",
|
|
139
|
-
name: "initialize",
|
|
140
|
-
inputs: [{ name: "_permit2", type: "address", internalType: "address" }],
|
|
141
|
-
outputs: [],
|
|
142
|
-
stateMutability: "nonpayable"
|
|
143
|
-
},
|
|
144
164
|
{
|
|
145
165
|
type: "function",
|
|
146
166
|
name: "settle",
|
|
@@ -167,12 +187,8 @@ var x402ExactPermit2ProxyABI = [
|
|
|
167
187
|
{
|
|
168
188
|
name: "witness",
|
|
169
189
|
type: "tuple",
|
|
170
|
-
internalType: "struct
|
|
171
|
-
components:
|
|
172
|
-
{ name: "to", type: "address", internalType: "address" },
|
|
173
|
-
{ name: "validAfter", type: "uint256", internalType: "uint256" },
|
|
174
|
-
{ name: "extra", type: "bytes", internalType: "bytes" }
|
|
175
|
-
]
|
|
190
|
+
internalType: "struct x402ExactPermit2Proxy.Witness",
|
|
191
|
+
components: permit2WitnessABIComponents
|
|
176
192
|
},
|
|
177
193
|
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
178
194
|
],
|
|
@@ -186,7 +202,7 @@ var x402ExactPermit2ProxyABI = [
|
|
|
186
202
|
{
|
|
187
203
|
name: "permit2612",
|
|
188
204
|
type: "tuple",
|
|
189
|
-
internalType: "struct
|
|
205
|
+
internalType: "struct x402ExactPermit2Proxy.EIP2612Permit",
|
|
190
206
|
components: [
|
|
191
207
|
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
192
208
|
{ name: "deadline", type: "uint256", internalType: "uint256" },
|
|
@@ -217,12 +233,8 @@ var x402ExactPermit2ProxyABI = [
|
|
|
217
233
|
{
|
|
218
234
|
name: "witness",
|
|
219
235
|
type: "tuple",
|
|
220
|
-
internalType: "struct
|
|
221
|
-
components:
|
|
222
|
-
{ name: "to", type: "address", internalType: "address" },
|
|
223
|
-
{ name: "validAfter", type: "uint256", internalType: "uint256" },
|
|
224
|
-
{ name: "extra", type: "bytes", internalType: "bytes" }
|
|
225
|
-
]
|
|
236
|
+
internalType: "struct x402ExactPermit2Proxy.Witness",
|
|
237
|
+
components: permit2WitnessABIComponents
|
|
226
238
|
},
|
|
227
239
|
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
228
240
|
],
|
|
@@ -231,14 +243,29 @@ var x402ExactPermit2ProxyABI = [
|
|
|
231
243
|
},
|
|
232
244
|
{ type: "event", name: "Settled", inputs: [], anonymous: false },
|
|
233
245
|
{ type: "event", name: "SettledWithPermit", inputs: [], anonymous: false },
|
|
234
|
-
{ type: "error", name: "
|
|
246
|
+
{ type: "error", name: "InvalidAmount", inputs: [] },
|
|
235
247
|
{ type: "error", name: "InvalidDestination", inputs: [] },
|
|
236
248
|
{ type: "error", name: "InvalidOwner", inputs: [] },
|
|
237
249
|
{ type: "error", name: "InvalidPermit2Address", inputs: [] },
|
|
238
250
|
{ type: "error", name: "PaymentTooEarly", inputs: [] },
|
|
251
|
+
{ type: "error", name: "Permit2612AmountMismatch", inputs: [] },
|
|
239
252
|
{ type: "error", name: "ReentrancyGuardReentrantCall", inputs: [] }
|
|
240
253
|
];
|
|
241
254
|
|
|
255
|
+
// src/utils.ts
|
|
256
|
+
var import_viem = require("viem");
|
|
257
|
+
function getEvmChainId(network) {
|
|
258
|
+
if (network.startsWith("eip155:")) {
|
|
259
|
+
const idStr = network.split(":")[1];
|
|
260
|
+
const chainId = parseInt(idStr, 10);
|
|
261
|
+
if (isNaN(chainId)) {
|
|
262
|
+
throw new Error(`Invalid CAIP-2 chain ID: ${network}`);
|
|
263
|
+
}
|
|
264
|
+
return chainId;
|
|
265
|
+
}
|
|
266
|
+
throw new Error(`Unsupported network format: ${network} (expected eip155:CHAIN_ID)`);
|
|
267
|
+
}
|
|
268
|
+
|
|
242
269
|
// src/exact/facilitator/eip3009.ts
|
|
243
270
|
async function verifyEIP3009(signer, payload, requirements, eip3009Payload) {
|
|
244
271
|
const payer = eip3009Payload.authorization.from;
|
|
@@ -257,7 +284,7 @@ async function verifyEIP3009(signer, payload, requirements, eip3009Payload) {
|
|
|
257
284
|
};
|
|
258
285
|
}
|
|
259
286
|
const { name, version } = requirements.extra;
|
|
260
|
-
const erc20Address = (0,
|
|
287
|
+
const erc20Address = (0, import_viem2.getAddress)(requirements.asset);
|
|
261
288
|
if (payload.accepted.network !== requirements.network) {
|
|
262
289
|
return {
|
|
263
290
|
isValid: false,
|
|
@@ -271,7 +298,7 @@ async function verifyEIP3009(signer, payload, requirements, eip3009Payload) {
|
|
|
271
298
|
domain: {
|
|
272
299
|
name,
|
|
273
300
|
version,
|
|
274
|
-
chainId:
|
|
301
|
+
chainId: getEvmChainId(requirements.network),
|
|
275
302
|
verifyingContract: erc20Address
|
|
276
303
|
},
|
|
277
304
|
message: {
|
|
@@ -304,8 +331,8 @@ async function verifyEIP3009(signer, payload, requirements, eip3009Payload) {
|
|
|
304
331
|
const payerAddress = eip3009Payload.authorization.from;
|
|
305
332
|
const bytecode = await signer.getCode({ address: payerAddress });
|
|
306
333
|
if (!bytecode || bytecode === "0x") {
|
|
307
|
-
const erc6492Data = (0,
|
|
308
|
-
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0,
|
|
334
|
+
const erc6492Data = (0, import_viem2.parseErc6492Signature)(signature);
|
|
335
|
+
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem2.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
|
|
309
336
|
if (!hasDeploymentInfo) {
|
|
310
337
|
return {
|
|
311
338
|
isValid: false,
|
|
@@ -328,7 +355,7 @@ async function verifyEIP3009(signer, payload, requirements, eip3009Payload) {
|
|
|
328
355
|
};
|
|
329
356
|
}
|
|
330
357
|
}
|
|
331
|
-
if ((0,
|
|
358
|
+
if ((0, import_viem2.getAddress)(eip3009Payload.authorization.to) !== (0, import_viem2.getAddress)(requirements.payTo)) {
|
|
332
359
|
return {
|
|
333
360
|
isValid: false,
|
|
334
361
|
invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
|
|
@@ -393,9 +420,9 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
393
420
|
};
|
|
394
421
|
}
|
|
395
422
|
try {
|
|
396
|
-
const parseResult = (0,
|
|
423
|
+
const parseResult = (0, import_viem2.parseErc6492Signature)(eip3009Payload.signature);
|
|
397
424
|
const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;
|
|
398
|
-
if (config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0,
|
|
425
|
+
if (config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0, import_viem2.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
|
|
399
426
|
const bytecode = await signer.getCode({ address: payer });
|
|
400
427
|
if (!bytecode || bytecode === "0x") {
|
|
401
428
|
const deployTx = await signer.sendTransaction({
|
|
@@ -409,14 +436,14 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
409
436
|
const isECDSA = signatureLength === 130;
|
|
410
437
|
let tx;
|
|
411
438
|
if (isECDSA) {
|
|
412
|
-
const parsedSig = (0,
|
|
439
|
+
const parsedSig = (0, import_viem2.parseSignature)(signature);
|
|
413
440
|
tx = await signer.writeContract({
|
|
414
|
-
address: (0,
|
|
441
|
+
address: (0, import_viem2.getAddress)(requirements.asset),
|
|
415
442
|
abi: eip3009ABI,
|
|
416
443
|
functionName: "transferWithAuthorization",
|
|
417
444
|
args: [
|
|
418
|
-
(0,
|
|
419
|
-
(0,
|
|
445
|
+
(0, import_viem2.getAddress)(eip3009Payload.authorization.from),
|
|
446
|
+
(0, import_viem2.getAddress)(eip3009Payload.authorization.to),
|
|
420
447
|
BigInt(eip3009Payload.authorization.value),
|
|
421
448
|
BigInt(eip3009Payload.authorization.validAfter),
|
|
422
449
|
BigInt(eip3009Payload.authorization.validBefore),
|
|
@@ -428,12 +455,12 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
428
455
|
});
|
|
429
456
|
} else {
|
|
430
457
|
tx = await signer.writeContract({
|
|
431
|
-
address: (0,
|
|
458
|
+
address: (0, import_viem2.getAddress)(requirements.asset),
|
|
432
459
|
abi: eip3009ABI,
|
|
433
460
|
functionName: "transferWithAuthorization",
|
|
434
461
|
args: [
|
|
435
|
-
(0,
|
|
436
|
-
(0,
|
|
462
|
+
(0, import_viem2.getAddress)(eip3009Payload.authorization.from),
|
|
463
|
+
(0, import_viem2.getAddress)(eip3009Payload.authorization.to),
|
|
437
464
|
BigInt(eip3009Payload.authorization.value),
|
|
438
465
|
BigInt(eip3009Payload.authorization.validAfter),
|
|
439
466
|
BigInt(eip3009Payload.authorization.validBefore),
|
|
@@ -470,21 +497,130 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
470
497
|
}
|
|
471
498
|
|
|
472
499
|
// src/exact/facilitator/permit2.ts
|
|
500
|
+
var import_extensions2 = require("@x402/extensions");
|
|
501
|
+
var import_viem4 = require("viem");
|
|
502
|
+
|
|
503
|
+
// src/exact/facilitator/errors.ts
|
|
504
|
+
var ErrPermit2InvalidSignature = "invalid_permit2_signature";
|
|
505
|
+
var ErrPermit2InvalidAmount = "permit2_invalid_amount";
|
|
506
|
+
var ErrPermit2InvalidDestination = "permit2_invalid_destination";
|
|
507
|
+
var ErrPermit2InvalidOwner = "permit2_invalid_owner";
|
|
508
|
+
var ErrPermit2PaymentTooEarly = "permit2_payment_too_early";
|
|
509
|
+
var ErrPermit2InvalidNonce = "permit2_invalid_nonce";
|
|
510
|
+
var ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch";
|
|
511
|
+
var ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format";
|
|
512
|
+
var ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch";
|
|
513
|
+
var ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch";
|
|
514
|
+
var ErrErc20ApprovalSpenderNotPermit2 = "erc20_approval_spender_not_permit2";
|
|
515
|
+
var ErrErc20ApprovalTxWrongTarget = "erc20_approval_tx_wrong_target";
|
|
516
|
+
var ErrErc20ApprovalTxWrongSelector = "erc20_approval_tx_wrong_selector";
|
|
517
|
+
var ErrErc20ApprovalTxWrongSpender = "erc20_approval_tx_wrong_spender";
|
|
518
|
+
var ErrErc20ApprovalTxInvalidCalldata = "erc20_approval_tx_invalid_calldata";
|
|
519
|
+
var ErrErc20ApprovalTxSignerMismatch = "erc20_approval_tx_signer_mismatch";
|
|
520
|
+
var ErrErc20ApprovalTxInvalidSignature = "erc20_approval_tx_invalid_signature";
|
|
521
|
+
var ErrErc20ApprovalTxParseFailed = "erc20_approval_tx_parse_failed";
|
|
522
|
+
|
|
523
|
+
// src/exact/facilitator/erc20approval.ts
|
|
524
|
+
var import_viem3 = require("viem");
|
|
473
525
|
var import_extensions = require("@x402/extensions");
|
|
474
|
-
var
|
|
475
|
-
|
|
476
|
-
{
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
],
|
|
483
|
-
outputs: [{ type: "uint256" }],
|
|
484
|
-
stateMutability: "view"
|
|
526
|
+
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
527
|
+
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
528
|
+
if (!(0, import_extensions.validateErc20ApprovalGasSponsoringInfo)(info)) {
|
|
529
|
+
return {
|
|
530
|
+
isValid: false,
|
|
531
|
+
invalidReason: ErrErc20ApprovalInvalidFormat,
|
|
532
|
+
invalidMessage: "ERC-20 approval extension info failed schema validation"
|
|
533
|
+
};
|
|
485
534
|
}
|
|
486
|
-
|
|
487
|
-
|
|
535
|
+
if ((0, import_viem3.getAddress)(info.from) !== (0, import_viem3.getAddress)(payer)) {
|
|
536
|
+
return {
|
|
537
|
+
isValid: false,
|
|
538
|
+
invalidReason: ErrErc20ApprovalFromMismatch,
|
|
539
|
+
invalidMessage: `Expected from=${payer}, got ${info.from}`
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
if ((0, import_viem3.getAddress)(info.asset) !== tokenAddress) {
|
|
543
|
+
return {
|
|
544
|
+
isValid: false,
|
|
545
|
+
invalidReason: ErrErc20ApprovalAssetMismatch,
|
|
546
|
+
invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
if ((0, import_viem3.getAddress)(info.spender) !== (0, import_viem3.getAddress)(PERMIT2_ADDRESS)) {
|
|
550
|
+
return {
|
|
551
|
+
isValid: false,
|
|
552
|
+
invalidReason: ErrErc20ApprovalSpenderNotPermit2,
|
|
553
|
+
invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
try {
|
|
557
|
+
const serializedTx = info.signedTransaction;
|
|
558
|
+
const tx = (0, import_viem3.parseTransaction)(serializedTx);
|
|
559
|
+
if (!tx.to || (0, import_viem3.getAddress)(tx.to) !== tokenAddress) {
|
|
560
|
+
return {
|
|
561
|
+
isValid: false,
|
|
562
|
+
invalidReason: ErrErc20ApprovalTxWrongTarget,
|
|
563
|
+
invalidMessage: `Transaction targets ${tx.to ?? "null"}, expected ${tokenAddress}`
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
const data = tx.data ?? "0x";
|
|
567
|
+
if (!data.startsWith(APPROVE_SELECTOR)) {
|
|
568
|
+
return {
|
|
569
|
+
isValid: false,
|
|
570
|
+
invalidReason: ErrErc20ApprovalTxWrongSelector,
|
|
571
|
+
invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
try {
|
|
575
|
+
const decoded = (0, import_viem3.decodeFunctionData)({
|
|
576
|
+
abi: erc20ApproveAbi,
|
|
577
|
+
data
|
|
578
|
+
});
|
|
579
|
+
const calldataSpender = (0, import_viem3.getAddress)(decoded.args[0]);
|
|
580
|
+
if (calldataSpender !== (0, import_viem3.getAddress)(PERMIT2_ADDRESS)) {
|
|
581
|
+
return {
|
|
582
|
+
isValid: false,
|
|
583
|
+
invalidReason: ErrErc20ApprovalTxWrongSpender,
|
|
584
|
+
invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
} catch {
|
|
588
|
+
return {
|
|
589
|
+
isValid: false,
|
|
590
|
+
invalidReason: ErrErc20ApprovalTxInvalidCalldata,
|
|
591
|
+
invalidMessage: "Failed to decode approve() calldata from the signed transaction"
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
const recoveredAddress = await (0, import_viem3.recoverTransactionAddress)({
|
|
596
|
+
serializedTransaction: serializedTx
|
|
597
|
+
});
|
|
598
|
+
if ((0, import_viem3.getAddress)(recoveredAddress) !== (0, import_viem3.getAddress)(payer)) {
|
|
599
|
+
return {
|
|
600
|
+
isValid: false,
|
|
601
|
+
invalidReason: ErrErc20ApprovalTxSignerMismatch,
|
|
602
|
+
invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
} catch {
|
|
606
|
+
return {
|
|
607
|
+
isValid: false,
|
|
608
|
+
invalidReason: ErrErc20ApprovalTxInvalidSignature,
|
|
609
|
+
invalidMessage: "Failed to recover signer from the signed transaction"
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
} catch {
|
|
613
|
+
return {
|
|
614
|
+
isValid: false,
|
|
615
|
+
invalidReason: ErrErc20ApprovalTxParseFailed,
|
|
616
|
+
invalidMessage: "Failed to parse the signed transaction"
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
return { isValid: true };
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/exact/facilitator/permit2.ts
|
|
623
|
+
async function verifyPermit2(signer, payload, requirements, permit2Payload, context) {
|
|
488
624
|
const payer = permit2Payload.permit2Authorization.from;
|
|
489
625
|
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
490
626
|
return {
|
|
@@ -500,16 +636,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
500
636
|
payer
|
|
501
637
|
};
|
|
502
638
|
}
|
|
503
|
-
const chainId =
|
|
504
|
-
const tokenAddress = (0,
|
|
505
|
-
if ((0,
|
|
639
|
+
const chainId = getEvmChainId(requirements.network);
|
|
640
|
+
const tokenAddress = (0, import_viem4.getAddress)(requirements.asset);
|
|
641
|
+
if ((0, import_viem4.getAddress)(permit2Payload.permit2Authorization.spender) !== (0, import_viem4.getAddress)(x402ExactPermit2ProxyAddress)) {
|
|
506
642
|
return {
|
|
507
643
|
isValid: false,
|
|
508
644
|
invalidReason: "invalid_permit2_spender",
|
|
509
645
|
payer
|
|
510
646
|
};
|
|
511
647
|
}
|
|
512
|
-
if ((0,
|
|
648
|
+
if ((0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to) !== (0, import_viem4.getAddress)(requirements.payTo)) {
|
|
513
649
|
return {
|
|
514
650
|
isValid: false,
|
|
515
651
|
invalidReason: "invalid_permit2_recipient_mismatch",
|
|
@@ -538,7 +674,7 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
538
674
|
payer
|
|
539
675
|
};
|
|
540
676
|
}
|
|
541
|
-
if ((0,
|
|
677
|
+
if ((0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {
|
|
542
678
|
return {
|
|
543
679
|
isValid: false,
|
|
544
680
|
invalidReason: "permit2_token_mismatch",
|
|
@@ -555,16 +691,15 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
555
691
|
},
|
|
556
692
|
message: {
|
|
557
693
|
permitted: {
|
|
558
|
-
token: (0,
|
|
694
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
559
695
|
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
560
696
|
},
|
|
561
|
-
spender: (0,
|
|
697
|
+
spender: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.spender),
|
|
562
698
|
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
563
699
|
deadline: BigInt(permit2Payload.permit2Authorization.deadline),
|
|
564
700
|
witness: {
|
|
565
|
-
to: (0,
|
|
566
|
-
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
567
|
-
extra: permit2Payload.permit2Authorization.witness.extra
|
|
701
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
702
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
568
703
|
}
|
|
569
704
|
}
|
|
570
705
|
};
|
|
@@ -588,44 +723,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
588
723
|
payer
|
|
589
724
|
};
|
|
590
725
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
const validationResult = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);
|
|
602
|
-
if (!validationResult.isValid) {
|
|
603
|
-
return {
|
|
604
|
-
isValid: false,
|
|
605
|
-
invalidReason: validationResult.invalidReason,
|
|
606
|
-
payer
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
} else {
|
|
610
|
-
return {
|
|
611
|
-
isValid: false,
|
|
612
|
-
invalidReason: "permit2_allowance_required",
|
|
613
|
-
payer
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
} catch {
|
|
618
|
-
const eip2612Info = (0, import_extensions.extractEip2612GasSponsoringInfo)(payload);
|
|
619
|
-
if (eip2612Info) {
|
|
620
|
-
const validationResult = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);
|
|
621
|
-
if (!validationResult.isValid) {
|
|
622
|
-
return {
|
|
623
|
-
isValid: false,
|
|
624
|
-
invalidReason: validationResult.invalidReason,
|
|
625
|
-
payer
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
}
|
|
726
|
+
const allowanceResult = await _verifyPermit2Allowance(
|
|
727
|
+
signer,
|
|
728
|
+
payload,
|
|
729
|
+
requirements,
|
|
730
|
+
payer,
|
|
731
|
+
tokenAddress,
|
|
732
|
+
context
|
|
733
|
+
);
|
|
734
|
+
if (allowanceResult) {
|
|
735
|
+
return allowanceResult;
|
|
629
736
|
}
|
|
630
737
|
try {
|
|
631
738
|
const balance = await signer.readContract({
|
|
@@ -650,9 +757,53 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
650
757
|
payer
|
|
651
758
|
};
|
|
652
759
|
}
|
|
653
|
-
async function
|
|
760
|
+
async function _verifyPermit2Allowance(signer, payload, requirements, payer, tokenAddress, context) {
|
|
761
|
+
try {
|
|
762
|
+
const allowance = await signer.readContract({
|
|
763
|
+
address: tokenAddress,
|
|
764
|
+
abi: erc20AllowanceAbi,
|
|
765
|
+
functionName: "allowance",
|
|
766
|
+
args: [payer, PERMIT2_ADDRESS]
|
|
767
|
+
});
|
|
768
|
+
if (allowance >= BigInt(requirements.amount)) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
const eip2612Info = (0, import_extensions2.extractEip2612GasSponsoringInfo)(payload);
|
|
772
|
+
if (eip2612Info) {
|
|
773
|
+
const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);
|
|
774
|
+
if (!result.isValid) {
|
|
775
|
+
return { isValid: false, invalidReason: result.invalidReason, payer };
|
|
776
|
+
}
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
780
|
+
import_extensions2.ERC20_APPROVAL_GAS_SPONSORING.key
|
|
781
|
+
);
|
|
782
|
+
if (erc20GasSponsorshipExtension) {
|
|
783
|
+
const erc20Info = (0, import_extensions2.extractErc20ApprovalGasSponsoringInfo)(payload);
|
|
784
|
+
if (erc20Info) {
|
|
785
|
+
const result = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);
|
|
786
|
+
if (!result.isValid) {
|
|
787
|
+
return { isValid: false, invalidReason: result.invalidReason, payer };
|
|
788
|
+
}
|
|
789
|
+
return null;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return { isValid: false, invalidReason: "permit2_allowance_required", payer };
|
|
793
|
+
} catch {
|
|
794
|
+
const eip2612Info = (0, import_extensions2.extractEip2612GasSponsoringInfo)(payload);
|
|
795
|
+
if (eip2612Info) {
|
|
796
|
+
const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);
|
|
797
|
+
if (!result.isValid) {
|
|
798
|
+
return { isValid: false, invalidReason: result.invalidReason, payer };
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
async function settlePermit2(signer, payload, requirements, permit2Payload, context) {
|
|
654
805
|
const payer = permit2Payload.permit2Authorization.from;
|
|
655
|
-
const valid = await verifyPermit2(signer, payload, requirements, permit2Payload);
|
|
806
|
+
const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context);
|
|
656
807
|
if (!valid.isValid) {
|
|
657
808
|
return {
|
|
658
809
|
success: false,
|
|
@@ -662,120 +813,195 @@ async function settlePermit2(signer, payload, requirements, permit2Payload) {
|
|
|
662
813
|
payer
|
|
663
814
|
};
|
|
664
815
|
}
|
|
816
|
+
const eip2612Info = (0, import_extensions2.extractEip2612GasSponsoringInfo)(payload);
|
|
817
|
+
if (eip2612Info) {
|
|
818
|
+
return _settlePermit2WithEIP2612(signer, payload, permit2Payload, eip2612Info);
|
|
819
|
+
}
|
|
820
|
+
const erc20Info = (0, import_extensions2.extractErc20ApprovalGasSponsoringInfo)(payload);
|
|
821
|
+
if (erc20Info) {
|
|
822
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
823
|
+
import_extensions2.ERC20_APPROVAL_GAS_SPONSORING.key
|
|
824
|
+
);
|
|
825
|
+
if (erc20GasSponsorshipExtension?.signer) {
|
|
826
|
+
return _settlePermit2WithERC20Approval(
|
|
827
|
+
erc20GasSponsorshipExtension.signer,
|
|
828
|
+
payload,
|
|
829
|
+
permit2Payload,
|
|
830
|
+
erc20Info
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return _settlePermit2Direct(signer, payload, permit2Payload);
|
|
835
|
+
}
|
|
836
|
+
async function _settlePermit2WithEIP2612(signer, payload, permit2Payload, eip2612Info) {
|
|
837
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
665
838
|
try {
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
permitted: {
|
|
684
|
-
token: (0, import_viem2.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
685
|
-
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
686
|
-
},
|
|
687
|
-
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
688
|
-
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
689
|
-
},
|
|
690
|
-
(0, import_viem2.getAddress)(payer),
|
|
691
|
-
{
|
|
692
|
-
to: (0, import_viem2.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
693
|
-
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),
|
|
694
|
-
extra: permit2Payload.permit2Authorization.witness.extra
|
|
695
|
-
},
|
|
696
|
-
permit2Payload.signature
|
|
697
|
-
]
|
|
698
|
-
});
|
|
699
|
-
} else {
|
|
700
|
-
tx = await signer.writeContract({
|
|
701
|
-
address: x402ExactPermit2ProxyAddress,
|
|
702
|
-
abi: x402ExactPermit2ProxyABI,
|
|
703
|
-
functionName: "settle",
|
|
704
|
-
args: [
|
|
705
|
-
{
|
|
706
|
-
permitted: {
|
|
707
|
-
token: (0, import_viem2.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
708
|
-
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
709
|
-
},
|
|
710
|
-
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
711
|
-
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
839
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
840
|
+
const tx = await signer.writeContract({
|
|
841
|
+
address: x402ExactPermit2ProxyAddress,
|
|
842
|
+
abi: x402ExactPermit2ProxyABI,
|
|
843
|
+
functionName: "settleWithPermit",
|
|
844
|
+
args: [
|
|
845
|
+
{
|
|
846
|
+
value: BigInt(eip2612Info.amount),
|
|
847
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
848
|
+
r,
|
|
849
|
+
s,
|
|
850
|
+
v
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
permitted: {
|
|
854
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
855
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
712
856
|
},
|
|
713
|
-
(
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
permit2Payload.
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
857
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
858
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
859
|
+
},
|
|
860
|
+
(0, import_viem4.getAddress)(payer),
|
|
861
|
+
{
|
|
862
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
863
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
864
|
+
},
|
|
865
|
+
permit2Payload.signature
|
|
866
|
+
]
|
|
867
|
+
});
|
|
868
|
+
return _waitAndReturn(signer, tx, payload, payer);
|
|
869
|
+
} catch (error) {
|
|
870
|
+
return _mapSettleError(error, payload, payer);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
async function _settlePermit2WithERC20Approval(extensionSigner, payload, permit2Payload, erc20Info) {
|
|
874
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
875
|
+
try {
|
|
876
|
+
const approvalTxHash = await extensionSigner.sendRawTransaction({
|
|
877
|
+
serializedTransaction: erc20Info.signedTransaction
|
|
878
|
+
});
|
|
879
|
+
const approvalReceipt = await extensionSigner.waitForTransactionReceipt({
|
|
880
|
+
hash: approvalTxHash
|
|
881
|
+
});
|
|
882
|
+
if (approvalReceipt.status !== "success") {
|
|
725
883
|
return {
|
|
726
884
|
success: false,
|
|
727
|
-
errorReason: "
|
|
728
|
-
transaction:
|
|
885
|
+
errorReason: "erc20_approval_tx_failed",
|
|
886
|
+
transaction: approvalTxHash,
|
|
729
887
|
network: payload.accepted.network,
|
|
730
888
|
payer
|
|
731
889
|
};
|
|
732
890
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
891
|
+
const tx = await extensionSigner.writeContract({
|
|
892
|
+
address: x402ExactPermit2ProxyAddress,
|
|
893
|
+
abi: x402ExactPermit2ProxyABI,
|
|
894
|
+
functionName: "settle",
|
|
895
|
+
args: [
|
|
896
|
+
{
|
|
897
|
+
permitted: {
|
|
898
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
899
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
900
|
+
},
|
|
901
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
902
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
903
|
+
},
|
|
904
|
+
(0, import_viem4.getAddress)(payer),
|
|
905
|
+
{
|
|
906
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
907
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
908
|
+
},
|
|
909
|
+
permit2Payload.signature
|
|
910
|
+
]
|
|
911
|
+
});
|
|
912
|
+
return _waitAndReturn(extensionSigner, tx, payload, payer);
|
|
739
913
|
} catch (error) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
914
|
+
return _mapSettleError(error, payload, payer);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
async function _settlePermit2Direct(signer, payload, permit2Payload) {
|
|
918
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
919
|
+
try {
|
|
920
|
+
const tx = await signer.writeContract({
|
|
921
|
+
address: x402ExactPermit2ProxyAddress,
|
|
922
|
+
abi: x402ExactPermit2ProxyABI,
|
|
923
|
+
functionName: "settle",
|
|
924
|
+
args: [
|
|
925
|
+
{
|
|
926
|
+
permitted: {
|
|
927
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
928
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
929
|
+
},
|
|
930
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
931
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
932
|
+
},
|
|
933
|
+
(0, import_viem4.getAddress)(payer),
|
|
934
|
+
{
|
|
935
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
936
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
937
|
+
},
|
|
938
|
+
permit2Payload.signature
|
|
939
|
+
]
|
|
940
|
+
});
|
|
941
|
+
return _waitAndReturn(signer, tx, payload, payer);
|
|
942
|
+
} catch (error) {
|
|
943
|
+
return _mapSettleError(error, payload, payer);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
async function _waitAndReturn(signer, tx, payload, payer) {
|
|
947
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
948
|
+
if (receipt.status !== "success") {
|
|
759
949
|
return {
|
|
760
950
|
success: false,
|
|
761
|
-
errorReason,
|
|
762
|
-
transaction:
|
|
951
|
+
errorReason: "invalid_transaction_state",
|
|
952
|
+
transaction: tx,
|
|
763
953
|
network: payload.accepted.network,
|
|
764
954
|
payer
|
|
765
955
|
};
|
|
766
956
|
}
|
|
957
|
+
return {
|
|
958
|
+
success: true,
|
|
959
|
+
transaction: tx,
|
|
960
|
+
network: payload.accepted.network,
|
|
961
|
+
payer
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
function _mapSettleError(error, payload, payer) {
|
|
965
|
+
let errorReason = "transaction_failed";
|
|
966
|
+
if (error instanceof Error) {
|
|
967
|
+
const message = error.message;
|
|
968
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
969
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
970
|
+
} else if (message.includes("InvalidAmount")) {
|
|
971
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
972
|
+
} else if (message.includes("InvalidDestination")) {
|
|
973
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
974
|
+
} else if (message.includes("InvalidOwner")) {
|
|
975
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
976
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
977
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
978
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
979
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
980
|
+
} else if (message.includes("InvalidNonce")) {
|
|
981
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
982
|
+
} else {
|
|
983
|
+
errorReason = `transaction_failed: ${message.slice(0, 500)}`;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return {
|
|
987
|
+
success: false,
|
|
988
|
+
errorReason,
|
|
989
|
+
transaction: "",
|
|
990
|
+
network: payload.accepted.network,
|
|
991
|
+
payer
|
|
992
|
+
};
|
|
767
993
|
}
|
|
768
994
|
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
769
|
-
if (!(0,
|
|
995
|
+
if (!(0, import_extensions2.validateEip2612GasSponsoringInfo)(info)) {
|
|
770
996
|
return { isValid: false, invalidReason: "invalid_eip2612_extension_format" };
|
|
771
997
|
}
|
|
772
|
-
if ((0,
|
|
998
|
+
if ((0, import_viem4.getAddress)(info.from) !== (0, import_viem4.getAddress)(payer)) {
|
|
773
999
|
return { isValid: false, invalidReason: "eip2612_from_mismatch" };
|
|
774
1000
|
}
|
|
775
|
-
if ((0,
|
|
1001
|
+
if ((0, import_viem4.getAddress)(info.asset) !== tokenAddress) {
|
|
776
1002
|
return { isValid: false, invalidReason: "eip2612_asset_mismatch" };
|
|
777
1003
|
}
|
|
778
|
-
if ((0,
|
|
1004
|
+
if ((0, import_viem4.getAddress)(info.spender) !== (0, import_viem4.getAddress)(PERMIT2_ADDRESS)) {
|
|
779
1005
|
return { isValid: false, invalidReason: "eip2612_spender_not_permit2" };
|
|
780
1006
|
}
|
|
781
1007
|
const now = Math.floor(Date.now() / 1e3);
|
|
@@ -800,10 +1026,10 @@ function splitEip2612Signature(signature) {
|
|
|
800
1026
|
// src/exact/facilitator/scheme.ts
|
|
801
1027
|
var ExactEvmScheme = class {
|
|
802
1028
|
/**
|
|
803
|
-
* Creates a new
|
|
1029
|
+
* Creates a new ExactEvmScheme facilitator instance.
|
|
804
1030
|
*
|
|
805
1031
|
* @param signer - The EVM signer for facilitator operations
|
|
806
|
-
* @param config - Optional configuration
|
|
1032
|
+
* @param config - Optional configuration
|
|
807
1033
|
*/
|
|
808
1034
|
constructor(signer, config) {
|
|
809
1035
|
this.signer = signer;
|
|
@@ -814,53 +1040,51 @@ var ExactEvmScheme = class {
|
|
|
814
1040
|
};
|
|
815
1041
|
}
|
|
816
1042
|
/**
|
|
817
|
-
*
|
|
818
|
-
* For EVM, no extra data is needed.
|
|
1043
|
+
* Returns undefined — EVM has no mechanism-specific extra data.
|
|
819
1044
|
*
|
|
820
|
-
* @param _ - The network identifier (unused
|
|
821
|
-
* @returns undefined
|
|
1045
|
+
* @param _ - The network identifier (unused)
|
|
1046
|
+
* @returns undefined
|
|
822
1047
|
*/
|
|
823
1048
|
getExtra(_) {
|
|
824
1049
|
return void 0;
|
|
825
1050
|
}
|
|
826
1051
|
/**
|
|
827
|
-
*
|
|
828
|
-
* Returns all addresses this facilitator can use for signing/settling transactions.
|
|
1052
|
+
* Returns facilitator wallet addresses for the supported response.
|
|
829
1053
|
*
|
|
830
|
-
* @param _ - The network identifier (unused
|
|
1054
|
+
* @param _ - The network identifier (unused, addresses are network-agnostic)
|
|
831
1055
|
* @returns Array of facilitator wallet addresses
|
|
832
1056
|
*/
|
|
833
1057
|
getSigners(_) {
|
|
834
1058
|
return [...this.signer.getAddresses()];
|
|
835
1059
|
}
|
|
836
1060
|
/**
|
|
837
|
-
* Verifies a payment payload.
|
|
838
|
-
* Routes to the appropriate verification logic based on payload type.
|
|
1061
|
+
* Verifies a payment payload. Routes to Permit2 or EIP-3009 based on payload type.
|
|
839
1062
|
*
|
|
840
1063
|
* @param payload - The payment payload to verify
|
|
841
1064
|
* @param requirements - The payment requirements
|
|
1065
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
842
1066
|
* @returns Promise resolving to verification response
|
|
843
1067
|
*/
|
|
844
|
-
async verify(payload, requirements) {
|
|
1068
|
+
async verify(payload, requirements, context) {
|
|
845
1069
|
const rawPayload = payload.payload;
|
|
846
1070
|
if (isPermit2Payload(rawPayload)) {
|
|
847
|
-
return verifyPermit2(this.signer, payload, requirements, rawPayload);
|
|
1071
|
+
return verifyPermit2(this.signer, payload, requirements, rawPayload, context);
|
|
848
1072
|
}
|
|
849
1073
|
const eip3009Payload = rawPayload;
|
|
850
1074
|
return verifyEIP3009(this.signer, payload, requirements, eip3009Payload);
|
|
851
1075
|
}
|
|
852
1076
|
/**
|
|
853
|
-
* Settles a payment
|
|
854
|
-
* Routes to the appropriate settlement logic based on payload type.
|
|
1077
|
+
* Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.
|
|
855
1078
|
*
|
|
856
1079
|
* @param payload - The payment payload to settle
|
|
857
1080
|
* @param requirements - The payment requirements
|
|
1081
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
858
1082
|
* @returns Promise resolving to settlement response
|
|
859
1083
|
*/
|
|
860
|
-
async settle(payload, requirements) {
|
|
1084
|
+
async settle(payload, requirements, context) {
|
|
861
1085
|
const rawPayload = payload.payload;
|
|
862
1086
|
if (isPermit2Payload(rawPayload)) {
|
|
863
|
-
return settlePermit2(this.signer, payload, requirements, rawPayload);
|
|
1087
|
+
return settlePermit2(this.signer, payload, requirements, rawPayload, context);
|
|
864
1088
|
}
|
|
865
1089
|
const eip3009Payload = rawPayload;
|
|
866
1090
|
return settleEIP3009(this.signer, payload, requirements, eip3009Payload, this.config);
|
|
@@ -868,13 +1092,10 @@ var ExactEvmScheme = class {
|
|
|
868
1092
|
};
|
|
869
1093
|
|
|
870
1094
|
// src/exact/v1/facilitator/scheme.ts
|
|
871
|
-
var
|
|
872
|
-
|
|
873
|
-
// src/utils.ts
|
|
874
|
-
var import_viem4 = require("viem");
|
|
1095
|
+
var import_viem6 = require("viem");
|
|
875
1096
|
|
|
876
1097
|
// src/exact/v1/client/scheme.ts
|
|
877
|
-
var
|
|
1098
|
+
var import_viem5 = require("viem");
|
|
878
1099
|
|
|
879
1100
|
// src/v1/index.ts
|
|
880
1101
|
var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
@@ -895,15 +1116,14 @@ var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
|
895
1116
|
story: 1514,
|
|
896
1117
|
educhain: 41923,
|
|
897
1118
|
"skale-base-sepolia": 324705682,
|
|
898
|
-
megaeth: 4326
|
|
1119
|
+
megaeth: 4326,
|
|
1120
|
+
monad: 143
|
|
899
1121
|
};
|
|
900
1122
|
var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
|
|
901
|
-
|
|
902
|
-
// src/utils.ts
|
|
903
|
-
function getEvmChainId(network) {
|
|
1123
|
+
function getEvmChainIdV1(network) {
|
|
904
1124
|
const chainId = EVM_NETWORK_CHAIN_ID_MAP[network];
|
|
905
1125
|
if (!chainId) {
|
|
906
|
-
throw new Error(`Unsupported network: ${network}`);
|
|
1126
|
+
throw new Error(`Unsupported v1 network: ${network}`);
|
|
907
1127
|
}
|
|
908
1128
|
return chainId;
|
|
909
1129
|
}
|
|
@@ -964,7 +1184,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
964
1184
|
}
|
|
965
1185
|
let chainId;
|
|
966
1186
|
try {
|
|
967
|
-
chainId =
|
|
1187
|
+
chainId = getEvmChainIdV1(payloadV1.network);
|
|
968
1188
|
} catch {
|
|
969
1189
|
return {
|
|
970
1190
|
isValid: false,
|
|
@@ -980,7 +1200,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
980
1200
|
};
|
|
981
1201
|
}
|
|
982
1202
|
const { name, version } = requirements.extra;
|
|
983
|
-
const erc20Address = (0,
|
|
1203
|
+
const erc20Address = (0, import_viem6.getAddress)(requirements.asset);
|
|
984
1204
|
if (payloadV1.network !== requirements.network) {
|
|
985
1205
|
return {
|
|
986
1206
|
isValid: false,
|
|
@@ -1027,8 +1247,8 @@ var ExactEvmSchemeV12 = class {
|
|
|
1027
1247
|
const payerAddress = exactEvmPayload.authorization.from;
|
|
1028
1248
|
const bytecode = await this.signer.getCode({ address: payerAddress });
|
|
1029
1249
|
if (!bytecode || bytecode === "0x") {
|
|
1030
|
-
const erc6492Data = (0,
|
|
1031
|
-
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0,
|
|
1250
|
+
const erc6492Data = (0, import_viem6.parseErc6492Signature)(signature);
|
|
1251
|
+
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem6.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
|
|
1032
1252
|
if (!hasDeploymentInfo) {
|
|
1033
1253
|
return {
|
|
1034
1254
|
isValid: false,
|
|
@@ -1051,7 +1271,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
1051
1271
|
};
|
|
1052
1272
|
}
|
|
1053
1273
|
}
|
|
1054
|
-
if ((0,
|
|
1274
|
+
if ((0, import_viem6.getAddress)(exactEvmPayload.authorization.to) !== (0, import_viem6.getAddress)(requirements.payTo)) {
|
|
1055
1275
|
return {
|
|
1056
1276
|
isValid: false,
|
|
1057
1277
|
invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
|
|
@@ -1124,9 +1344,9 @@ var ExactEvmSchemeV12 = class {
|
|
|
1124
1344
|
};
|
|
1125
1345
|
}
|
|
1126
1346
|
try {
|
|
1127
|
-
const parseResult = (0,
|
|
1347
|
+
const parseResult = (0, import_viem6.parseErc6492Signature)(exactEvmPayload.signature);
|
|
1128
1348
|
const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;
|
|
1129
|
-
if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0,
|
|
1349
|
+
if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0, import_viem6.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
|
|
1130
1350
|
const payerAddress = exactEvmPayload.authorization.from;
|
|
1131
1351
|
const bytecode = await this.signer.getCode({ address: payerAddress });
|
|
1132
1352
|
if (!bytecode || bytecode === "0x") {
|
|
@@ -1150,14 +1370,14 @@ var ExactEvmSchemeV12 = class {
|
|
|
1150
1370
|
const isECDSA = signatureLength === 130;
|
|
1151
1371
|
let tx;
|
|
1152
1372
|
if (isECDSA) {
|
|
1153
|
-
const parsedSig = (0,
|
|
1373
|
+
const parsedSig = (0, import_viem6.parseSignature)(signature);
|
|
1154
1374
|
tx = await this.signer.writeContract({
|
|
1155
|
-
address: (0,
|
|
1375
|
+
address: (0, import_viem6.getAddress)(requirements.asset),
|
|
1156
1376
|
abi: eip3009ABI,
|
|
1157
1377
|
functionName: "transferWithAuthorization",
|
|
1158
1378
|
args: [
|
|
1159
|
-
(0,
|
|
1160
|
-
(0,
|
|
1379
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.from),
|
|
1380
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.to),
|
|
1161
1381
|
BigInt(exactEvmPayload.authorization.value),
|
|
1162
1382
|
BigInt(exactEvmPayload.authorization.validAfter),
|
|
1163
1383
|
BigInt(exactEvmPayload.authorization.validBefore),
|
|
@@ -1169,12 +1389,12 @@ var ExactEvmSchemeV12 = class {
|
|
|
1169
1389
|
});
|
|
1170
1390
|
} else {
|
|
1171
1391
|
tx = await this.signer.writeContract({
|
|
1172
|
-
address: (0,
|
|
1392
|
+
address: (0, import_viem6.getAddress)(requirements.asset),
|
|
1173
1393
|
abi: eip3009ABI,
|
|
1174
1394
|
functionName: "transferWithAuthorization",
|
|
1175
1395
|
args: [
|
|
1176
|
-
(0,
|
|
1177
|
-
(0,
|
|
1396
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.from),
|
|
1397
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.to),
|
|
1178
1398
|
BigInt(exactEvmPayload.authorization.value),
|
|
1179
1399
|
BigInt(exactEvmPayload.authorization.validAfter),
|
|
1180
1400
|
BigInt(exactEvmPayload.authorization.validBefore),
|