@introspectivelabs/x402-evm 0.1.0-beta.17 → 0.1.0-beta.19
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 +3 -3
- package/dist/cjs/exact/client/index.js +147 -85
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +147 -85
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{userOpHash-Bzusu9T7.d.ts → userOpHash-qINeS6ay.d.ts} +70 -42
- package/dist/esm/{chunk-XA674MVY.mjs → chunk-WD636IAI.mjs} +148 -86
- package/dist/esm/chunk-WD636IAI.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +3 -3
- package/dist/esm/exact/client/index.mjs +1 -1
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/{userOpHash-Cz7aBb3Q.d.mts → userOpHash-BmAc6_D7.d.mts} +70 -42
- package/package.json +1 -1
- package/dist/esm/chunk-XA674MVY.mjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { U as UserOperationSigner, P as PreparedUserOperation } from '../../userOpHash-
|
|
2
|
-
export { B as BundlerClient,
|
|
1
|
+
import { U as UserOperationSigner, P as PreparedUserOperation } from '../../userOpHash-qINeS6ay.js';
|
|
2
|
+
export { B as BundlerClient, g as BundlerClientConfig, k as ERC20_TRANSFER_ABI, c as ExactEvmSchemeEIP3009, d as ExactEvmSchemeEIP3009Config, E as ExactEvmSchemeERC4337, a as ExactEvmSchemeERC4337Config, G as GasEstimate, m as PackedUserOp, b as PreparedPayment, h as UserOperationCall, V as ViemBundlerClient, i as ViemBundlerClientConfig, j as buildERC20TransferCallData, l as computeUserOpHash, e as createP256SafeMessageSigner, f as createWebAuthnSafeMessageSigner, u as userOpToJson } from '../../userOpHash-qINeS6ay.js';
|
|
3
3
|
import { SmartAccount } from 'viem/account-abstraction';
|
|
4
4
|
import 'viem';
|
|
5
|
-
import '../../types-Dk5U6Xnw.js';
|
|
6
5
|
import '../../types-lO5B0FRc.js';
|
|
7
6
|
import '@x402/core/types';
|
|
7
|
+
import '../../types-Dk5U6Xnw.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Adapter to make a SmartAccount (e.g., Safe account) work as a UserOperationSigner.
|
|
@@ -53,15 +53,13 @@ var import_viem5 = require("viem");
|
|
|
53
53
|
// src/exact/client/bundler/viem.ts
|
|
54
54
|
var import_viem = require("viem");
|
|
55
55
|
var import_account_abstraction = require("viem/account-abstraction");
|
|
56
|
+
function bigintToHex(n) {
|
|
57
|
+
return `0x${n.toString(16)}`;
|
|
58
|
+
}
|
|
56
59
|
var ViemBundlerClient = class {
|
|
57
|
-
/**
|
|
58
|
-
* Creates a new ViemBundlerClient instance.
|
|
59
|
-
*
|
|
60
|
-
* @param config - Configuration for the bundler client
|
|
61
|
-
*/
|
|
62
60
|
constructor(config) {
|
|
63
61
|
this.account = config.account;
|
|
64
|
-
this.
|
|
62
|
+
this.usePaymaster = config.paymaster === true;
|
|
65
63
|
this.bundlerClient = (0, import_account_abstraction.createBundlerClient)({
|
|
66
64
|
client: config.publicClient,
|
|
67
65
|
chain: config.chain,
|
|
@@ -70,13 +68,91 @@ var ViemBundlerClient = class {
|
|
|
70
68
|
});
|
|
71
69
|
}
|
|
72
70
|
/**
|
|
73
|
-
* Prepares an unsigned user operation
|
|
71
|
+
* Prepares an unsigned user operation using raw RPC calls.
|
|
74
72
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
73
|
+
* When paymaster is enabled, uses pm_sponsorUserOperation to get paymaster
|
|
74
|
+
* data and gas estimates in a single call (Pimlico-compatible).
|
|
75
|
+
* The returned UserOp has final paymaster data ready for hash computation and signing.
|
|
78
76
|
*/
|
|
79
|
-
async prepareUserOperation(calls,
|
|
77
|
+
async prepareUserOperation(calls, entryPoint) {
|
|
78
|
+
if (!this.usePaymaster) {
|
|
79
|
+
return this.prepareWithoutPaymaster(calls);
|
|
80
|
+
}
|
|
81
|
+
const callData = await this.account.encodeCalls(
|
|
82
|
+
calls.map((call) => ({
|
|
83
|
+
to: call.to,
|
|
84
|
+
value: call.value,
|
|
85
|
+
data: call.data
|
|
86
|
+
}))
|
|
87
|
+
);
|
|
88
|
+
const nonce = await this.account.getNonce();
|
|
89
|
+
const sender = await this.account.getAddress();
|
|
90
|
+
const gasPriceResult = await this.bundlerClient.request({
|
|
91
|
+
method: "pimlico_getUserOperationGasPrice",
|
|
92
|
+
params: []
|
|
93
|
+
});
|
|
94
|
+
const maxFeePerGas = BigInt(gasPriceResult.fast.maxFeePerGas);
|
|
95
|
+
const maxPriorityFeePerGas = BigInt(gasPriceResult.fast.maxPriorityFeePerGas);
|
|
96
|
+
const stubSignature = await this.account.getStubSignature();
|
|
97
|
+
{
|
|
98
|
+
const userOpForEstimation = {
|
|
99
|
+
sender,
|
|
100
|
+
nonce: `0x${nonce.toString(16)}`,
|
|
101
|
+
callData,
|
|
102
|
+
signature: stubSignature,
|
|
103
|
+
callGasLimit: bigintToHex(500000n),
|
|
104
|
+
verificationGasLimit: bigintToHex(500000n),
|
|
105
|
+
preVerificationGas: bigintToHex(100000n),
|
|
106
|
+
maxFeePerGas: bigintToHex(maxFeePerGas),
|
|
107
|
+
maxPriorityFeePerGas: bigintToHex(maxPriorityFeePerGas)
|
|
108
|
+
};
|
|
109
|
+
const sponsorResult = await this.bundlerClient.request({
|
|
110
|
+
method: "pm_sponsorUserOperation",
|
|
111
|
+
params: [userOpForEstimation, entryPoint]
|
|
112
|
+
});
|
|
113
|
+
const callGasLimit = BigInt(sponsorResult.callGasLimit);
|
|
114
|
+
const verificationGasLimit = BigInt(sponsorResult.verificationGasLimit);
|
|
115
|
+
const preVerificationGas = BigInt(sponsorResult.preVerificationGas);
|
|
116
|
+
let paymaster;
|
|
117
|
+
let paymasterData;
|
|
118
|
+
let paymasterVerificationGasLimit;
|
|
119
|
+
let paymasterPostOpGasLimit;
|
|
120
|
+
if (sponsorResult.paymaster) {
|
|
121
|
+
paymaster = sponsorResult.paymaster;
|
|
122
|
+
paymasterData = sponsorResult.paymasterData ?? "0x";
|
|
123
|
+
paymasterVerificationGasLimit = BigInt(sponsorResult.paymasterVerificationGasLimit ?? "0x0");
|
|
124
|
+
paymasterPostOpGasLimit = BigInt(sponsorResult.paymasterPostOpGasLimit ?? "0x0");
|
|
125
|
+
} else if (sponsorResult.paymasterAndData && sponsorResult.paymasterAndData !== "0x") {
|
|
126
|
+
const packed = sponsorResult.paymasterAndData;
|
|
127
|
+
paymaster = `0x${packed.slice(2, 42)}`;
|
|
128
|
+
paymasterVerificationGasLimit = BigInt(`0x${packed.slice(42, 74)}`);
|
|
129
|
+
paymasterPostOpGasLimit = BigInt(`0x${packed.slice(74, 106)}`);
|
|
130
|
+
paymasterData = `0x${packed.slice(106)}`;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
sender,
|
|
134
|
+
nonce,
|
|
135
|
+
// Include factory/factoryData keys so that downstream signers (e.g. permissionless
|
|
136
|
+
// Safe signUserOperation) detect v0.7 format and correctly pack paymasterAndData
|
|
137
|
+
// from the separate v0.7 fields. Without these keys, permissionless defaults to
|
|
138
|
+
// paymasterAndData: "0x" causing SafeOp hash mismatch (AA24).
|
|
139
|
+
factory: void 0,
|
|
140
|
+
factoryData: void 0,
|
|
141
|
+
callData,
|
|
142
|
+
callGasLimit,
|
|
143
|
+
verificationGasLimit,
|
|
144
|
+
preVerificationGas,
|
|
145
|
+
maxFeePerGas,
|
|
146
|
+
maxPriorityFeePerGas,
|
|
147
|
+
...paymaster ? { paymaster } : {},
|
|
148
|
+
...paymasterData ? { paymasterData } : {},
|
|
149
|
+
...paymasterVerificationGasLimit != null ? { paymasterVerificationGasLimit } : {},
|
|
150
|
+
...paymasterPostOpGasLimit != null ? { paymasterPostOpGasLimit } : {},
|
|
151
|
+
signature: stubSignature
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async prepareWithoutPaymaster(calls) {
|
|
80
156
|
const prepared = await this.bundlerClient.prepareUserOperation({
|
|
81
157
|
account: this.account,
|
|
82
158
|
calls: calls.map((call) => ({
|
|
@@ -89,31 +165,20 @@ var ViemBundlerClient = class {
|
|
|
89
165
|
return {
|
|
90
166
|
sender: prepared.sender,
|
|
91
167
|
nonce: prepared.nonce,
|
|
168
|
+
// Always include factory/factoryData keys for v0.7 format detection by signers
|
|
169
|
+
factory: p.factory ?? void 0,
|
|
170
|
+
factoryData: p.factoryData ?? void 0,
|
|
92
171
|
callData: prepared.callData,
|
|
93
172
|
callGasLimit: prepared.callGasLimit,
|
|
94
173
|
verificationGasLimit: prepared.verificationGasLimit,
|
|
95
174
|
preVerificationGas: prepared.preVerificationGas,
|
|
96
175
|
maxFeePerGas: prepared.maxFeePerGas,
|
|
97
176
|
maxPriorityFeePerGas: prepared.maxPriorityFeePerGas,
|
|
98
|
-
// v0.7 factory fields (for account deployment)
|
|
99
|
-
...p.factory ? { factory: p.factory } : {},
|
|
100
|
-
...p.factoryData ? { factoryData: p.factoryData } : {},
|
|
101
|
-
// v0.7 paymaster fields (separate, not paymasterAndData)
|
|
102
|
-
...p.paymaster ? { paymaster: p.paymaster } : {},
|
|
103
|
-
...p.paymasterData ? { paymasterData: p.paymasterData } : {},
|
|
104
|
-
...p.paymasterVerificationGasLimit != null ? { paymasterVerificationGasLimit: p.paymasterVerificationGasLimit } : {},
|
|
105
|
-
...p.paymasterPostOpGasLimit != null ? { paymasterPostOpGasLimit: p.paymasterPostOpGasLimit } : {},
|
|
106
177
|
signature: prepared.signature
|
|
107
178
|
};
|
|
108
179
|
}
|
|
109
180
|
/**
|
|
110
|
-
*
|
|
111
|
-
* Note: This is typically done as part of prepareUserOperation,
|
|
112
|
-
* but is available as a separate method for flexibility.
|
|
113
|
-
*
|
|
114
|
-
* @param _userOp - The user operation to estimate gas for
|
|
115
|
-
* @param _entryPoint - The entry point address
|
|
116
|
-
* @returns Promise resolving to gas estimates
|
|
181
|
+
* @deprecated Gas estimation is done as part of prepareUserOperation
|
|
117
182
|
*/
|
|
118
183
|
async estimateGas(_userOp, _entryPoint) {
|
|
119
184
|
throw new Error(
|
|
@@ -121,26 +186,15 @@ var ViemBundlerClient = class {
|
|
|
121
186
|
);
|
|
122
187
|
}
|
|
123
188
|
/**
|
|
124
|
-
* Sends a user operation to the bundler.
|
|
189
|
+
* Sends a signed user operation to the bundler via raw eth_sendUserOperation RPC.
|
|
125
190
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* @returns Promise resolving to the user operation hash
|
|
191
|
+
* Bypasses viem's middleware to avoid re-calling paymaster RPCs which would
|
|
192
|
+
* change paymaster fields and invalidate the signature.
|
|
129
193
|
*/
|
|
130
|
-
async sendUserOperation(userOp,
|
|
131
|
-
const hash = await this.bundlerClient.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
nonce: BigInt(userOp.nonce),
|
|
135
|
-
callData: userOp.callData,
|
|
136
|
-
callGasLimit: BigInt(userOp.callGasLimit),
|
|
137
|
-
verificationGasLimit: BigInt(userOp.verificationGasLimit),
|
|
138
|
-
preVerificationGas: BigInt(userOp.preVerificationGas),
|
|
139
|
-
maxFeePerGas: BigInt(userOp.maxFeePerGas),
|
|
140
|
-
maxPriorityFeePerGas: BigInt(userOp.maxPriorityFeePerGas),
|
|
141
|
-
// Combine paymaster and paymasterData into paymasterAndData
|
|
142
|
-
paymasterAndData: userOp.paymaster && userOp.paymasterData ? userOp.paymaster + userOp.paymasterData.slice(2) : userOp.paymaster ? userOp.paymaster : "0x",
|
|
143
|
-
signature: userOp.signature
|
|
194
|
+
async sendUserOperation(userOp, entryPoint) {
|
|
195
|
+
const hash = await this.bundlerClient.request({
|
|
196
|
+
method: "eth_sendUserOperation",
|
|
197
|
+
params: [userOp, entryPoint]
|
|
144
198
|
});
|
|
145
199
|
return hash;
|
|
146
200
|
}
|
|
@@ -253,6 +307,7 @@ function userOpToJson(userOp) {
|
|
|
253
307
|
const json = {};
|
|
254
308
|
for (const [key, value] of Object.entries(userOp)) {
|
|
255
309
|
if (key === "account") continue;
|
|
310
|
+
if (value === void 0) continue;
|
|
256
311
|
if (typeof value === "bigint") {
|
|
257
312
|
json[key] = toRpcHex(value);
|
|
258
313
|
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
@@ -443,7 +498,7 @@ function createDefaultPublicClient(network) {
|
|
|
443
498
|
transport: (0, import_viem4.http)()
|
|
444
499
|
});
|
|
445
500
|
}
|
|
446
|
-
var ExactEvmSchemeERC4337 = class {
|
|
501
|
+
var ExactEvmSchemeERC4337 = class _ExactEvmSchemeERC4337 {
|
|
447
502
|
/**
|
|
448
503
|
* Creates a new ExactEvmSchemeERC4337 instance.
|
|
449
504
|
*
|
|
@@ -458,6 +513,7 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
458
513
|
this.publicClient = config.publicClient;
|
|
459
514
|
this.entrypoint = config.entrypoint;
|
|
460
515
|
this.bundlerUrl = config.bundlerUrl;
|
|
516
|
+
this.paymaster = config.paymaster;
|
|
461
517
|
if (!this.bundlerClient && !this.account) {
|
|
462
518
|
throw new Error(
|
|
463
519
|
"Either bundlerClient or account must be provided. If bundlerClient is not provided, account (SmartAccount) is required for dynamic bundlerClient creation."
|
|
@@ -479,24 +535,14 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
479
535
|
}
|
|
480
536
|
}
|
|
481
537
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
* This method:
|
|
485
|
-
* 1. Extracts user operation capability from payment requirements
|
|
486
|
-
* 2. Creates bundlerClient dynamically if not provided (when userOperation.supported is true)
|
|
487
|
-
* 3. Builds ERC20 transfer call data
|
|
488
|
-
* 4. Prepares the user operation using the bundler client
|
|
489
|
-
* 5. Signs the user operation
|
|
490
|
-
* 6. Converts to JSON-RPC format
|
|
491
|
-
* 7. Returns the x402 payment payload
|
|
492
|
-
*
|
|
493
|
-
* @param x402Version - The x402 protocol version
|
|
494
|
-
* @param paymentRequirements - The payment requirements
|
|
495
|
-
* @returns Promise resolving to a payment payload
|
|
496
|
-
* @throws Error if user operation capability is not found or required fields are missing
|
|
538
|
+
* Prepares an unsigned payment payload (UserOp) without signing.
|
|
539
|
+
* Use with `completePaymentPayload()` to attach a signature from any surface.
|
|
497
540
|
*/
|
|
498
|
-
async
|
|
541
|
+
async preparePaymentPayload(x402Version, paymentRequirements) {
|
|
499
542
|
const capability = extractUserOperationCapability(paymentRequirements);
|
|
543
|
+
const chain = resolveChain(paymentRequirements.network);
|
|
544
|
+
const configBundlerUrl = typeof this.bundlerUrl === "function" ? this.bundlerUrl(chain.id, paymentRequirements.network) : this.bundlerUrl;
|
|
545
|
+
const bundlerUrl = configBundlerUrl ?? capability?.bundlerUrl;
|
|
500
546
|
let bundlerClient;
|
|
501
547
|
if (this.bundlerClient) {
|
|
502
548
|
bundlerClient = this.bundlerClient;
|
|
@@ -506,8 +552,7 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
506
552
|
"Account (SmartAccount) is required when bundlerClient is not provided. Either provide bundlerClient in config or account for dynamic creation."
|
|
507
553
|
);
|
|
508
554
|
}
|
|
509
|
-
|
|
510
|
-
if (!bundlerUrl2) {
|
|
555
|
+
if (!bundlerUrl) {
|
|
511
556
|
throw new PaymentCreationError(
|
|
512
557
|
"Bundler URL not provided",
|
|
513
558
|
{
|
|
@@ -517,13 +562,14 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
517
562
|
}
|
|
518
563
|
);
|
|
519
564
|
}
|
|
520
|
-
const chain = resolveChain(paymentRequirements.network);
|
|
521
565
|
const publicClient = this.publicClient ?? createDefaultPublicClient(paymentRequirements.network);
|
|
566
|
+
const paymaster = this.paymaster ?? true;
|
|
522
567
|
bundlerClient = new ViemBundlerClient({
|
|
523
568
|
publicClient,
|
|
524
569
|
account: this.account,
|
|
525
570
|
chain,
|
|
526
|
-
bundlerUrl
|
|
571
|
+
bundlerUrl,
|
|
572
|
+
paymaster
|
|
527
573
|
});
|
|
528
574
|
}
|
|
529
575
|
const entryPoint = this.entrypoint ?? capability?.entrypoint;
|
|
@@ -537,7 +583,6 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
537
583
|
}
|
|
538
584
|
);
|
|
539
585
|
}
|
|
540
|
-
const bundlerUrl = this.bundlerUrl ?? capability?.bundlerUrl;
|
|
541
586
|
if (!bundlerUrl) {
|
|
542
587
|
throw new PaymentCreationError(
|
|
543
588
|
"Bundler URL not provided",
|
|
@@ -563,7 +608,6 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
563
608
|
{
|
|
564
609
|
to: token,
|
|
565
610
|
value: BigInt(0),
|
|
566
|
-
// ERC20 transfers don't send ETH
|
|
567
611
|
data: callData
|
|
568
612
|
}
|
|
569
613
|
],
|
|
@@ -582,9 +626,43 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
582
626
|
}
|
|
583
627
|
);
|
|
584
628
|
}
|
|
629
|
+
return {
|
|
630
|
+
unsignedUserOp,
|
|
631
|
+
bundlerClient,
|
|
632
|
+
entryPoint,
|
|
633
|
+
bundlerUrl,
|
|
634
|
+
x402Version,
|
|
635
|
+
network: paymentRequirements.network,
|
|
636
|
+
signer: this.signer
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Assembles a signed payment payload from a prepared (unsigned) UserOp and a signature.
|
|
641
|
+
*/
|
|
642
|
+
static completePaymentPayload(prepared, signature) {
|
|
643
|
+
const signedUserOp = { ...prepared.unsignedUserOp, signature };
|
|
644
|
+
const jsonUserOp = userOpToJson(signedUserOp);
|
|
645
|
+
const payload = {
|
|
646
|
+
type: "erc4337",
|
|
647
|
+
entryPoint: prepared.entryPoint,
|
|
648
|
+
bundlerRpcUrl: prepared.bundlerUrl,
|
|
649
|
+
userOperation: jsonUserOp
|
|
650
|
+
};
|
|
651
|
+
return {
|
|
652
|
+
x402Version: prepared.x402Version,
|
|
653
|
+
...prepared.x402Version === 1 ? { scheme: "exact", network: prepared.network } : {},
|
|
654
|
+
payload
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Creates a payment payload for the Exact scheme using ERC-4337 UserOperations.
|
|
659
|
+
* Convenience method that calls `preparePaymentPayload` + signs + `completePaymentPayload`.
|
|
660
|
+
*/
|
|
661
|
+
async createPaymentPayload(x402Version, paymentRequirements) {
|
|
662
|
+
const prepared = await this.preparePaymentPayload(x402Version, paymentRequirements);
|
|
585
663
|
let signature;
|
|
586
664
|
try {
|
|
587
|
-
signature = await this.signer.signUserOperation(unsignedUserOp);
|
|
665
|
+
signature = await this.signer.signUserOperation(prepared.unsignedUserOp);
|
|
588
666
|
} catch (error) {
|
|
589
667
|
const aaError = parseAAError(error);
|
|
590
668
|
throw new PaymentCreationError(
|
|
@@ -598,23 +676,7 @@ var ExactEvmSchemeERC4337 = class {
|
|
|
598
676
|
}
|
|
599
677
|
);
|
|
600
678
|
}
|
|
601
|
-
|
|
602
|
-
...unsignedUserOp,
|
|
603
|
-
signature
|
|
604
|
-
};
|
|
605
|
-
const jsonUserOp = userOpToJson(signedUserOp);
|
|
606
|
-
const payload = {
|
|
607
|
-
type: "erc4337",
|
|
608
|
-
entryPoint,
|
|
609
|
-
bundlerRpcUrl: bundlerUrl,
|
|
610
|
-
userOperation: jsonUserOp
|
|
611
|
-
};
|
|
612
|
-
return {
|
|
613
|
-
x402Version,
|
|
614
|
-
// v1 requires scheme and network at top level
|
|
615
|
-
...x402Version === 1 ? { scheme: this.scheme, network: paymentRequirements.network } : {},
|
|
616
|
-
payload
|
|
617
|
-
};
|
|
679
|
+
return _ExactEvmSchemeERC4337.completePaymentPayload(prepared, signature);
|
|
618
680
|
}
|
|
619
681
|
};
|
|
620
682
|
|