@x402/evm 2.6.0 → 2.7.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/README.md +24 -0
- package/dist/cjs/exact/client/index.d.ts +12 -5
- package/dist/cjs/exact/client/index.js +127 -28
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.d.ts +13 -1
- package/dist/cjs/exact/facilitator/index.js +987 -606
- 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 +11 -5
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.d.ts +16 -1
- package/dist/cjs/exact/v1/facilitator/index.js +414 -177
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +143 -30
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{permit2-DHAq6FTe.d.ts → permit2-U9Zolx3O.d.ts} +38 -5
- package/dist/{esm/signer-DC81R8wQ.d.mts → cjs/signer-D912R4mq.d.ts} +9 -3
- package/dist/cjs/v1/index.d.ts +1 -1
- package/dist/cjs/v1/index.js +6 -0
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/chunk-GD4MKCN7.mjs +57 -0
- package/dist/esm/chunk-GD4MKCN7.mjs.map +1 -0
- package/dist/esm/{chunk-XL6IFXCP.mjs → chunk-IZEI7JTG.mjs} +516 -178
- package/dist/esm/chunk-IZEI7JTG.mjs.map +1 -0
- package/dist/esm/{chunk-LBIJBD7Q.mjs → chunk-WJWNS4G4.mjs} +113 -20
- package/dist/esm/chunk-WJWNS4G4.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +12 -5
- package/dist/esm/exact/client/index.mjs +3 -2
- package/dist/esm/exact/facilitator/index.d.mts +13 -1
- package/dist/esm/exact/facilitator/index.mjs +498 -391
- 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 +1 -1
- package/dist/esm/exact/v1/facilitator/index.d.mts +16 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +1 -1
- package/dist/esm/index.d.mts +2 -2
- package/dist/esm/index.mjs +7 -9
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{permit2-BuAhWvNC.d.mts → permit2-Bbh3a8_h.d.mts} +38 -5
- package/dist/{cjs/signer-DC81R8wQ.d.ts → esm/signer-D912R4mq.d.mts} +9 -3
- package/dist/esm/v1/index.d.mts +1 -1
- package/dist/esm/v1/index.mjs +1 -1
- package/package.json +2 -3
- package/dist/esm/chunk-LBIJBD7Q.mjs.map +0 -1
- package/dist/esm/chunk-XL6IFXCP.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -125,6 +125,30 @@ const client = new x402Client()
|
|
|
125
125
|
.registerSchemeV1("base", new ExactEvmClientV1(signer));
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
### Extension RPC Configuration (Optional)
|
|
129
|
+
|
|
130
|
+
`ExactEvmClient` only requires signer support for `address` + `signTypedData`.
|
|
131
|
+
Permit2 extension enrichment (EIP-2612 / ERC-20 approval gas sponsoring) can
|
|
132
|
+
optionally use explicit RPC config when signer read/fee helpers are unavailable.
|
|
133
|
+
|
|
134
|
+
No chain-default RPC fallback is applied by the SDK.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Per-network explicit registration
|
|
138
|
+
const client = new x402Client()
|
|
139
|
+
.register("eip155:137", new ExactEvmClient(signer, { rpcUrl: polygonRpcUrl }))
|
|
140
|
+
.register("eip155:8453", new ExactEvmClient(signer, { rpcUrl: baseRpcUrl }));
|
|
141
|
+
|
|
142
|
+
// Wildcard registration with chain-id keyed config map
|
|
143
|
+
const wildcardClient = new x402Client().register(
|
|
144
|
+
"eip155:*",
|
|
145
|
+
new ExactEvmClient(signer, {
|
|
146
|
+
137: { rpcUrl: polygonRpcUrl },
|
|
147
|
+
8453: { rpcUrl: baseRpcUrl },
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
128
152
|
### 3. Using Config (Flexible)
|
|
129
153
|
|
|
130
154
|
```typescript
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { i as ExactEvmSchemeOptions } from '../../permit2-U9Zolx3O.js';
|
|
2
|
+
export { E as ExactEvmScheme, j as ExactEvmSchemeConfig, k as ExactEvmSchemeConfigByChainId, P as Permit2AllowanceParams, c as createPermit2ApprovalTx, e as erc20AllowanceAbi, g as getPermit2AllowanceReadParams } from '../../permit2-U9Zolx3O.js';
|
|
2
3
|
import { x402Client, SelectPaymentRequirements, PaymentPolicy } from '@x402/core/client';
|
|
3
4
|
import { Network } from '@x402/core/types';
|
|
4
|
-
import { C as ClientEvmSigner } from '../../signer-
|
|
5
|
+
import { C as ClientEvmSigner } from '../../signer-D912R4mq.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Configuration options for registering EVM schemes to an x402Client
|
|
@@ -21,8 +22,14 @@ interface EvmClientConfig {
|
|
|
21
22
|
*/
|
|
22
23
|
policies?: PaymentPolicy[];
|
|
23
24
|
/**
|
|
24
|
-
* Optional
|
|
25
|
-
*
|
|
25
|
+
* Optional Exact EVM client scheme options.
|
|
26
|
+
* Supports either a single config ({ rpcUrl }) or per-chain configs
|
|
27
|
+
* keyed by EVM chain ID ({ 8453: { rpcUrl: "..." } }).
|
|
28
|
+
*/
|
|
29
|
+
schemeOptions?: ExactEvmSchemeOptions;
|
|
30
|
+
/**
|
|
31
|
+
* Optional specific networks to register.
|
|
32
|
+
* If not provided, registers wildcard support (eip155:*).
|
|
26
33
|
*/
|
|
27
34
|
networks?: Network[];
|
|
28
35
|
}
|
|
@@ -50,4 +57,4 @@ interface EvmClientConfig {
|
|
|
50
57
|
*/
|
|
51
58
|
declare function registerExactEvmScheme(client: x402Client, config: EvmClientConfig): x402Client;
|
|
52
59
|
|
|
53
|
-
export { type EvmClientConfig, registerExactEvmScheme };
|
|
60
|
+
export { type EvmClientConfig, ExactEvmSchemeOptions, registerExactEvmScheme };
|
|
@@ -28,9 +28,6 @@ __export(client_exports, {
|
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(client_exports);
|
|
30
30
|
|
|
31
|
-
// src/exact/client/scheme.ts
|
|
32
|
-
var import_extensions2 = require("@x402/extensions");
|
|
33
|
-
|
|
34
31
|
// src/constants.ts
|
|
35
32
|
var authorizationTypes = {
|
|
36
33
|
TransferWithAuthorization: [
|
|
@@ -108,7 +105,7 @@ var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
|
108
105
|
var x402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
109
106
|
|
|
110
107
|
// src/exact/client/scheme.ts
|
|
111
|
-
var
|
|
108
|
+
var import_viem7 = require("viem");
|
|
112
109
|
|
|
113
110
|
// src/utils.ts
|
|
114
111
|
var import_viem = require("viem");
|
|
@@ -138,6 +135,11 @@ function createPermit2Nonce() {
|
|
|
138
135
|
return BigInt((0, import_viem.toHex)(randomBytes)).toString();
|
|
139
136
|
}
|
|
140
137
|
|
|
138
|
+
// src/exact/extensions.ts
|
|
139
|
+
var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
|
|
140
|
+
var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
|
|
141
|
+
var ERC20_APPROVAL_GAS_SPONSORING_VERSION = "1";
|
|
142
|
+
|
|
141
143
|
// src/exact/client/eip3009.ts
|
|
142
144
|
var import_viem2 = require("viem");
|
|
143
145
|
async function createEIP3009Payload(signer, x402Version, paymentRequirements) {
|
|
@@ -319,7 +321,6 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
319
321
|
|
|
320
322
|
// src/exact/client/erc20approval.ts
|
|
321
323
|
var import_viem5 = require("viem");
|
|
322
|
-
var import_extensions = require("@x402/extensions");
|
|
323
324
|
async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
|
|
324
325
|
const from = signer.address;
|
|
325
326
|
const spender = (0, import_viem5.getAddress)(PERMIT2_ADDRESS);
|
|
@@ -332,7 +333,10 @@ async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
|
|
|
332
333
|
let maxFeePerGas;
|
|
333
334
|
let maxPriorityFeePerGas;
|
|
334
335
|
try {
|
|
335
|
-
const fees = await signer.estimateFeesPerGas();
|
|
336
|
+
const fees = await signer.estimateFeesPerGas?.();
|
|
337
|
+
if (!fees) {
|
|
338
|
+
throw new Error("no fee estimates available");
|
|
339
|
+
}
|
|
336
340
|
maxFeePerGas = fees.maxFeePerGas;
|
|
337
341
|
maxPriorityFeePerGas = fees.maxPriorityFeePerGas;
|
|
338
342
|
} catch {
|
|
@@ -354,8 +358,65 @@ async function signErc20ApprovalTransaction(signer, tokenAddress, chainId) {
|
|
|
354
358
|
spender,
|
|
355
359
|
amount: import_viem5.maxUint256.toString(),
|
|
356
360
|
signedTransaction,
|
|
357
|
-
version:
|
|
361
|
+
version: ERC20_APPROVAL_GAS_SPONSORING_VERSION
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/exact/client/rpc.ts
|
|
366
|
+
var import_viem6 = require("viem");
|
|
367
|
+
var rpcClientCache = /* @__PURE__ */ new Map();
|
|
368
|
+
function isConfigByChainId(options) {
|
|
369
|
+
const keys = Object.keys(options);
|
|
370
|
+
return keys.length > 0 && keys.every((key) => /^\d+$/.test(key));
|
|
371
|
+
}
|
|
372
|
+
function getRpcClient(rpcUrl) {
|
|
373
|
+
const existing = rpcClientCache.get(rpcUrl);
|
|
374
|
+
if (existing) {
|
|
375
|
+
return existing;
|
|
376
|
+
}
|
|
377
|
+
const client = (0, import_viem6.createPublicClient)({
|
|
378
|
+
transport: (0, import_viem6.http)(rpcUrl)
|
|
379
|
+
});
|
|
380
|
+
rpcClientCache.set(rpcUrl, client);
|
|
381
|
+
return client;
|
|
382
|
+
}
|
|
383
|
+
function resolveRpcUrl(network, options) {
|
|
384
|
+
if (!options) {
|
|
385
|
+
return void 0;
|
|
386
|
+
}
|
|
387
|
+
if (isConfigByChainId(options)) {
|
|
388
|
+
const chainId = getEvmChainId(network);
|
|
389
|
+
const optionsByChainId = options;
|
|
390
|
+
return optionsByChainId[chainId]?.rpcUrl;
|
|
391
|
+
}
|
|
392
|
+
return options.rpcUrl;
|
|
393
|
+
}
|
|
394
|
+
function resolveExtensionRpcCapabilities(network, signer, options) {
|
|
395
|
+
const capabilities = {
|
|
396
|
+
signTransaction: signer.signTransaction,
|
|
397
|
+
readContract: signer.readContract,
|
|
398
|
+
getTransactionCount: signer.getTransactionCount,
|
|
399
|
+
estimateFeesPerGas: signer.estimateFeesPerGas
|
|
358
400
|
};
|
|
401
|
+
const needsRpcBackfill = !capabilities.readContract || !capabilities.getTransactionCount || !capabilities.estimateFeesPerGas;
|
|
402
|
+
if (!needsRpcBackfill) {
|
|
403
|
+
return capabilities;
|
|
404
|
+
}
|
|
405
|
+
const rpcUrl = resolveRpcUrl(network, options);
|
|
406
|
+
if (!rpcUrl) {
|
|
407
|
+
return capabilities;
|
|
408
|
+
}
|
|
409
|
+
const rpcClient = getRpcClient(rpcUrl);
|
|
410
|
+
if (!capabilities.readContract) {
|
|
411
|
+
capabilities.readContract = (args) => rpcClient.readContract(args);
|
|
412
|
+
}
|
|
413
|
+
if (!capabilities.getTransactionCount) {
|
|
414
|
+
capabilities.getTransactionCount = async (args) => rpcClient.getTransactionCount({ address: args.address });
|
|
415
|
+
}
|
|
416
|
+
if (!capabilities.estimateFeesPerGas) {
|
|
417
|
+
capabilities.estimateFeesPerGas = async () => rpcClient.estimateFeesPerGas();
|
|
418
|
+
}
|
|
419
|
+
return capabilities;
|
|
359
420
|
}
|
|
360
421
|
|
|
361
422
|
// src/exact/client/scheme.ts
|
|
@@ -364,11 +425,14 @@ var ExactEvmScheme = class {
|
|
|
364
425
|
* Creates a new ExactEvmClient instance.
|
|
365
426
|
*
|
|
366
427
|
* @param signer - The EVM signer for client operations.
|
|
367
|
-
*
|
|
368
|
-
*
|
|
428
|
+
* Base flow only requires `address` + `signTypedData`.
|
|
429
|
+
* Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally
|
|
430
|
+
* requires optional capabilities like `readContract` and tx signing helpers.
|
|
431
|
+
* @param options - Optional RPC configuration used to backfill extension capabilities.
|
|
369
432
|
*/
|
|
370
|
-
constructor(signer) {
|
|
433
|
+
constructor(signer, options) {
|
|
371
434
|
this.signer = signer;
|
|
435
|
+
this.options = options;
|
|
372
436
|
this.scheme = "exact";
|
|
373
437
|
}
|
|
374
438
|
/**
|
|
@@ -426,7 +490,15 @@ var ExactEvmScheme = class {
|
|
|
426
490
|
* @returns Extension data for EIP-2612 gas sponsoring, or undefined if not applicable
|
|
427
491
|
*/
|
|
428
492
|
async trySignEip2612Permit(requirements, result, context) {
|
|
429
|
-
|
|
493
|
+
const capabilities = resolveExtensionRpcCapabilities(
|
|
494
|
+
requirements.network,
|
|
495
|
+
this.signer,
|
|
496
|
+
this.options
|
|
497
|
+
);
|
|
498
|
+
if (!capabilities.readContract) {
|
|
499
|
+
return void 0;
|
|
500
|
+
}
|
|
501
|
+
if (!context?.extensions?.[EIP2612_GAS_SPONSORING_KEY]) {
|
|
430
502
|
return void 0;
|
|
431
503
|
}
|
|
432
504
|
const tokenName = requirements.extra?.name;
|
|
@@ -435,9 +507,9 @@ var ExactEvmScheme = class {
|
|
|
435
507
|
return void 0;
|
|
436
508
|
}
|
|
437
509
|
const chainId = getEvmChainId(requirements.network);
|
|
438
|
-
const tokenAddress = (0,
|
|
510
|
+
const tokenAddress = (0, import_viem7.getAddress)(requirements.asset);
|
|
439
511
|
try {
|
|
440
|
-
const allowance = await
|
|
512
|
+
const allowance = await capabilities.readContract({
|
|
441
513
|
address: tokenAddress,
|
|
442
514
|
abi: erc20AllowanceAbi,
|
|
443
515
|
functionName: "allowance",
|
|
@@ -451,7 +523,11 @@ var ExactEvmScheme = class {
|
|
|
451
523
|
const permit2Auth = result.payload?.permit2Authorization;
|
|
452
524
|
const deadline = permit2Auth?.deadline ?? Math.floor(Date.now() / 1e3 + requirements.maxTimeoutSeconds).toString();
|
|
453
525
|
const info = await signEip2612Permit(
|
|
454
|
-
|
|
526
|
+
{
|
|
527
|
+
address: this.signer.address,
|
|
528
|
+
signTypedData: (msg) => this.signer.signTypedData(msg),
|
|
529
|
+
readContract: capabilities.readContract
|
|
530
|
+
},
|
|
455
531
|
tokenAddress,
|
|
456
532
|
tokenName,
|
|
457
533
|
tokenVersion,
|
|
@@ -460,7 +536,7 @@ var ExactEvmScheme = class {
|
|
|
460
536
|
requirements.amount
|
|
461
537
|
);
|
|
462
538
|
return {
|
|
463
|
-
[
|
|
539
|
+
[EIP2612_GAS_SPONSORING_KEY]: { info }
|
|
464
540
|
};
|
|
465
541
|
}
|
|
466
542
|
/**
|
|
@@ -483,16 +559,24 @@ var ExactEvmScheme = class {
|
|
|
483
559
|
* @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable
|
|
484
560
|
*/
|
|
485
561
|
async trySignErc20Approval(requirements, _result, context) {
|
|
486
|
-
|
|
562
|
+
const capabilities = resolveExtensionRpcCapabilities(
|
|
563
|
+
requirements.network,
|
|
564
|
+
this.signer,
|
|
565
|
+
this.options
|
|
566
|
+
);
|
|
567
|
+
if (!capabilities.readContract) {
|
|
568
|
+
return void 0;
|
|
569
|
+
}
|
|
570
|
+
if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING_KEY]) {
|
|
487
571
|
return void 0;
|
|
488
572
|
}
|
|
489
|
-
if (!
|
|
573
|
+
if (!capabilities.signTransaction || !capabilities.getTransactionCount) {
|
|
490
574
|
return void 0;
|
|
491
575
|
}
|
|
492
576
|
const chainId = getEvmChainId(requirements.network);
|
|
493
|
-
const tokenAddress = (0,
|
|
577
|
+
const tokenAddress = (0, import_viem7.getAddress)(requirements.asset);
|
|
494
578
|
try {
|
|
495
|
-
const allowance = await
|
|
579
|
+
const allowance = await capabilities.readContract({
|
|
496
580
|
address: tokenAddress,
|
|
497
581
|
abi: erc20AllowanceAbi,
|
|
498
582
|
functionName: "allowance",
|
|
@@ -503,18 +587,33 @@ var ExactEvmScheme = class {
|
|
|
503
587
|
}
|
|
504
588
|
} catch {
|
|
505
589
|
}
|
|
506
|
-
const info = await signErc20ApprovalTransaction(
|
|
590
|
+
const info = await signErc20ApprovalTransaction(
|
|
591
|
+
{
|
|
592
|
+
address: this.signer.address,
|
|
593
|
+
signTransaction: capabilities.signTransaction,
|
|
594
|
+
getTransactionCount: capabilities.getTransactionCount,
|
|
595
|
+
estimateFeesPerGas: capabilities.estimateFeesPerGas
|
|
596
|
+
},
|
|
597
|
+
tokenAddress,
|
|
598
|
+
chainId
|
|
599
|
+
);
|
|
507
600
|
return {
|
|
508
|
-
[
|
|
601
|
+
[ERC20_APPROVAL_GAS_SPONSORING_KEY]: { info }
|
|
509
602
|
};
|
|
510
603
|
}
|
|
511
604
|
};
|
|
512
605
|
|
|
513
606
|
// src/exact/v1/client/scheme.ts
|
|
514
|
-
var
|
|
607
|
+
var import_viem11 = require("viem");
|
|
515
608
|
|
|
516
609
|
// src/exact/v1/facilitator/scheme.ts
|
|
517
|
-
var
|
|
610
|
+
var import_viem10 = require("viem");
|
|
611
|
+
|
|
612
|
+
// src/exact/facilitator/eip3009-utils.ts
|
|
613
|
+
var import_viem9 = require("viem");
|
|
614
|
+
|
|
615
|
+
// src/multicall.ts
|
|
616
|
+
var import_viem8 = require("viem");
|
|
518
617
|
|
|
519
618
|
// src/v1/index.ts
|
|
520
619
|
var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
@@ -571,7 +670,7 @@ var ExactEvmSchemeV1 = class {
|
|
|
571
670
|
const now = Math.floor(Date.now() / 1e3);
|
|
572
671
|
const authorization = {
|
|
573
672
|
from: this.signer.address,
|
|
574
|
-
to: (0,
|
|
673
|
+
to: (0, import_viem11.getAddress)(selectedV1.payTo),
|
|
575
674
|
value: selectedV1.maxAmountRequired,
|
|
576
675
|
validAfter: (now - 600).toString(),
|
|
577
676
|
// 10 minutes before
|
|
@@ -609,11 +708,11 @@ var ExactEvmSchemeV1 = class {
|
|
|
609
708
|
name,
|
|
610
709
|
version,
|
|
611
710
|
chainId,
|
|
612
|
-
verifyingContract: (0,
|
|
711
|
+
verifyingContract: (0, import_viem11.getAddress)(requirements.asset)
|
|
613
712
|
};
|
|
614
713
|
const message = {
|
|
615
|
-
from: (0,
|
|
616
|
-
to: (0,
|
|
714
|
+
from: (0, import_viem11.getAddress)(authorization.from),
|
|
715
|
+
to: (0, import_viem11.getAddress)(authorization.to),
|
|
617
716
|
value: BigInt(authorization.value),
|
|
618
717
|
validAfter: BigInt(authorization.validAfter),
|
|
619
718
|
validBefore: BigInt(authorization.validBefore),
|
|
@@ -630,7 +729,7 @@ var ExactEvmSchemeV1 = class {
|
|
|
630
729
|
|
|
631
730
|
// src/exact/client/register.ts
|
|
632
731
|
function registerExactEvmScheme(client, config) {
|
|
633
|
-
const evmScheme = new ExactEvmScheme(config.signer);
|
|
732
|
+
const evmScheme = new ExactEvmScheme(config.signer, config.schemeOptions);
|
|
634
733
|
if (config.networks && config.networks.length > 0) {
|
|
635
734
|
config.networks.forEach((network) => {
|
|
636
735
|
client.register(network, evmScheme);
|