@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
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
DEFAULT_MAX_FEE_PER_GAS,
|
|
3
|
+
DEFAULT_MAX_PRIORITY_FEE_PER_GAS,
|
|
4
|
+
ERC20_APPROVE_GAS_LIMIT,
|
|
5
|
+
ExactEvmSchemeV12 as ExactEvmSchemeV1,
|
|
3
6
|
NETWORKS,
|
|
4
7
|
PERMIT2_ADDRESS,
|
|
5
8
|
authorizationTypes,
|
|
@@ -7,13 +10,16 @@ import {
|
|
|
7
10
|
createPermit2Nonce,
|
|
8
11
|
eip2612NoncesAbi,
|
|
9
12
|
eip2612PermitTypes,
|
|
13
|
+
erc20AllowanceAbi,
|
|
14
|
+
erc20ApproveAbi,
|
|
15
|
+
getEvmChainId,
|
|
10
16
|
permit2WitnessTypes,
|
|
11
17
|
x402ExactPermit2ProxyAddress
|
|
12
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7KHQD5KT.mjs";
|
|
13
19
|
|
|
14
20
|
// src/exact/client/scheme.ts
|
|
15
|
-
import { EIP2612_GAS_SPONSORING } from "@x402/extensions";
|
|
16
|
-
import { getAddress as
|
|
21
|
+
import { EIP2612_GAS_SPONSORING, ERC20_APPROVAL_GAS_SPONSORING } from "@x402/extensions";
|
|
22
|
+
import { getAddress as getAddress5 } from "viem";
|
|
17
23
|
|
|
18
24
|
// src/exact/client/eip3009.ts
|
|
19
25
|
import { getAddress } from "viem";
|
|
@@ -39,7 +45,7 @@ async function createEIP3009Payload(signer, x402Version, paymentRequirements) {
|
|
|
39
45
|
};
|
|
40
46
|
}
|
|
41
47
|
async function signEIP3009Authorization(signer, authorization, requirements) {
|
|
42
|
-
const chainId =
|
|
48
|
+
const chainId = getEvmChainId(requirements.network);
|
|
43
49
|
if (!requirements.extra?.name || !requirements.extra?.version) {
|
|
44
50
|
throw new Error(
|
|
45
51
|
`EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
|
|
@@ -87,8 +93,7 @@ async function createPermit2Payload(signer, x402Version, paymentRequirements) {
|
|
|
87
93
|
deadline,
|
|
88
94
|
witness: {
|
|
89
95
|
to: getAddress2(paymentRequirements.payTo),
|
|
90
|
-
validAfter
|
|
91
|
-
extra: "0x"
|
|
96
|
+
validAfter
|
|
92
97
|
}
|
|
93
98
|
};
|
|
94
99
|
const signature = await signPermit2Authorization(
|
|
@@ -106,7 +111,7 @@ async function createPermit2Payload(signer, x402Version, paymentRequirements) {
|
|
|
106
111
|
};
|
|
107
112
|
}
|
|
108
113
|
async function signPermit2Authorization(signer, permit2Authorization, requirements) {
|
|
109
|
-
const chainId =
|
|
114
|
+
const chainId = getEvmChainId(requirements.network);
|
|
110
115
|
const domain = {
|
|
111
116
|
name: "Permit2",
|
|
112
117
|
chainId,
|
|
@@ -122,8 +127,7 @@ async function signPermit2Authorization(signer, permit2Authorization, requiremen
|
|
|
122
127
|
deadline: BigInt(permit2Authorization.deadline),
|
|
123
128
|
witness: {
|
|
124
129
|
to: getAddress2(permit2Authorization.witness.to),
|
|
125
|
-
validAfter: BigInt(permit2Authorization.witness.validAfter)
|
|
126
|
-
extra: permit2Authorization.witness.extra
|
|
130
|
+
validAfter: BigInt(permit2Authorization.witness.validAfter)
|
|
127
131
|
}
|
|
128
132
|
};
|
|
129
133
|
return await signer.signTypedData({
|
|
@@ -133,30 +137,6 @@ async function signPermit2Authorization(signer, permit2Authorization, requiremen
|
|
|
133
137
|
message
|
|
134
138
|
});
|
|
135
139
|
}
|
|
136
|
-
var erc20ApproveAbi = [
|
|
137
|
-
{
|
|
138
|
-
type: "function",
|
|
139
|
-
name: "approve",
|
|
140
|
-
inputs: [
|
|
141
|
-
{ name: "spender", type: "address" },
|
|
142
|
-
{ name: "amount", type: "uint256" }
|
|
143
|
-
],
|
|
144
|
-
outputs: [{ type: "bool" }],
|
|
145
|
-
stateMutability: "nonpayable"
|
|
146
|
-
}
|
|
147
|
-
];
|
|
148
|
-
var erc20AllowanceAbi = [
|
|
149
|
-
{
|
|
150
|
-
type: "function",
|
|
151
|
-
name: "allowance",
|
|
152
|
-
inputs: [
|
|
153
|
-
{ name: "owner", type: "address" },
|
|
154
|
-
{ name: "spender", type: "address" }
|
|
155
|
-
],
|
|
156
|
-
outputs: [{ type: "uint256" }],
|
|
157
|
-
stateMutability: "view"
|
|
158
|
-
}
|
|
159
|
-
];
|
|
160
140
|
function createPermit2ApprovalTx(tokenAddress) {
|
|
161
141
|
const data = encodeFunctionData({
|
|
162
142
|
abi: erc20ApproveAbi,
|
|
@@ -179,8 +159,7 @@ function getPermit2AllowanceReadParams(params) {
|
|
|
179
159
|
|
|
180
160
|
// src/exact/client/eip2612.ts
|
|
181
161
|
import { getAddress as getAddress3 } from "viem";
|
|
182
|
-
|
|
183
|
-
async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline) {
|
|
162
|
+
async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline, permittedAmount) {
|
|
184
163
|
const owner = signer.address;
|
|
185
164
|
const spender = getAddress3(PERMIT2_ADDRESS);
|
|
186
165
|
const nonce = await signer.readContract({
|
|
@@ -195,10 +174,11 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
195
174
|
chainId,
|
|
196
175
|
verifyingContract: tokenAddress
|
|
197
176
|
};
|
|
177
|
+
const approvalAmount = BigInt(permittedAmount);
|
|
198
178
|
const message = {
|
|
199
179
|
owner,
|
|
200
180
|
spender,
|
|
201
|
-
value:
|
|
181
|
+
value: approvalAmount,
|
|
202
182
|
nonce,
|
|
203
183
|
deadline: BigInt(deadline)
|
|
204
184
|
};
|
|
@@ -212,7 +192,7 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
212
192
|
from: owner,
|
|
213
193
|
asset: tokenAddress,
|
|
214
194
|
spender,
|
|
215
|
-
amount:
|
|
195
|
+
amount: approvalAmount.toString(),
|
|
216
196
|
nonce: nonce.toString(),
|
|
217
197
|
deadline,
|
|
218
198
|
signature,
|
|
@@ -220,19 +200,50 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
220
200
|
};
|
|
221
201
|
}
|
|
222
202
|
|
|
223
|
-
// src/exact/client/
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
203
|
+
// src/exact/client/erc20approval.ts
|
|
204
|
+
import { encodeFunctionData as encodeFunctionData2, getAddress as getAddress4, maxUint256 } from "viem";
|
|
205
|
+
import {
|
|
206
|
+
ERC20_APPROVAL_GAS_SPONSORING_VERSION
|
|
207
|
+
} from "@x402/extensions";
|
|
208
|
+
async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
|
|
209
|
+
const from = signer.address;
|
|
210
|
+
const spender = getAddress4(PERMIT2_ADDRESS);
|
|
211
|
+
const data = encodeFunctionData2({
|
|
212
|
+
abi: erc20ApproveAbi,
|
|
213
|
+
functionName: "approve",
|
|
214
|
+
args: [spender, maxUint256]
|
|
215
|
+
});
|
|
216
|
+
const nonce = await signer.getTransactionCount({ address: from });
|
|
217
|
+
let maxFeePerGas;
|
|
218
|
+
let maxPriorityFeePerGas;
|
|
219
|
+
try {
|
|
220
|
+
const fees = await signer.estimateFeesPerGas();
|
|
221
|
+
maxFeePerGas = fees.maxFeePerGas;
|
|
222
|
+
maxPriorityFeePerGas = fees.maxPriorityFeePerGas;
|
|
223
|
+
} catch {
|
|
224
|
+
maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;
|
|
225
|
+
maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;
|
|
234
226
|
}
|
|
235
|
-
|
|
227
|
+
const signedTransaction = await signer.signTransaction({
|
|
228
|
+
to: tokenAddress,
|
|
229
|
+
data,
|
|
230
|
+
nonce,
|
|
231
|
+
gas: ERC20_APPROVE_GAS_LIMIT,
|
|
232
|
+
maxFeePerGas,
|
|
233
|
+
maxPriorityFeePerGas,
|
|
234
|
+
chainId
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
from,
|
|
238
|
+
asset: tokenAddress,
|
|
239
|
+
spender,
|
|
240
|
+
amount: maxUint256.toString(),
|
|
241
|
+
signedTransaction,
|
|
242
|
+
version: ERC20_APPROVAL_GAS_SPONSORING_VERSION
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/exact/client/scheme.ts
|
|
236
247
|
var ExactEvmScheme = class {
|
|
237
248
|
/**
|
|
238
249
|
* Creates a new ExactEvmClient instance.
|
|
@@ -273,6 +284,13 @@ var ExactEvmScheme = class {
|
|
|
273
284
|
extensions: eip2612Extensions
|
|
274
285
|
};
|
|
275
286
|
}
|
|
287
|
+
const erc20Extensions = await this.trySignErc20Approval(paymentRequirements, result, context);
|
|
288
|
+
if (erc20Extensions) {
|
|
289
|
+
return {
|
|
290
|
+
...result,
|
|
291
|
+
extensions: erc20Extensions
|
|
292
|
+
};
|
|
293
|
+
}
|
|
276
294
|
return result;
|
|
277
295
|
}
|
|
278
296
|
return createEIP3009Payload(this.signer, x402Version, paymentRequirements);
|
|
@@ -301,12 +319,12 @@ var ExactEvmScheme = class {
|
|
|
301
319
|
if (!tokenName || !tokenVersion) {
|
|
302
320
|
return void 0;
|
|
303
321
|
}
|
|
304
|
-
const chainId =
|
|
305
|
-
const tokenAddress =
|
|
322
|
+
const chainId = getEvmChainId(requirements.network);
|
|
323
|
+
const tokenAddress = getAddress5(requirements.asset);
|
|
306
324
|
try {
|
|
307
325
|
const allowance = await this.signer.readContract({
|
|
308
326
|
address: tokenAddress,
|
|
309
|
-
abi:
|
|
327
|
+
abi: erc20AllowanceAbi,
|
|
310
328
|
functionName: "allowance",
|
|
311
329
|
args: [this.signer.address, PERMIT2_ADDRESS]
|
|
312
330
|
});
|
|
@@ -323,12 +341,58 @@ var ExactEvmScheme = class {
|
|
|
323
341
|
tokenName,
|
|
324
342
|
tokenVersion,
|
|
325
343
|
chainId,
|
|
326
|
-
deadline
|
|
344
|
+
deadline,
|
|
345
|
+
requirements.amount
|
|
327
346
|
);
|
|
328
347
|
return {
|
|
329
348
|
[EIP2612_GAS_SPONSORING.key]: { info }
|
|
330
349
|
};
|
|
331
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Attempts to sign an ERC-20 approval transaction for gasless Permit2 approval.
|
|
353
|
+
*
|
|
354
|
+
* This is the fallback path when the token does not support EIP-2612. The client
|
|
355
|
+
* signs (but does not broadcast) a raw `approve(Permit2, MaxUint256)` transaction.
|
|
356
|
+
* The facilitator broadcasts it atomically before settling.
|
|
357
|
+
*
|
|
358
|
+
* Returns extension data if:
|
|
359
|
+
* 1. Server advertises erc20ApprovalGasSponsoring
|
|
360
|
+
* 2. Signer has signTransaction + getTransactionCount capabilities
|
|
361
|
+
* 3. Current Permit2 allowance is insufficient
|
|
362
|
+
*
|
|
363
|
+
* Returns undefined if the extension should not be used.
|
|
364
|
+
*
|
|
365
|
+
* @param requirements - The payment requirements from the server
|
|
366
|
+
* @param _result - The payment payload result from the scheme (unused)
|
|
367
|
+
* @param context - Optional context containing server extensions and metadata
|
|
368
|
+
* @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable
|
|
369
|
+
*/
|
|
370
|
+
async trySignErc20Approval(requirements, _result, context) {
|
|
371
|
+
if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING.key]) {
|
|
372
|
+
return void 0;
|
|
373
|
+
}
|
|
374
|
+
if (!this.signer.signTransaction || !this.signer.getTransactionCount) {
|
|
375
|
+
return void 0;
|
|
376
|
+
}
|
|
377
|
+
const chainId = getEvmChainId(requirements.network);
|
|
378
|
+
const tokenAddress = getAddress5(requirements.asset);
|
|
379
|
+
try {
|
|
380
|
+
const allowance = await this.signer.readContract({
|
|
381
|
+
address: tokenAddress,
|
|
382
|
+
abi: erc20AllowanceAbi,
|
|
383
|
+
functionName: "allowance",
|
|
384
|
+
args: [this.signer.address, PERMIT2_ADDRESS]
|
|
385
|
+
});
|
|
386
|
+
if (allowance >= BigInt(requirements.amount)) {
|
|
387
|
+
return void 0;
|
|
388
|
+
}
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
const info = await signErc20ApprovalTransaction(this.signer, tokenAddress, chainId);
|
|
392
|
+
return {
|
|
393
|
+
[ERC20_APPROVAL_GAS_SPONSORING.key]: { info }
|
|
394
|
+
};
|
|
395
|
+
}
|
|
332
396
|
};
|
|
333
397
|
|
|
334
398
|
// src/exact/client/register.ts
|
|
@@ -353,10 +417,9 @@ function registerExactEvmScheme(client, config) {
|
|
|
353
417
|
}
|
|
354
418
|
|
|
355
419
|
export {
|
|
356
|
-
erc20AllowanceAbi,
|
|
357
420
|
createPermit2ApprovalTx,
|
|
358
421
|
getPermit2AllowanceReadParams,
|
|
359
422
|
ExactEvmScheme,
|
|
360
423
|
registerExactEvmScheme
|
|
361
424
|
};
|
|
362
|
-
//# sourceMappingURL=chunk-
|
|
425
|
+
//# sourceMappingURL=chunk-GY6X5A3G.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/client/scheme.ts","../../src/exact/client/eip3009.ts","../../src/exact/client/permit2.ts","../../src/exact/client/eip2612.ts","../../src/exact/client/erc20approval.ts","../../src/exact/client/register.ts"],"sourcesContent":["import {\n PaymentRequirements,\n SchemeNetworkClient,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@x402/core/types\";\nimport { EIP2612_GAS_SPONSORING, ERC20_APPROVAL_GAS_SPONSORING } from \"@x402/extensions\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { AssetTransferMethod } from \"../../types\";\nimport { PERMIT2_ADDRESS, erc20AllowanceAbi } from \"../../constants\";\nimport { getAddress } from \"viem\";\nimport { getEvmChainId } from \"../../utils\";\nimport { createEIP3009Payload } from \"./eip3009\";\nimport { createPermit2Payload } from \"./permit2\";\nimport { signEip2612Permit } from \"./eip2612\";\nimport { signErc20ApprovalTransaction } from \"./erc20approval\";\n\n/**\n * EVM client implementation for the Exact payment scheme.\n * Supports both EIP-3009 (transferWithAuthorization) and Permit2 flows.\n *\n * Routes to the appropriate authorization method based on\n * `requirements.extra.assetTransferMethod`. Defaults to EIP-3009\n * for backward compatibility with older facilitators.\n *\n * When the server advertises `eip2612GasSponsoring` and the asset transfer\n * method is `permit2`, the scheme automatically signs an EIP-2612 permit\n * if the user lacks Permit2 approval. This requires `readContract` on the signer.\n */\nexport class ExactEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClient instance.\n *\n * @param signer - The EVM signer for client operations.\n * Must support `readContract` for EIP-2612 gas sponsoring.\n * Use `createWalletClient(...).extend(publicActions)` or `toClientEvmSigner(account, publicClient)`.\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Exact scheme.\n * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.\n *\n * For Permit2 flows, if the server advertises `eip2612GasSponsoring` and the\n * signer supports `readContract`, automatically signs an EIP-2612 permit\n * when Permit2 allowance is insufficient.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @param context - Optional context with server-declared extensions\n * @returns Promise resolving to a payment payload result (with optional extensions)\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const assetTransferMethod =\n (paymentRequirements.extra?.assetTransferMethod as AssetTransferMethod) ?? \"eip3009\";\n\n if (assetTransferMethod === \"permit2\") {\n const result = await createPermit2Payload(this.signer, x402Version, paymentRequirements);\n\n // Check if EIP-2612 gas sponsoring is advertised and we can handle it\n const eip2612Extensions = await this.trySignEip2612Permit(\n paymentRequirements,\n result,\n context,\n );\n\n if (eip2612Extensions) {\n return {\n ...result,\n extensions: eip2612Extensions,\n };\n }\n\n // EIP-2612 not applicable — try ERC-20 approval gas sponsoring as fallback\n const erc20Extensions = await this.trySignErc20Approval(paymentRequirements, result, context);\n if (erc20Extensions) {\n return {\n ...result,\n extensions: erc20Extensions,\n };\n }\n\n return result;\n }\n\n return createEIP3009Payload(this.signer, x402Version, paymentRequirements);\n }\n\n /**\n * Attempts to sign an EIP-2612 permit for gasless Permit2 approval.\n *\n * Returns extension data if:\n * 1. Server advertises eip2612GasSponsoring\n * 2. Signer has readContract capability\n * 3. Current Permit2 allowance is insufficient\n *\n * Returns undefined if the extension should not be used.\n *\n * @param requirements - The payment requirements from the server\n * @param result - The payment payload result from the scheme\n * @param context - Optional context containing server extensions and metadata\n * @returns Extension data for EIP-2612 gas sponsoring, or undefined if not applicable\n */\n private async trySignEip2612Permit(\n requirements: PaymentRequirements,\n result: PaymentPayloadResult,\n context?: PaymentPayloadContext,\n ): Promise<Record<string, unknown> | undefined> {\n // Check if server advertises eip2612GasSponsoring\n if (!context?.extensions?.[EIP2612_GAS_SPONSORING.key]) {\n return undefined;\n }\n\n // Check that required token metadata is available\n const tokenName = requirements.extra?.name as string | undefined;\n const tokenVersion = requirements.extra?.version as string | undefined;\n if (!tokenName || !tokenVersion) {\n return undefined;\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n\n // Check if user already has sufficient Permit2 allowance\n try {\n const allowance = (await this.signer.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [this.signer.address, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance >= BigInt(requirements.amount)) {\n return undefined; // Already approved, no need for EIP-2612\n }\n } catch {\n // If we can't check allowance, proceed with EIP-2612 signing\n }\n\n // Use the same deadline as the Permit2 authorization\n const permit2Auth = result.payload?.permit2Authorization as Record<string, unknown> | undefined;\n const deadline =\n (permit2Auth?.deadline as string) ??\n Math.floor(Date.now() / 1000 + requirements.maxTimeoutSeconds).toString();\n\n // Sign the EIP-2612 permit with the exact Permit2 permitted amount\n // (the contract enforces permit2612.value == permit.permitted.amount)\n const info = await signEip2612Permit(\n this.signer,\n tokenAddress,\n tokenName,\n tokenVersion,\n chainId,\n deadline,\n requirements.amount,\n );\n\n return {\n [EIP2612_GAS_SPONSORING.key]: { info },\n };\n }\n\n /**\n * Attempts to sign an ERC-20 approval transaction for gasless Permit2 approval.\n *\n * This is the fallback path when the token does not support EIP-2612. The client\n * signs (but does not broadcast) a raw `approve(Permit2, MaxUint256)` transaction.\n * The facilitator broadcasts it atomically before settling.\n *\n * Returns extension data if:\n * 1. Server advertises erc20ApprovalGasSponsoring\n * 2. Signer has signTransaction + getTransactionCount capabilities\n * 3. Current Permit2 allowance is insufficient\n *\n * Returns undefined if the extension should not be used.\n *\n * @param requirements - The payment requirements from the server\n * @param _result - The payment payload result from the scheme (unused)\n * @param context - Optional context containing server extensions and metadata\n * @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable\n */\n private async trySignErc20Approval(\n requirements: PaymentRequirements,\n _result: PaymentPayloadResult,\n context?: PaymentPayloadContext,\n ): Promise<Record<string, unknown> | undefined> {\n // Check if server advertises erc20ApprovalGasSponsoring\n if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING.key]) {\n return undefined;\n }\n\n // Check that signer has the required capabilities for signing raw transactions\n if (!this.signer.signTransaction || !this.signer.getTransactionCount) {\n return undefined;\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n\n // Check if user already has sufficient Permit2 allowance\n try {\n const allowance = (await this.signer.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [this.signer.address, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance >= BigInt(requirements.amount)) {\n return undefined; // Already approved, no need for ERC-20 approval tx\n }\n } catch {\n // If we can't check allowance, proceed with signing\n }\n\n // Sign the approve(Permit2, MaxUint256) transaction\n const info = await signErc20ApprovalTransaction(this.signer, tokenAddress, chainId);\n\n return {\n [ERC20_APPROVAL_GAS_SPONSORING.key]: { info },\n };\n }\n}\n","import { PaymentRequirements, PaymentPayloadResult } from \"@x402/core/types\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\n\n/**\n * Creates an EIP-3009 (transferWithAuthorization) payload.\n *\n * @param signer - The EVM signer for client operations\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createEIP3009Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEIP3009Payload[\"authorization\"] = {\n from: signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(),\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n const signature = await signEIP3009Authorization(signer, authorization, paymentRequirements);\n\n const payload: ExactEIP3009Payload = {\n authorization,\n signature,\n };\n\n return {\n x402Version,\n payload,\n };\n}\n\n/**\n * Sign the EIP-3009 authorization using EIP-712.\n *\n * @param signer - The EVM signer\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\nasync function signEIP3009Authorization(\n signer: ClientEvmSigner,\n authorization: ExactEIP3009Payload[\"authorization\"],\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n}\n","import { PaymentRequirements, PaymentPayloadResult } from \"@x402/core/types\";\nimport { encodeFunctionData, getAddress } from \"viem\";\nimport {\n permit2WitnessTypes,\n PERMIT2_ADDRESS,\n x402ExactPermit2ProxyAddress,\n erc20ApproveAbi,\n erc20AllowanceAbi,\n} from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactPermit2Payload } from \"../../types\";\nimport { createPermit2Nonce, getEvmChainId } from \"../../utils\";\n\n/** Maximum uint256 value for unlimited approval. */\nconst MAX_UINT256 = BigInt(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\n\n/**\n * Creates a Permit2 payload using the x402Permit2Proxy witness pattern.\n * The spender is set to x402Permit2Proxy, which enforces that funds\n * can only be sent to the witness.to address.\n *\n * @param signer - The EVM signer for client operations\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createPermit2Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const now = Math.floor(Date.now() / 1000);\n const nonce = createPermit2Nonce();\n\n // Lower time bound - allow some clock skew\n const validAfter = (now - 600).toString();\n // Upper time bound is enforced by Permit2's deadline field\n const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();\n\n const permit2Authorization: ExactPermit2Payload[\"permit2Authorization\"] = {\n from: signer.address,\n permitted: {\n token: getAddress(paymentRequirements.asset),\n amount: paymentRequirements.amount,\n },\n spender: x402ExactPermit2ProxyAddress,\n nonce,\n deadline,\n witness: {\n to: getAddress(paymentRequirements.payTo),\n validAfter,\n },\n };\n\n const signature = await signPermit2Authorization(\n signer,\n permit2Authorization,\n paymentRequirements,\n );\n\n const payload: ExactPermit2Payload = {\n signature,\n permit2Authorization,\n };\n\n return {\n x402Version,\n payload,\n };\n}\n\n/**\n * Sign the Permit2 authorization using EIP-712 with witness data.\n * The signature authorizes the x402Permit2Proxy to transfer tokens on behalf of the signer.\n *\n * @param signer - The EVM signer\n * @param permit2Authorization - The Permit2 authorization parameters\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\nasync function signPermit2Authorization(\n signer: ClientEvmSigner,\n permit2Authorization: ExactPermit2Payload[\"permit2Authorization\"],\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n const domain = {\n name: \"Permit2\",\n chainId,\n verifyingContract: PERMIT2_ADDRESS,\n };\n\n const message = {\n permitted: {\n token: getAddress(permit2Authorization.permitted.token),\n amount: BigInt(permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Authorization.spender),\n nonce: BigInt(permit2Authorization.nonce),\n deadline: BigInt(permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Authorization.witness.to),\n validAfter: BigInt(permit2Authorization.witness.validAfter),\n },\n };\n\n return await signer.signTypedData({\n domain,\n types: permit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message,\n });\n}\n\n/**\n * Creates transaction data to approve Permit2 to spend tokens.\n * The user sends this transaction (paying gas) before using Permit2 flow.\n *\n * @param tokenAddress - The ERC20 token contract address\n * @returns Transaction data to send for approval\n *\n * @example\n * ```typescript\n * const tx = createPermit2ApprovalTx(\"0x...\");\n * await walletClient.sendTransaction({\n * to: tx.to,\n * data: tx.data,\n * });\n * ```\n */\nexport function createPermit2ApprovalTx(tokenAddress: `0x${string}`): {\n to: `0x${string}`;\n data: `0x${string}`;\n} {\n const data = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: \"approve\",\n args: [PERMIT2_ADDRESS, MAX_UINT256],\n });\n\n return {\n to: getAddress(tokenAddress),\n data,\n };\n}\n\n/**\n * Parameters for checking Permit2 allowance.\n * Application provides these to check if approval is needed.\n */\nexport interface Permit2AllowanceParams {\n tokenAddress: `0x${string}`;\n ownerAddress: `0x${string}`;\n}\n\n/**\n * Returns contract read parameters for checking Permit2 allowance.\n * Use with a public client to check if the user has approved Permit2.\n *\n * @param params - The allowance check parameters\n * @returns Contract read parameters for checking allowance\n *\n * @example\n * ```typescript\n * const readParams = getPermit2AllowanceReadParams({\n * tokenAddress: \"0x...\",\n * ownerAddress: \"0x...\",\n * });\n *\n * const allowance = await publicClient.readContract(readParams);\n * const needsApproval = allowance < requiredAmount;\n * ```\n */\nexport function getPermit2AllowanceReadParams(params: Permit2AllowanceParams): {\n address: `0x${string}`;\n abi: typeof erc20AllowanceAbi;\n functionName: \"allowance\";\n args: [`0x${string}`, `0x${string}`];\n} {\n return {\n address: getAddress(params.tokenAddress),\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [getAddress(params.ownerAddress), PERMIT2_ADDRESS],\n };\n}\n","import { getAddress } from \"viem\";\nimport type { Eip2612GasSponsoringInfo } from \"@x402/extensions\";\nimport { eip2612PermitTypes, eip2612NoncesAbi, PERMIT2_ADDRESS } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\n\n/**\n * Signs an EIP-2612 permit authorizing the Permit2 contract to spend tokens.\n *\n * This creates a gasless off-chain signature that the facilitator can submit\n * on-chain via `x402Permit2Proxy.settleWithPermit()`.\n *\n * The `permittedAmount` must match the Permit2 `permitted.amount` exactly, as the\n * proxy contract enforces `permit2612.value == permittedAmount`.\n *\n * @param signer - The client EVM signer (must support readContract for nonce query)\n * @param tokenAddress - The ERC-20 token contract address\n * @param tokenName - The token name (from paymentRequirements.extra.name)\n * @param tokenVersion - The token version (from paymentRequirements.extra.version)\n * @param chainId - The chain ID\n * @param deadline - The deadline for the permit (unix timestamp as string)\n * @param permittedAmount - The Permit2 permitted amount (must match exactly)\n * @returns The EIP-2612 gas sponsoring info object\n */\nexport async function signEip2612Permit(\n signer: ClientEvmSigner,\n tokenAddress: `0x${string}`,\n tokenName: string,\n tokenVersion: string,\n chainId: number,\n deadline: string,\n permittedAmount: string,\n): Promise<Eip2612GasSponsoringInfo> {\n const owner = signer.address;\n const spender = getAddress(PERMIT2_ADDRESS);\n\n // Query the current EIP-2612 nonce from the token contract\n const nonce = (await signer.readContract({\n address: tokenAddress,\n abi: eip2612NoncesAbi,\n functionName: \"nonces\",\n args: [owner],\n })) as bigint;\n\n // Construct EIP-712 domain for the token's permit function\n const domain = {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: tokenAddress,\n };\n\n const approvalAmount = BigInt(permittedAmount);\n\n const message = {\n owner,\n spender,\n value: approvalAmount,\n nonce,\n deadline: BigInt(deadline),\n };\n\n // Sign the EIP-2612 permit\n const signature = await signer.signTypedData({\n domain,\n types: eip2612PermitTypes,\n primaryType: \"Permit\",\n message,\n });\n\n return {\n from: owner,\n asset: tokenAddress,\n spender,\n amount: approvalAmount.toString(),\n nonce: nonce.toString(),\n deadline,\n signature,\n version: \"1\",\n };\n}\n","import { encodeFunctionData, getAddress, maxUint256 } from \"viem\";\nimport {\n ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n type Erc20ApprovalGasSponsoringInfo,\n} from \"@x402/extensions\";\nimport {\n PERMIT2_ADDRESS,\n erc20ApproveAbi,\n ERC20_APPROVE_GAS_LIMIT,\n DEFAULT_MAX_FEE_PER_GAS,\n DEFAULT_MAX_PRIORITY_FEE_PER_GAS,\n} from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\n\n/**\n * Signs an EIP-1559 `approve(Permit2, MaxUint256)` transaction for the given token.\n *\n * The signed transaction is NOT broadcast here — the facilitator broadcasts it\n * atomically before settling the Permit2 payment. This enables Permit2 payments\n * for generic ERC-20 tokens that do NOT implement EIP-2612.\n *\n * Always approves MaxUint256 regardless of the payment amount.\n *\n * @param signer - The client EVM signer (must support signTransaction, getTransactionCount)\n * @param tokenAddress - The ERC-20 token contract address\n * @param chainId - The chain ID\n * @returns The ERC-20 approval gas sponsoring info object\n */\nexport async function signErc20ApprovalTransaction(\n signer: ClientEvmSigner,\n tokenAddress: `0x${string}`,\n chainId: number,\n): Promise<Erc20ApprovalGasSponsoringInfo> {\n const from = signer.address;\n const spender = getAddress(PERMIT2_ADDRESS);\n\n // Encode approve(PERMIT2_ADDRESS, MaxUint256) calldata\n const data = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: \"approve\",\n args: [spender, maxUint256],\n });\n\n // Get current nonce for the sender\n const nonce = await signer.getTransactionCount!({ address: from });\n\n // Get current fee estimates, with fallback values\n let maxFeePerGas: bigint;\n let maxPriorityFeePerGas: bigint;\n try {\n const fees = await signer.estimateFeesPerGas!();\n maxFeePerGas = fees.maxFeePerGas;\n maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n } catch {\n maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;\n maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;\n }\n\n // Sign the EIP-1559 transaction (not broadcast)\n const signedTransaction = await signer.signTransaction!({\n to: tokenAddress,\n data,\n nonce,\n gas: ERC20_APPROVE_GAS_LIMIT,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chainId,\n });\n\n return {\n from,\n asset: tokenAddress,\n spender,\n amount: maxUint256.toString(),\n signedTransaction,\n version: ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n };\n}\n","import { x402Client, SelectPaymentRequirements, PaymentPolicy } from \"@x402/core/client\";\nimport { Network } from \"@x402/core/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeV1 } from \"../v1/client/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Client\n */\nexport interface EvmClientConfig {\n /**\n * The EVM signer to use for creating payment payloads\n */\n signer: ClientEvmSigner;\n\n /**\n * Optional payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Client instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param client - The x402Client instance to register schemes to\n * @param config - Configuration for EVM client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/client/register\";\n * import { x402Client } from \"@x402/core/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const account = privateKeyToAccount(\"0x...\");\n * const client = new x402Client();\n * registerExactEvmScheme(client, { signer: account });\n * ```\n */\nexport function registerExactEvmScheme(client: x402Client, config: EvmClientConfig): x402Client {\n const evmScheme = new ExactEvmScheme(config.signer);\n\n // Register V2 scheme\n // EIP-2612 gas sponsoring is handled internally by the scheme when the\n // server advertises support - no separate extension registration needed.\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n client.register(network, evmScheme);\n });\n } else {\n // Register wildcard for all EVM chains\n client.register(\"eip155:*\", evmScheme);\n }\n\n // Register all V1 networks\n NETWORKS.forEach(network => {\n client.registerV1(network as Network, new ExactEvmSchemeV1(config.signer));\n });\n\n // Apply policies if provided\n if (config.policies) {\n config.policies.forEach(policy => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":["getAddress","getAddress","getAddress","getAddress","getAddress","encodeFunctionData","getAddress","getAddress","encodeFunctionData","getAddress"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["/**\n * Asset transfer methods for the exact EVM scheme.\n * - eip3009: Uses transferWithAuthorization (USDC, etc.) - recommended for compatible tokens\n * - permit2: Uses Permit2 + x402Permit2Proxy - universal fallback for any ERC-20\n */\nexport type AssetTransferMethod = \"eip3009\" | \"permit2\";\n\n/**\n * EIP-3009 payload for tokens with native transferWithAuthorization support.\n */\nexport type ExactEIP3009Payload = {\n signature?: `0x${string}`;\n authorization: {\n from: `0x${string}`;\n to: `0x${string}`;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: `0x${string}`;\n };\n};\n\n/**\n * Permit2 witness data structure.\n * Matches the Witness struct in x402Permit2Proxy contract.\n * Note: Upper time bound is enforced by Permit2's `deadline` field, not a witness field.\n */\nexport type Permit2Witness = {\n to: `0x${string}`;\n validAfter: string;\n};\n\n/**\n * Permit2 authorization parameters.\n * Used to reconstruct the signed message for verification.\n */\nexport type Permit2Authorization = {\n permitted: {\n token: `0x${string}`;\n amount: string;\n };\n spender: `0x${string}`;\n nonce: string;\n deadline: string;\n witness: Permit2Witness;\n};\n\n/**\n * Permit2 payload for tokens using the Permit2 + x402Permit2Proxy flow.\n */\nexport type ExactPermit2Payload = {\n signature: `0x${string}`;\n permit2Authorization: Permit2Authorization & {\n from: `0x${string}`;\n };\n};\n\nexport type ExactEvmPayloadV1 = ExactEIP3009Payload;\n\nexport type ExactEvmPayloadV2 = ExactEIP3009Payload | ExactPermit2Payload;\n\n/**\n * Type guard to check if a payload is a Permit2 payload.\n * Permit2 payloads have a `permit2Authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is a Permit2 payload, false otherwise.\n */\nexport function isPermit2Payload(payload: ExactEvmPayloadV2): payload is ExactPermit2Payload {\n return \"permit2Authorization\" in payload;\n}\n\n/**\n * Type guard to check if a payload is an EIP-3009 payload.\n * EIP-3009 payloads have an `authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is an EIP-3009 payload, false otherwise.\n */\nexport function isEIP3009Payload(payload: ExactEvmPayloadV2): payload is ExactEIP3009Payload {\n return \"authorization\" in payload;\n}\n"],"mappings":";AAoEO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,0BAA0B;AACnC;AASO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,mBAAmB;AAC5B;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { E as ExactEvmScheme,
|
|
1
|
+
export { E as ExactEvmScheme, a as Permit2AllowanceParams, c as createPermit2ApprovalTx, d as erc20AllowanceAbi, g as getPermit2AllowanceReadParams } from '../../permit2-CGOcN7Et.mjs';
|
|
2
2
|
import { SelectPaymentRequirements, PaymentPolicy, x402Client } from '@x402/core/client';
|
|
3
3
|
import { Network } from '@x402/core/types';
|
|
4
|
-
import { C as ClientEvmSigner } from '../../signer-
|
|
4
|
+
import { C as ClientEvmSigner } from '../../signer-DC81R8wQ.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Configuration options for registering EVM schemes to an x402Client
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExactEvmScheme,
|
|
3
3
|
createPermit2ApprovalTx,
|
|
4
|
-
erc20AllowanceAbi,
|
|
5
4
|
getPermit2AllowanceReadParams,
|
|
6
5
|
registerExactEvmScheme
|
|
7
|
-
} from "../../chunk-
|
|
8
|
-
import
|
|
6
|
+
} from "../../chunk-GY6X5A3G.mjs";
|
|
7
|
+
import {
|
|
8
|
+
erc20AllowanceAbi
|
|
9
|
+
} from "../../chunk-7KHQD5KT.mjs";
|
|
9
10
|
export {
|
|
10
11
|
ExactEvmScheme,
|
|
11
12
|
createPermit2ApprovalTx,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse, Network } from '@x402/core/types';
|
|
2
|
-
import { F as FacilitatorEvmSigner } from '../../signer-
|
|
1
|
+
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, FacilitatorContext, VerifyResponse, SettleResponse, Network } from '@x402/core/types';
|
|
2
|
+
import { F as FacilitatorEvmSigner } from '../../signer-DC81R8wQ.mjs';
|
|
3
3
|
import { x402Facilitator } from '@x402/core/facilitator';
|
|
4
4
|
|
|
5
5
|
interface ExactEvmSchemeConfig {
|
|
@@ -13,7 +13,9 @@ interface ExactEvmSchemeConfig {
|
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* EVM facilitator implementation for the Exact payment scheme.
|
|
16
|
-
*
|
|
16
|
+
* Thin router that delegates to EIP-3009 or Permit2 based on payload type.
|
|
17
|
+
* All extension handling (EIP-2612, ERC-20 approval gas sponsoring) is owned
|
|
18
|
+
* by the Permit2 functions via FacilitatorContext.
|
|
17
19
|
*/
|
|
18
20
|
declare class ExactEvmScheme implements SchemeNetworkFacilitator {
|
|
19
21
|
private readonly signer;
|
|
@@ -21,46 +23,44 @@ declare class ExactEvmScheme implements SchemeNetworkFacilitator {
|
|
|
21
23
|
readonly caipFamily = "eip155:*";
|
|
22
24
|
private readonly config;
|
|
23
25
|
/**
|
|
24
|
-
* Creates a new
|
|
26
|
+
* Creates a new ExactEvmScheme facilitator instance.
|
|
25
27
|
*
|
|
26
28
|
* @param signer - The EVM signer for facilitator operations
|
|
27
|
-
* @param config - Optional configuration
|
|
29
|
+
* @param config - Optional configuration
|
|
28
30
|
*/
|
|
29
31
|
constructor(signer: FacilitatorEvmSigner, config?: ExactEvmSchemeConfig);
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
32
|
-
* For EVM, no extra data is needed.
|
|
33
|
+
* Returns undefined — EVM has no mechanism-specific extra data.
|
|
33
34
|
*
|
|
34
|
-
* @param _ - The network identifier (unused
|
|
35
|
-
* @returns undefined
|
|
35
|
+
* @param _ - The network identifier (unused)
|
|
36
|
+
* @returns undefined
|
|
36
37
|
*/
|
|
37
38
|
getExtra(_: string): Record<string, unknown> | undefined;
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
* Returns all addresses this facilitator can use for signing/settling transactions.
|
|
40
|
+
* Returns facilitator wallet addresses for the supported response.
|
|
41
41
|
*
|
|
42
|
-
* @param _ - The network identifier (unused
|
|
42
|
+
* @param _ - The network identifier (unused, addresses are network-agnostic)
|
|
43
43
|
* @returns Array of facilitator wallet addresses
|
|
44
44
|
*/
|
|
45
45
|
getSigners(_: string): string[];
|
|
46
46
|
/**
|
|
47
|
-
* Verifies a payment payload.
|
|
48
|
-
* Routes to the appropriate verification logic based on payload type.
|
|
47
|
+
* Verifies a payment payload. Routes to Permit2 or EIP-3009 based on payload type.
|
|
49
48
|
*
|
|
50
49
|
* @param payload - The payment payload to verify
|
|
51
50
|
* @param requirements - The payment requirements
|
|
51
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
52
52
|
* @returns Promise resolving to verification response
|
|
53
53
|
*/
|
|
54
|
-
verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
|
|
54
|
+
verify(payload: PaymentPayload, requirements: PaymentRequirements, context?: FacilitatorContext): Promise<VerifyResponse>;
|
|
55
55
|
/**
|
|
56
|
-
* Settles a payment
|
|
57
|
-
* Routes to the appropriate settlement logic based on payload type.
|
|
56
|
+
* Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.
|
|
58
57
|
*
|
|
59
58
|
* @param payload - The payment payload to settle
|
|
60
59
|
* @param requirements - The payment requirements
|
|
60
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
61
61
|
* @returns Promise resolving to settlement response
|
|
62
62
|
*/
|
|
63
|
-
settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
|
|
63
|
+
settle(payload: PaymentPayload, requirements: PaymentRequirements, context?: FacilitatorContext): Promise<SettleResponse>;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|