@x402/evm 2.3.1 → 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 +412 -169
- 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 +467 -157
- 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 +363 -110
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/permit2-CQbXqCMC.d.ts +517 -0
- package/dist/cjs/signer-DC81R8wQ.d.ts +161 -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-RPL6OFJL.mjs → chunk-7KHQD5KT.mjs} +92 -37
- package/dist/esm/chunk-7KHQD5KT.mjs.map +1 -0
- package/dist/esm/chunk-GY6X5A3G.mjs +425 -0
- 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 +401 -99
- 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 +29 -6
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/permit2-CGOcN7Et.d.mts +517 -0
- package/dist/esm/signer-DC81R8wQ.d.mts +161 -0
- package/dist/esm/v1/index.d.mts +11 -2
- package/dist/esm/v1/index.mjs +6 -4
- package/package.json +3 -2
- package/dist/cjs/permit2-BYv82va2.d.ts +0 -103
- package/dist/cjs/signer-5OVDxViv.d.ts +0 -79
- package/dist/esm/chunk-E2YMUI3X.mjs +0 -229
- package/dist/esm/chunk-E2YMUI3X.mjs.map +0 -1
- package/dist/esm/chunk-PFULIQAE.mjs.map +0 -1
- package/dist/esm/chunk-RPL6OFJL.mjs.map +0 -1
- package/dist/esm/permit2-BsAoJiWD.d.mts +0 -103
- package/dist/esm/signer-5OVDxViv.d.mts +0 -79
|
@@ -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,20 +497,130 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
470
497
|
}
|
|
471
498
|
|
|
472
499
|
// src/exact/facilitator/permit2.ts
|
|
473
|
-
var
|
|
474
|
-
var
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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");
|
|
525
|
+
var import_extensions = require("@x402/extensions");
|
|
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
|
+
};
|
|
484
534
|
}
|
|
485
|
-
|
|
486
|
-
|
|
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) {
|
|
487
624
|
const payer = permit2Payload.permit2Authorization.from;
|
|
488
625
|
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
489
626
|
return {
|
|
@@ -499,16 +636,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
499
636
|
payer
|
|
500
637
|
};
|
|
501
638
|
}
|
|
502
|
-
const chainId =
|
|
503
|
-
const tokenAddress = (0,
|
|
504
|
-
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)) {
|
|
505
642
|
return {
|
|
506
643
|
isValid: false,
|
|
507
644
|
invalidReason: "invalid_permit2_spender",
|
|
508
645
|
payer
|
|
509
646
|
};
|
|
510
647
|
}
|
|
511
|
-
if ((0,
|
|
648
|
+
if ((0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to) !== (0, import_viem4.getAddress)(requirements.payTo)) {
|
|
512
649
|
return {
|
|
513
650
|
isValid: false,
|
|
514
651
|
invalidReason: "invalid_permit2_recipient_mismatch",
|
|
@@ -537,7 +674,7 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
537
674
|
payer
|
|
538
675
|
};
|
|
539
676
|
}
|
|
540
|
-
if ((0,
|
|
677
|
+
if ((0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {
|
|
541
678
|
return {
|
|
542
679
|
isValid: false,
|
|
543
680
|
invalidReason: "permit2_token_mismatch",
|
|
@@ -554,16 +691,15 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
554
691
|
},
|
|
555
692
|
message: {
|
|
556
693
|
permitted: {
|
|
557
|
-
token: (0,
|
|
694
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
558
695
|
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
559
696
|
},
|
|
560
|
-
spender: (0,
|
|
697
|
+
spender: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.spender),
|
|
561
698
|
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
562
699
|
deadline: BigInt(permit2Payload.permit2Authorization.deadline),
|
|
563
700
|
witness: {
|
|
564
|
-
to: (0,
|
|
565
|
-
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
566
|
-
extra: permit2Payload.permit2Authorization.witness.extra
|
|
701
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
702
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
567
703
|
}
|
|
568
704
|
}
|
|
569
705
|
};
|
|
@@ -587,21 +723,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
587
723
|
payer
|
|
588
724
|
};
|
|
589
725
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
invalidReason: "permit2_allowance_required",
|
|
601
|
-
payer
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
} catch {
|
|
726
|
+
const allowanceResult = await _verifyPermit2Allowance(
|
|
727
|
+
signer,
|
|
728
|
+
payload,
|
|
729
|
+
requirements,
|
|
730
|
+
payer,
|
|
731
|
+
tokenAddress,
|
|
732
|
+
context
|
|
733
|
+
);
|
|
734
|
+
if (allowanceResult) {
|
|
735
|
+
return allowanceResult;
|
|
605
736
|
}
|
|
606
737
|
try {
|
|
607
738
|
const balance = await signer.readContract({
|
|
@@ -626,9 +757,53 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload) {
|
|
|
626
757
|
payer
|
|
627
758
|
};
|
|
628
759
|
}
|
|
629
|
-
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) {
|
|
630
805
|
const payer = permit2Payload.permit2Authorization.from;
|
|
631
|
-
const valid = await verifyPermit2(signer, payload, requirements, permit2Payload);
|
|
806
|
+
const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context);
|
|
632
807
|
if (!valid.isValid) {
|
|
633
808
|
return {
|
|
634
809
|
success: false,
|
|
@@ -638,82 +813,223 @@ async function settlePermit2(signer, payload, requirements, permit2Payload) {
|
|
|
638
813
|
payer
|
|
639
814
|
};
|
|
640
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;
|
|
641
838
|
try {
|
|
839
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
642
840
|
const tx = await signer.writeContract({
|
|
643
841
|
address: x402ExactPermit2ProxyAddress,
|
|
644
842
|
abi: x402ExactPermit2ProxyABI,
|
|
645
|
-
functionName: "
|
|
843
|
+
functionName: "settleWithPermit",
|
|
646
844
|
args: [
|
|
845
|
+
{
|
|
846
|
+
value: BigInt(eip2612Info.amount),
|
|
847
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
848
|
+
r,
|
|
849
|
+
s,
|
|
850
|
+
v
|
|
851
|
+
},
|
|
647
852
|
{
|
|
648
853
|
permitted: {
|
|
649
|
-
token: (0,
|
|
854
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
650
855
|
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
651
856
|
},
|
|
652
857
|
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
653
858
|
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
654
859
|
},
|
|
655
|
-
(0,
|
|
860
|
+
(0, import_viem4.getAddress)(payer),
|
|
656
861
|
{
|
|
657
|
-
to: (0,
|
|
658
|
-
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
659
|
-
extra: permit2Payload.permit2Authorization.witness.extra
|
|
862
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
863
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
660
864
|
},
|
|
661
865
|
permit2Payload.signature
|
|
662
866
|
]
|
|
663
867
|
});
|
|
664
|
-
|
|
665
|
-
|
|
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") {
|
|
666
883
|
return {
|
|
667
884
|
success: false,
|
|
668
|
-
errorReason: "
|
|
669
|
-
transaction:
|
|
885
|
+
errorReason: "erc20_approval_tx_failed",
|
|
886
|
+
transaction: approvalTxHash,
|
|
670
887
|
network: payload.accepted.network,
|
|
671
888
|
payer
|
|
672
889
|
};
|
|
673
890
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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);
|
|
680
913
|
} catch (error) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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") {
|
|
700
949
|
return {
|
|
701
950
|
success: false,
|
|
702
|
-
errorReason,
|
|
703
|
-
transaction:
|
|
951
|
+
errorReason: "invalid_transaction_state",
|
|
952
|
+
transaction: tx,
|
|
704
953
|
network: payload.accepted.network,
|
|
705
954
|
payer
|
|
706
955
|
};
|
|
707
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
|
+
};
|
|
993
|
+
}
|
|
994
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
995
|
+
if (!(0, import_extensions2.validateEip2612GasSponsoringInfo)(info)) {
|
|
996
|
+
return { isValid: false, invalidReason: "invalid_eip2612_extension_format" };
|
|
997
|
+
}
|
|
998
|
+
if ((0, import_viem4.getAddress)(info.from) !== (0, import_viem4.getAddress)(payer)) {
|
|
999
|
+
return { isValid: false, invalidReason: "eip2612_from_mismatch" };
|
|
1000
|
+
}
|
|
1001
|
+
if ((0, import_viem4.getAddress)(info.asset) !== tokenAddress) {
|
|
1002
|
+
return { isValid: false, invalidReason: "eip2612_asset_mismatch" };
|
|
1003
|
+
}
|
|
1004
|
+
if ((0, import_viem4.getAddress)(info.spender) !== (0, import_viem4.getAddress)(PERMIT2_ADDRESS)) {
|
|
1005
|
+
return { isValid: false, invalidReason: "eip2612_spender_not_permit2" };
|
|
1006
|
+
}
|
|
1007
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1008
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
1009
|
+
return { isValid: false, invalidReason: "eip2612_deadline_expired" };
|
|
1010
|
+
}
|
|
1011
|
+
return { isValid: true };
|
|
1012
|
+
}
|
|
1013
|
+
function splitEip2612Signature(signature) {
|
|
1014
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
1015
|
+
if (sig.length !== 130) {
|
|
1016
|
+
throw new Error(
|
|
1017
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
1021
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
1022
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
1023
|
+
return { v, r, s };
|
|
708
1024
|
}
|
|
709
1025
|
|
|
710
1026
|
// src/exact/facilitator/scheme.ts
|
|
711
1027
|
var ExactEvmScheme = class {
|
|
712
1028
|
/**
|
|
713
|
-
* Creates a new
|
|
1029
|
+
* Creates a new ExactEvmScheme facilitator instance.
|
|
714
1030
|
*
|
|
715
1031
|
* @param signer - The EVM signer for facilitator operations
|
|
716
|
-
* @param config - Optional configuration
|
|
1032
|
+
* @param config - Optional configuration
|
|
717
1033
|
*/
|
|
718
1034
|
constructor(signer, config) {
|
|
719
1035
|
this.signer = signer;
|
|
@@ -724,53 +1040,51 @@ var ExactEvmScheme = class {
|
|
|
724
1040
|
};
|
|
725
1041
|
}
|
|
726
1042
|
/**
|
|
727
|
-
*
|
|
728
|
-
* For EVM, no extra data is needed.
|
|
1043
|
+
* Returns undefined — EVM has no mechanism-specific extra data.
|
|
729
1044
|
*
|
|
730
|
-
* @param _ - The network identifier (unused
|
|
731
|
-
* @returns undefined
|
|
1045
|
+
* @param _ - The network identifier (unused)
|
|
1046
|
+
* @returns undefined
|
|
732
1047
|
*/
|
|
733
1048
|
getExtra(_) {
|
|
734
1049
|
return void 0;
|
|
735
1050
|
}
|
|
736
1051
|
/**
|
|
737
|
-
*
|
|
738
|
-
* Returns all addresses this facilitator can use for signing/settling transactions.
|
|
1052
|
+
* Returns facilitator wallet addresses for the supported response.
|
|
739
1053
|
*
|
|
740
|
-
* @param _ - The network identifier (unused
|
|
1054
|
+
* @param _ - The network identifier (unused, addresses are network-agnostic)
|
|
741
1055
|
* @returns Array of facilitator wallet addresses
|
|
742
1056
|
*/
|
|
743
1057
|
getSigners(_) {
|
|
744
1058
|
return [...this.signer.getAddresses()];
|
|
745
1059
|
}
|
|
746
1060
|
/**
|
|
747
|
-
* Verifies a payment payload.
|
|
748
|
-
* 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.
|
|
749
1062
|
*
|
|
750
1063
|
* @param payload - The payment payload to verify
|
|
751
1064
|
* @param requirements - The payment requirements
|
|
1065
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
752
1066
|
* @returns Promise resolving to verification response
|
|
753
1067
|
*/
|
|
754
|
-
async verify(payload, requirements) {
|
|
1068
|
+
async verify(payload, requirements, context) {
|
|
755
1069
|
const rawPayload = payload.payload;
|
|
756
1070
|
if (isPermit2Payload(rawPayload)) {
|
|
757
|
-
return verifyPermit2(this.signer, payload, requirements, rawPayload);
|
|
1071
|
+
return verifyPermit2(this.signer, payload, requirements, rawPayload, context);
|
|
758
1072
|
}
|
|
759
1073
|
const eip3009Payload = rawPayload;
|
|
760
1074
|
return verifyEIP3009(this.signer, payload, requirements, eip3009Payload);
|
|
761
1075
|
}
|
|
762
1076
|
/**
|
|
763
|
-
* Settles a payment
|
|
764
|
-
* Routes to the appropriate settlement logic based on payload type.
|
|
1077
|
+
* Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.
|
|
765
1078
|
*
|
|
766
1079
|
* @param payload - The payment payload to settle
|
|
767
1080
|
* @param requirements - The payment requirements
|
|
1081
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
768
1082
|
* @returns Promise resolving to settlement response
|
|
769
1083
|
*/
|
|
770
|
-
async settle(payload, requirements) {
|
|
1084
|
+
async settle(payload, requirements, context) {
|
|
771
1085
|
const rawPayload = payload.payload;
|
|
772
1086
|
if (isPermit2Payload(rawPayload)) {
|
|
773
|
-
return settlePermit2(this.signer, payload, requirements, rawPayload);
|
|
1087
|
+
return settlePermit2(this.signer, payload, requirements, rawPayload, context);
|
|
774
1088
|
}
|
|
775
1089
|
const eip3009Payload = rawPayload;
|
|
776
1090
|
return settleEIP3009(this.signer, payload, requirements, eip3009Payload, this.config);
|
|
@@ -778,13 +1092,10 @@ var ExactEvmScheme = class {
|
|
|
778
1092
|
};
|
|
779
1093
|
|
|
780
1094
|
// src/exact/v1/facilitator/scheme.ts
|
|
781
|
-
var
|
|
782
|
-
|
|
783
|
-
// src/utils.ts
|
|
784
|
-
var import_viem4 = require("viem");
|
|
1095
|
+
var import_viem6 = require("viem");
|
|
785
1096
|
|
|
786
1097
|
// src/exact/v1/client/scheme.ts
|
|
787
|
-
var
|
|
1098
|
+
var import_viem5 = require("viem");
|
|
788
1099
|
|
|
789
1100
|
// src/v1/index.ts
|
|
790
1101
|
var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
@@ -805,15 +1116,14 @@ var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
|
805
1116
|
story: 1514,
|
|
806
1117
|
educhain: 41923,
|
|
807
1118
|
"skale-base-sepolia": 324705682,
|
|
808
|
-
megaeth: 4326
|
|
1119
|
+
megaeth: 4326,
|
|
1120
|
+
monad: 143
|
|
809
1121
|
};
|
|
810
1122
|
var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
|
|
811
|
-
|
|
812
|
-
// src/utils.ts
|
|
813
|
-
function getEvmChainId(network) {
|
|
1123
|
+
function getEvmChainIdV1(network) {
|
|
814
1124
|
const chainId = EVM_NETWORK_CHAIN_ID_MAP[network];
|
|
815
1125
|
if (!chainId) {
|
|
816
|
-
throw new Error(`Unsupported network: ${network}`);
|
|
1126
|
+
throw new Error(`Unsupported v1 network: ${network}`);
|
|
817
1127
|
}
|
|
818
1128
|
return chainId;
|
|
819
1129
|
}
|
|
@@ -874,7 +1184,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
874
1184
|
}
|
|
875
1185
|
let chainId;
|
|
876
1186
|
try {
|
|
877
|
-
chainId =
|
|
1187
|
+
chainId = getEvmChainIdV1(payloadV1.network);
|
|
878
1188
|
} catch {
|
|
879
1189
|
return {
|
|
880
1190
|
isValid: false,
|
|
@@ -890,7 +1200,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
890
1200
|
};
|
|
891
1201
|
}
|
|
892
1202
|
const { name, version } = requirements.extra;
|
|
893
|
-
const erc20Address = (0,
|
|
1203
|
+
const erc20Address = (0, import_viem6.getAddress)(requirements.asset);
|
|
894
1204
|
if (payloadV1.network !== requirements.network) {
|
|
895
1205
|
return {
|
|
896
1206
|
isValid: false,
|
|
@@ -937,8 +1247,8 @@ var ExactEvmSchemeV12 = class {
|
|
|
937
1247
|
const payerAddress = exactEvmPayload.authorization.from;
|
|
938
1248
|
const bytecode = await this.signer.getCode({ address: payerAddress });
|
|
939
1249
|
if (!bytecode || bytecode === "0x") {
|
|
940
|
-
const erc6492Data = (0,
|
|
941
|
-
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");
|
|
942
1252
|
if (!hasDeploymentInfo) {
|
|
943
1253
|
return {
|
|
944
1254
|
isValid: false,
|
|
@@ -961,7 +1271,7 @@ var ExactEvmSchemeV12 = class {
|
|
|
961
1271
|
};
|
|
962
1272
|
}
|
|
963
1273
|
}
|
|
964
|
-
if ((0,
|
|
1274
|
+
if ((0, import_viem6.getAddress)(exactEvmPayload.authorization.to) !== (0, import_viem6.getAddress)(requirements.payTo)) {
|
|
965
1275
|
return {
|
|
966
1276
|
isValid: false,
|
|
967
1277
|
invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
|
|
@@ -1034,9 +1344,9 @@ var ExactEvmSchemeV12 = class {
|
|
|
1034
1344
|
};
|
|
1035
1345
|
}
|
|
1036
1346
|
try {
|
|
1037
|
-
const parseResult = (0,
|
|
1347
|
+
const parseResult = (0, import_viem6.parseErc6492Signature)(exactEvmPayload.signature);
|
|
1038
1348
|
const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;
|
|
1039
|
-
if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0,
|
|
1349
|
+
if (this.config.deployERC4337WithEIP6492 && factoryAddress && factoryCalldata && !(0, import_viem6.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
|
|
1040
1350
|
const payerAddress = exactEvmPayload.authorization.from;
|
|
1041
1351
|
const bytecode = await this.signer.getCode({ address: payerAddress });
|
|
1042
1352
|
if (!bytecode || bytecode === "0x") {
|
|
@@ -1060,14 +1370,14 @@ var ExactEvmSchemeV12 = class {
|
|
|
1060
1370
|
const isECDSA = signatureLength === 130;
|
|
1061
1371
|
let tx;
|
|
1062
1372
|
if (isECDSA) {
|
|
1063
|
-
const parsedSig = (0,
|
|
1373
|
+
const parsedSig = (0, import_viem6.parseSignature)(signature);
|
|
1064
1374
|
tx = await this.signer.writeContract({
|
|
1065
|
-
address: (0,
|
|
1375
|
+
address: (0, import_viem6.getAddress)(requirements.asset),
|
|
1066
1376
|
abi: eip3009ABI,
|
|
1067
1377
|
functionName: "transferWithAuthorization",
|
|
1068
1378
|
args: [
|
|
1069
|
-
(0,
|
|
1070
|
-
(0,
|
|
1379
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.from),
|
|
1380
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.to),
|
|
1071
1381
|
BigInt(exactEvmPayload.authorization.value),
|
|
1072
1382
|
BigInt(exactEvmPayload.authorization.validAfter),
|
|
1073
1383
|
BigInt(exactEvmPayload.authorization.validBefore),
|
|
@@ -1079,12 +1389,12 @@ var ExactEvmSchemeV12 = class {
|
|
|
1079
1389
|
});
|
|
1080
1390
|
} else {
|
|
1081
1391
|
tx = await this.signer.writeContract({
|
|
1082
|
-
address: (0,
|
|
1392
|
+
address: (0, import_viem6.getAddress)(requirements.asset),
|
|
1083
1393
|
abi: eip3009ABI,
|
|
1084
1394
|
functionName: "transferWithAuthorization",
|
|
1085
1395
|
args: [
|
|
1086
|
-
(0,
|
|
1087
|
-
(0,
|
|
1396
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.from),
|
|
1397
|
+
(0, import_viem6.getAddress)(exactEvmPayload.authorization.to),
|
|
1088
1398
|
BigInt(exactEvmPayload.authorization.value),
|
|
1089
1399
|
BigInt(exactEvmPayload.authorization.validAfter),
|
|
1090
1400
|
BigInt(exactEvmPayload.authorization.validBefore),
|