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