@introspectivelabs/x402-evm 0.0.1

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.
Files changed (38) hide show
  1. package/README.md +16 -0
  2. package/dist/cjs/exact/client/index.d.ts +48 -0
  3. package/dist/cjs/exact/client/index.js +403 -0
  4. package/dist/cjs/exact/client/index.js.map +1 -0
  5. package/dist/cjs/exact/facilitator/index.d.ts +224 -0
  6. package/dist/cjs/exact/facilitator/index.js +355 -0
  7. package/dist/cjs/exact/facilitator/index.js.map +1 -0
  8. package/dist/cjs/exact/server/index.d.ts +47 -0
  9. package/dist/cjs/exact/server/index.js +86 -0
  10. package/dist/cjs/exact/server/index.js.map +1 -0
  11. package/dist/cjs/index.d.ts +71 -0
  12. package/dist/cjs/index.js +860 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/types-Dk5U6Xnw.d.ts +33 -0
  15. package/dist/cjs/userOperation-Dh1zucfd.d.ts +409 -0
  16. package/dist/esm/chunk-56L4QUDN.mjs +359 -0
  17. package/dist/esm/chunk-56L4QUDN.mjs.map +1 -0
  18. package/dist/esm/chunk-5HWFMQYG.mjs +328 -0
  19. package/dist/esm/chunk-5HWFMQYG.mjs.map +1 -0
  20. package/dist/esm/chunk-E3XDJP7M.mjs +53 -0
  21. package/dist/esm/chunk-E3XDJP7M.mjs.map +1 -0
  22. package/dist/esm/chunk-GGPRPAM4.mjs +13 -0
  23. package/dist/esm/chunk-GGPRPAM4.mjs.map +1 -0
  24. package/dist/esm/exact/client/index.d.mts +48 -0
  25. package/dist/esm/exact/client/index.mjs +18 -0
  26. package/dist/esm/exact/client/index.mjs.map +1 -0
  27. package/dist/esm/exact/facilitator/index.d.mts +224 -0
  28. package/dist/esm/exact/facilitator/index.mjs +9 -0
  29. package/dist/esm/exact/facilitator/index.mjs.map +1 -0
  30. package/dist/esm/exact/server/index.d.mts +47 -0
  31. package/dist/esm/exact/server/index.mjs +8 -0
  32. package/dist/esm/exact/server/index.mjs.map +1 -0
  33. package/dist/esm/index.d.mts +71 -0
  34. package/dist/esm/index.mjs +110 -0
  35. package/dist/esm/index.mjs.map +1 -0
  36. package/dist/esm/types-Dk5U6Xnw.d.mts +33 -0
  37. package/dist/esm/userOperation-B2UUp3K6.d.mts +409 -0
  38. package/package.json +107 -0
package/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # @introspectivelabs/x402-evm
2
+
3
+ EVM (Ethereum Virtual Machine) implementation of the x402 payment protocol using the **Exact** payment scheme with EIP-3009 TransferWithAuthorization.
4
+
5
+ ## Installation
6
+ This package depends of `@x402/core` and `@x402/evm` you must install it in your project
7
+
8
+ ```bash
9
+ npm install @introspectivelabs/x402-evm
10
+ ```
11
+
12
+ ## Overview
13
+
14
+ This package provides three main components for handling x402 payments on EVM-compatible blockchains and Smart Wallets:
15
+
16
+ - **Server** - For resource servers that accept payments and build payment requirements
@@ -0,0 +1,48 @@
1
+ import { U as UserOperationSigner, P as PreparedUserOperation } from '../../userOperation-Dh1zucfd.js';
2
+ export { B as BundlerClient, b as BundlerClientConfig, f as ERC20_TRANSFER_ABI, E as ExactEvmSchemeERC4337, a as ExactEvmSchemeERC4337Config, G as GasEstimate, c as UserOperationCall, V as ViemBundlerClient, d as ViemBundlerClientConfig, e as buildERC20TransferCallData, u as userOpToJson } from '../../userOperation-Dh1zucfd.js';
3
+ import { SmartAccount } from 'viem/account-abstraction';
4
+ import 'viem';
5
+ import '../../types-Dk5U6Xnw.js';
6
+ import '@x402/core/types';
7
+
8
+ /**
9
+ * Adapter to make a SmartAccount (e.g., Safe account) work as a UserOperationSigner.
10
+ *
11
+ * This class wraps a SmartAccount that supports `signUserOperation` and adapts it
12
+ * to the UserOperationSigner interface required by the x402 ERC-4337 scheme.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { SafeAccountSigner } from "@introspectivelabs/x402-evm/exact/client";
17
+ * import { toSafeSmartAccount } from "permissionless/accounts";
18
+ *
19
+ * const safeAccount = await toSafeSmartAccount({ ... });
20
+ * const signer = new SafeAccountSigner(safeAccount);
21
+ *
22
+ * const scheme = new ExactEvmSchemeERC4337({
23
+ * bundlerClient,
24
+ * signer,
25
+ * });
26
+ * ```
27
+ */
28
+ declare class SafeAccountSigner implements UserOperationSigner {
29
+ private readonly account;
30
+ readonly address: `0x${string}`;
31
+ /**
32
+ * Creates a new SafeAccountSigner instance.
33
+ *
34
+ * @param account - The SmartAccount instance (e.g., from permissionless/accounts)
35
+ * @throws Error if the account is not initialized or missing an address
36
+ */
37
+ constructor(account: SmartAccount);
38
+ /**
39
+ * Signs a prepared (unsigned) user operation.
40
+ *
41
+ * @param userOp - The prepared user operation to sign
42
+ * @returns Promise resolving to the signature
43
+ * @throws Error if the account does not support signUserOperation
44
+ */
45
+ signUserOperation(userOp: PreparedUserOperation): Promise<`0x${string}`>;
46
+ }
47
+
48
+ export { PreparedUserOperation, SafeAccountSigner, UserOperationSigner };
@@ -0,0 +1,403 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/exact/client/index.ts
31
+ var client_exports = {};
32
+ __export(client_exports, {
33
+ ERC20_TRANSFER_ABI: () => ERC20_TRANSFER_ABI,
34
+ ExactEvmSchemeERC4337: () => ExactEvmSchemeERC4337,
35
+ SafeAccountSigner: () => SafeAccountSigner,
36
+ ViemBundlerClient: () => ViemBundlerClient,
37
+ buildERC20TransferCallData: () => buildERC20TransferCallData,
38
+ userOpToJson: () => userOpToJson
39
+ });
40
+ module.exports = __toCommonJS(client_exports);
41
+
42
+ // src/exact/client/scheme.ts
43
+ var import_viem3 = require("viem");
44
+ var allChains = __toESM(require("viem/chains"));
45
+ var import_viem4 = require("viem");
46
+
47
+ // src/exact/client/bundler/viem.ts
48
+ var import_viem = require("viem");
49
+ var import_account_abstraction = require("viem/account-abstraction");
50
+ var ViemBundlerClient = class {
51
+ /**
52
+ * Creates a new ViemBundlerClient instance.
53
+ *
54
+ * @param config - Configuration for the bundler client
55
+ */
56
+ constructor(config) {
57
+ this.account = config.account;
58
+ this.entryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";
59
+ this.bundlerClient = (0, import_account_abstraction.createBundlerClient)({
60
+ client: config.publicClient,
61
+ chain: config.chain,
62
+ account: config.account,
63
+ transport: (0, import_viem.http)(config.bundlerUrl)
64
+ });
65
+ }
66
+ /**
67
+ * Prepares an unsigned user operation for the given calls.
68
+ *
69
+ * @param calls - Array of calls to execute in the user operation
70
+ * @param _entryPoint - The entry point address (unused, viem uses the configured entry point)
71
+ * @returns Promise resolving to a prepared (unsigned) user operation
72
+ */
73
+ async prepareUserOperation(calls, _entryPoint) {
74
+ const prepared = await this.bundlerClient.prepareUserOperation({
75
+ account: this.account,
76
+ calls: calls.map((call) => ({
77
+ to: call.to,
78
+ value: call.value,
79
+ data: call.data
80
+ }))
81
+ });
82
+ return {
83
+ sender: prepared.sender,
84
+ nonce: prepared.nonce,
85
+ callData: prepared.callData,
86
+ callGasLimit: prepared.callGasLimit,
87
+ verificationGasLimit: prepared.verificationGasLimit,
88
+ preVerificationGas: prepared.preVerificationGas,
89
+ maxFeePerGas: prepared.maxFeePerGas,
90
+ maxPriorityFeePerGas: prepared.maxPriorityFeePerGas,
91
+ // viem uses paymasterAndData instead of separate paymaster/paymasterData
92
+ paymaster: prepared.paymasterAndData?.slice(
93
+ 0,
94
+ 42
95
+ ),
96
+ paymasterData: prepared.paymasterAndData?.slice(
97
+ 42
98
+ ),
99
+ paymasterVerificationGasLimit: prepared.paymasterVerificationGasLimit,
100
+ paymasterPostOpGasLimit: prepared.paymasterPostOpGasLimit,
101
+ signature: prepared.signature
102
+ };
103
+ }
104
+ /**
105
+ * Estimates gas for a user operation.
106
+ * Note: This is typically done as part of prepareUserOperation,
107
+ * but is available as a separate method for flexibility.
108
+ *
109
+ * @param _userOp - The user operation to estimate gas for
110
+ * @param _entryPoint - The entry point address
111
+ * @returns Promise resolving to gas estimates
112
+ */
113
+ async estimateGas(_userOp, _entryPoint) {
114
+ throw new Error(
115
+ "estimateGas should be called through prepareUserOperation, which includes gas estimation"
116
+ );
117
+ }
118
+ /**
119
+ * Sends a user operation to the bundler.
120
+ *
121
+ * @param userOp - The signed user operation to send
122
+ * @param _entryPoint - The entry point address (unused, viem uses the configured entry point)
123
+ * @returns Promise resolving to the user operation hash
124
+ */
125
+ async sendUserOperation(userOp, _entryPoint) {
126
+ const hash = await this.bundlerClient.sendUserOperation({
127
+ account: this.account,
128
+ sender: userOp.sender,
129
+ nonce: BigInt(userOp.nonce),
130
+ callData: userOp.callData,
131
+ callGasLimit: BigInt(userOp.callGasLimit),
132
+ verificationGasLimit: BigInt(userOp.verificationGasLimit),
133
+ preVerificationGas: BigInt(userOp.preVerificationGas),
134
+ maxFeePerGas: BigInt(userOp.maxFeePerGas),
135
+ maxPriorityFeePerGas: BigInt(userOp.maxPriorityFeePerGas),
136
+ // Combine paymaster and paymasterData into paymasterAndData
137
+ paymasterAndData: userOp.paymaster && userOp.paymasterData ? userOp.paymaster + userOp.paymasterData.slice(2) : userOp.paymaster ? userOp.paymaster : "0x",
138
+ signature: userOp.signature
139
+ });
140
+ return hash;
141
+ }
142
+ };
143
+
144
+ // src/exact/client/signer/safeAccountSigner.ts
145
+ var SafeAccountSigner = class {
146
+ /**
147
+ * Creates a new SafeAccountSigner instance.
148
+ *
149
+ * @param account - The SmartAccount instance (e.g., from permissionless/accounts)
150
+ * @throws Error if the account is not initialized or missing an address
151
+ */
152
+ constructor(account) {
153
+ this.account = account;
154
+ if (!account?.address) {
155
+ throw new Error("Smart account not initialized");
156
+ }
157
+ this.address = account.address;
158
+ }
159
+ /**
160
+ * Signs a prepared (unsigned) user operation.
161
+ *
162
+ * @param userOp - The prepared user operation to sign
163
+ * @returns Promise resolving to the signature
164
+ * @throws Error if the account does not support signUserOperation
165
+ */
166
+ async signUserOperation(userOp) {
167
+ if (!this.account?.signUserOperation) {
168
+ throw new Error("Smart account does not support signUserOperation");
169
+ }
170
+ return await this.account.signUserOperation(userOp);
171
+ }
172
+ };
173
+
174
+ // src/exact/utils.ts
175
+ function extractUserOperationCapability(requirements) {
176
+ const userOpExtra = requirements.extra?.userOperation;
177
+ if (userOpExtra && typeof userOpExtra === "object" && "supported" in userOpExtra && userOpExtra.supported === true) {
178
+ return userOpExtra;
179
+ }
180
+ return void 0;
181
+ }
182
+
183
+ // src/exact/client/utils/callData.ts
184
+ var import_viem2 = require("viem");
185
+ var ERC20_TRANSFER_ABI = [
186
+ {
187
+ type: "function",
188
+ name: "transfer",
189
+ stateMutability: "nonpayable",
190
+ inputs: [
191
+ { name: "to", type: "address" },
192
+ { name: "amount", type: "uint256" }
193
+ ],
194
+ outputs: [{ name: "success", type: "bool" }]
195
+ }
196
+ ];
197
+ function buildERC20TransferCallData(token, to, amount) {
198
+ return (0, import_viem2.encodeFunctionData)({
199
+ abi: ERC20_TRANSFER_ABI,
200
+ functionName: "transfer",
201
+ args: [to, amount]
202
+ });
203
+ }
204
+
205
+ // src/exact/client/utils/userOperation.ts
206
+ function toRpcHex(value) {
207
+ return `0x${value.toString(16)}`;
208
+ }
209
+ function userOpToJson(userOp) {
210
+ const json = {};
211
+ for (const [key, value] of Object.entries(userOp)) {
212
+ if (key === "account") continue;
213
+ if (typeof value === "bigint") {
214
+ json[key] = toRpcHex(value);
215
+ } else if (value && typeof value === "object" && !Array.isArray(value)) {
216
+ const inner = {};
217
+ for (const [k, v] of Object.entries(value)) {
218
+ inner[k] = typeof v === "bigint" ? toRpcHex(v) : v;
219
+ }
220
+ json[key] = inner;
221
+ } else {
222
+ json[key] = value;
223
+ }
224
+ }
225
+ return json;
226
+ }
227
+
228
+ // src/exact/client/scheme.ts
229
+ function getChainFromNetwork(network) {
230
+ if (!network.startsWith("eip155:")) {
231
+ throw new Error(
232
+ `Unsupported network format: ${network}. Expected CAIP-2 format (eip155:chainId)`
233
+ );
234
+ }
235
+ const chainIdStr = network.split(":")[1];
236
+ const chainId = parseInt(chainIdStr, 10);
237
+ if (isNaN(chainId)) {
238
+ throw new Error(`Invalid chain ID in network: ${network}`);
239
+ }
240
+ const knownChain = Object.values(allChains).find((c) => c.id === chainId);
241
+ if (knownChain) {
242
+ return knownChain;
243
+ }
244
+ return (0, import_viem4.defineChain)({
245
+ id: chainId,
246
+ name: `Chain ${chainId}`,
247
+ nativeCurrency: {
248
+ name: "Ether",
249
+ symbol: "ETH",
250
+ decimals: 18
251
+ },
252
+ rpcUrls: {
253
+ default: {
254
+ http: []
255
+ }
256
+ }
257
+ });
258
+ }
259
+ function createDefaultPublicClient(network) {
260
+ const chain = getChainFromNetwork(network);
261
+ return (0, import_viem3.createPublicClient)({
262
+ chain,
263
+ transport: (0, import_viem3.http)()
264
+ });
265
+ }
266
+ var ExactEvmSchemeERC4337 = class {
267
+ /**
268
+ * Creates a new ExactEvmSchemeERC4337 instance.
269
+ *
270
+ * @param config - Configuration for the scheme (type-safe: either bundlerClient or account must be provided)
271
+ * @throws Error if bundlerClient is not provided and account is also not provided (runtime safety check)
272
+ * @throws Error if signer is not provided and account doesn't support signUserOperation
273
+ */
274
+ constructor(config) {
275
+ this.scheme = "exact";
276
+ this.bundlerClient = config.bundlerClient;
277
+ this.account = config.account;
278
+ this.publicClient = config.publicClient;
279
+ this.entrypoint = config.entrypoint;
280
+ this.bundlerUrl = config.bundlerUrl;
281
+ if (!this.bundlerClient && !this.account) {
282
+ throw new Error(
283
+ "Either bundlerClient or account must be provided. If bundlerClient is not provided, account (SmartAccount) is required for dynamic bundlerClient creation."
284
+ );
285
+ }
286
+ if (config.signer) {
287
+ this.signer = config.signer;
288
+ } else if (this.account) {
289
+ if (!this.account.signUserOperation) {
290
+ throw new Error(
291
+ "Account does not support signUserOperation. Either provide a signer explicitly or use an account that supports signUserOperation."
292
+ );
293
+ }
294
+ this.signer = new SafeAccountSigner(this.account);
295
+ } else {
296
+ throw new Error(
297
+ "Signer is required when bundlerClient is provided. Either provide a signer explicitly or use account-based configuration."
298
+ );
299
+ }
300
+ }
301
+ /**
302
+ * Creates a payment payload for the Exact scheme using ERC-4337 UserOperations.
303
+ *
304
+ * This method:
305
+ * 1. Extracts user operation capability from payment requirements
306
+ * 2. Creates bundlerClient dynamically if not provided (when userOperation.supported is true)
307
+ * 3. Builds ERC20 transfer call data
308
+ * 4. Prepares the user operation using the bundler client
309
+ * 5. Signs the user operation
310
+ * 6. Converts to JSON-RPC format
311
+ * 7. Returns the x402 payment payload
312
+ *
313
+ * @param x402Version - The x402 protocol version
314
+ * @param paymentRequirements - The payment requirements
315
+ * @returns Promise resolving to a payment payload
316
+ * @throws Error if user operation capability is not found or required fields are missing
317
+ */
318
+ async createPaymentPayload(x402Version, paymentRequirements) {
319
+ const capability = extractUserOperationCapability(paymentRequirements);
320
+ if (!capability) {
321
+ throw new Error(
322
+ `UserOperation capability not found in payment requirements for asset ${paymentRequirements.asset}. The server must announce UserOperation support in the requirements.`
323
+ );
324
+ }
325
+ let bundlerClient;
326
+ if (this.bundlerClient) {
327
+ bundlerClient = this.bundlerClient;
328
+ } else {
329
+ if (!this.account) {
330
+ throw new Error(
331
+ "Account (SmartAccount) is required when bundlerClient is not provided. Either provide bundlerClient in config or account for dynamic creation."
332
+ );
333
+ }
334
+ const bundlerUrl2 = this.bundlerUrl ?? capability.bundlerUrl;
335
+ if (!bundlerUrl2) {
336
+ throw new Error(
337
+ "Bundler URL not provided. Set it in ExactEvmSchemeERC4337Config.defaultBundlerUrl or in payment requirements extra.userOperation.bundlerUrl"
338
+ );
339
+ }
340
+ const chain = getChainFromNetwork(paymentRequirements.network);
341
+ const publicClient = this.publicClient ?? createDefaultPublicClient(paymentRequirements.network);
342
+ bundlerClient = new ViemBundlerClient({
343
+ publicClient,
344
+ account: this.account,
345
+ chain,
346
+ bundlerUrl: bundlerUrl2
347
+ });
348
+ }
349
+ const entryPoint = this.entrypoint ?? capability.entrypoint;
350
+ if (!entryPoint) {
351
+ throw new Error(
352
+ "Entry point not provided. Set it in ExactEvmSchemeERC4337Config.entrypoint when payment requirements extra.userOperation.entrypoint is not provided"
353
+ );
354
+ }
355
+ const bundlerUrl = this.bundlerUrl ?? capability.bundlerUrl;
356
+ if (!bundlerUrl) {
357
+ throw new Error(
358
+ "Bundler URL not provided. Set it in ExactEvmSchemeERC4337Config.defaultBundlerUrl or in payment requirements extra.userOperation.bundlerUrl"
359
+ );
360
+ }
361
+ const token = (0, import_viem3.getAddress)(paymentRequirements.asset);
362
+ const payTo = (0, import_viem3.getAddress)(paymentRequirements.payTo);
363
+ const amount = BigInt(paymentRequirements.amount);
364
+ const callData = buildERC20TransferCallData(token, payTo, amount);
365
+ const unsignedUserOp = await bundlerClient.prepareUserOperation(
366
+ [
367
+ {
368
+ to: token,
369
+ value: BigInt(0),
370
+ // ERC20 transfers don't send ETH
371
+ data: callData
372
+ }
373
+ ],
374
+ entryPoint
375
+ );
376
+ const signature = await this.signer.signUserOperation(unsignedUserOp);
377
+ const signedUserOp = {
378
+ ...unsignedUserOp,
379
+ signature
380
+ };
381
+ const jsonUserOp = userOpToJson(signedUserOp);
382
+ const payload = {
383
+ type: "erc4337",
384
+ entryPoint,
385
+ bundlerRpcUrl: bundlerUrl,
386
+ userOperation: jsonUserOp
387
+ };
388
+ return {
389
+ x402Version,
390
+ payload
391
+ };
392
+ }
393
+ };
394
+ // Annotate the CommonJS export names for ESM import in node:
395
+ 0 && (module.exports = {
396
+ ERC20_TRANSFER_ABI,
397
+ ExactEvmSchemeERC4337,
398
+ SafeAccountSigner,
399
+ ViemBundlerClient,
400
+ buildERC20TransferCallData,
401
+ userOpToJson
402
+ });
403
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/exact/client/index.ts","../../../../src/exact/client/scheme.ts","../../../../src/exact/client/bundler/viem.ts","../../../../src/exact/client/signer/safeAccountSigner.ts","../../../../src/exact/utils.ts","../../../../src/exact/client/utils/callData.ts","../../../../src/exact/client/utils/userOperation.ts"],"sourcesContent":["export { ExactEvmSchemeERC4337 } from \"./scheme\";\nexport type { ExactEvmSchemeERC4337Config } from \"./scheme\";\nexport * from \"./bundler\";\nexport * from \"./signer\";\nexport * from \"./utils\";\n","import type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@x402/core/types\";\nimport {\n getAddress,\n createPublicClient,\n http,\n type Chain,\n type PublicClient,\n type Transport,\n Hex,\n} from \"viem\";\nimport * as allChains from \"viem/chains\";\nimport { defineChain } from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport type { BundlerClient } from \"./bundler\";\nimport { ViemBundlerClient } from \"./bundler/viem\";\nimport type { UserOperationSigner } from \"./signer\";\nimport { SafeAccountSigner } from \"./signer\";\nimport { extractUserOperationCapability } from \"../utils\";\nimport type { Erc4337Payload } from \"../facilitator/types\";\nimport { buildERC20TransferCallData } from \"./utils/callData\";\nimport { userOpToJson } from \"./utils/userOperation\";\n\n/**\n * Base configuration properties shared by all configuration variants\n */\ninterface ExactEvmSchemeERC4337ConfigBase {\n /**\n * Entry point address (EntryPoint v0.7)\n * Optional - can be provided in payment requirements if not set here\n */\n entrypoint?: Hex;\n\n /**\n * Bundler URL (optional, can be provided in payment requirements)\n */\n bundlerUrl?: string;\n}\n\n/**\n * Configuration variant when bundlerClient is explicitly provided.\n * Account and publicClient are NOT needed when bundlerClient is used.\n * Signer is required when using bundlerClient.\n */\ntype ExactEvmSchemeERC4337ConfigWithBundler = ExactEvmSchemeERC4337ConfigBase & {\n /**\n * Bundler client for preparing and sending user operations.\n */\n bundlerClient: BundlerClient;\n /**\n * Signer for signing user operations (required when bundlerClient is provided).\n */\n signer: UserOperationSigner;\n} & {\n /**\n * Account must not be provided when bundlerClient is used.\n * Using `never` type prevents this property from being set.\n */\n account?: never;\n /**\n * Public client must not be provided when bundlerClient is used.\n * The bundlerClient already has its own publicClient configured.\n */\n publicClient?: never;\n};\n\n/**\n * Configuration variant when bundlerClient is not provided.\n * Account is required for dynamic bundlerClient creation.\n * Signer is optional - will be auto-created from account if not provided.\n * PublicClient is optional - will create a default from network if not provided.\n */\ntype ExactEvmSchemeERC4337ConfigWithAccount = ExactEvmSchemeERC4337ConfigBase & {\n /**\n * Bundler client is not provided - will be created dynamically from PaymentRequirements.\n * Using `never` type prevents this property from being set.\n */\n bundlerClient?: never;\n} & {\n /**\n * Smart account for user operation preparation.\n * Required when bundlerClient is not provided.\n */\n account: SmartAccount;\n /**\n * Signer for signing user operations.\n * Optional - will be auto-created from account using SafeAccountSigner if not provided.\n * The account must support signUserOperation method for auto-creation to work.\n */\n signer?: UserOperationSigner;\n /**\n * Public client for blockchain interactions.\n * Optional - will create a default from network if not provided.\n */\n publicClient?: PublicClient<Transport, Chain>;\n};\n\n/**\n * Configuration for the ERC-4337 client scheme.\n *\n * This is a discriminated union that enforces type-safe combinations:\n * - Either `bundlerClient` is provided (account and publicClient must NOT be provided)\n * - Or `account` is provided when bundlerClient is not (for dynamic creation, publicClient optional)\n *\n * @example\n * ```typescript\n * // Minimal config (just account - signer auto-created)\n * const scheme1 = new ExactEvmSchemeERC4337({\n * account: myAccount,\n * // signer will be auto-created from account\n * // bundlerClient will be created dynamically from PaymentRequirements\n * });\n *\n * // With account and custom signer\n * const scheme2 = new ExactEvmSchemeERC4337({\n * account: myAccount,\n * signer: myCustomSigner,\n * publicClient: myPublicClient, // Optional\n * });\n *\n * // With explicit bundlerClient (backward compatible)\n * const scheme3 = new ExactEvmSchemeERC4337({\n * bundlerClient: myBundlerClient,\n * signer: mySigner, // Required when bundlerClient is provided\n * // account and publicClient must NOT be provided (bundlerClient has its own)\n * });\n * ```\n */\nexport type ExactEvmSchemeERC4337Config =\n | ExactEvmSchemeERC4337ConfigWithBundler\n | ExactEvmSchemeERC4337ConfigWithAccount;\n\n/**\n * Gets a Chain object from a network string (CAIP-2 format).\n * Parses chainId from \"eip155:84532\" format and finds matching chain from viem's allChains,\n * or creates a custom chain using defineChain for unknown chains.\n *\n * @param network - The network string in CAIP-2 format (e.g., \"eip155:84532\")\n * @returns The Chain object\n */\nfunction getChainFromNetwork(network: string): Chain {\n if (!network.startsWith(\"eip155:\")) {\n throw new Error(\n `Unsupported network format: ${network}. Expected CAIP-2 format (eip155:chainId)`,\n );\n }\n\n const chainIdStr = network.split(\":\")[1];\n const chainId = parseInt(chainIdStr, 10);\n\n if (isNaN(chainId)) {\n throw new Error(`Invalid chain ID in network: ${network}`);\n }\n\n // Try to find chain in viem's allChains\n const knownChain = Object.values(allChains).find((c: Chain) => c.id === chainId);\n if (knownChain) {\n return knownChain;\n }\n\n // Create a minimal chain definition for unknown chains\n return defineChain({\n id: chainId,\n name: `Chain ${chainId}`,\n nativeCurrency: {\n name: \"Ether\",\n symbol: \"ETH\",\n decimals: 18,\n },\n rpcUrls: {\n default: {\n http: [],\n },\n },\n });\n}\n\n/**\n * Creates a default public client from a network string.\n *\n * @param network - The network string in CAIP-2 format (e.g., \"eip155:84532\")\n * @returns A PublicClient instance\n */\nfunction createDefaultPublicClient(network: string): PublicClient<Transport, Chain> {\n const chain = getChainFromNetwork(network);\n return createPublicClient({\n chain,\n transport: http(),\n });\n}\n\n/**\n * EVM client implementation for the Exact payment scheme using ERC-4337 UserOperations.\n *\n * This implementation creates payment payloads by building and signing UserOperations\n * that execute ERC20 transfers. The UserOperations are prepared using a bundler client\n * and signed using a user operation signer (e.g., Safe account, EOA).\n *\n * Supports minimal configuration: when bundlerClient is not provided and\n * PaymentRequirements.extra.userOperation.supported is true, a ViemBundlerClient\n * will be created dynamically from the payment requirements.\n *\n * @example\n * ```typescript\n * // Minimal config (just account - signer and bundlerClient auto-created)\n * import { ExactEvmSchemeERC4337 } from '@introspectivelabs/x402-evm/exact/client';\n * import { x402Client } from '@x402/core/client';\n *\n * const scheme = new ExactEvmSchemeERC4337({\n * account: safeAccount, // SmartAccount - signer will be auto-created\n * });\n *\n * // With custom signer\n * const scheme2 = new ExactEvmSchemeERC4337({\n * account: safeAccount,\n * signer: customSigner, // Optional - overrides auto-creation\n * });\n *\n * // Explicit config (backward compatible)\n * import { ViemBundlerClient } from '@introspectivelabs/x402-evm/exact/client/bundler';\n *\n * const bundlerClient = new ViemBundlerClient({\n * publicClient,\n * account,\n * chain,\n * bundlerUrl: 'https://bundler.example.com',\n * });\n *\n * const scheme3 = new ExactEvmSchemeERC4337({\n * bundlerClient,\n * signer: account, // Required when bundlerClient is provided\n * });\n *\n * const client = new x402Client();\n * client.register('eip155:84532', scheme);\n * ```\n */\nexport class ExactEvmSchemeERC4337 implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n private readonly bundlerClient?: BundlerClient;\n private readonly account?: SmartAccount;\n private readonly publicClient?: PublicClient<Transport, Chain>;\n private readonly signer: UserOperationSigner;\n private readonly entrypoint?: Hex;\n private readonly bundlerUrl?: string;\n\n /**\n * Creates a new ExactEvmSchemeERC4337 instance.\n *\n * @param config - Configuration for the scheme (type-safe: either bundlerClient or account must be provided)\n * @throws Error if bundlerClient is not provided and account is also not provided (runtime safety check)\n * @throws Error if signer is not provided and account doesn't support signUserOperation\n */\n constructor(config: ExactEvmSchemeERC4337Config) {\n this.bundlerClient = config.bundlerClient;\n this.account = config.account;\n this.publicClient = config.publicClient;\n this.entrypoint = config.entrypoint;\n this.bundlerUrl = config.bundlerUrl;\n\n // Validate: if bundlerClient is not provided, account must be provided\n if (!this.bundlerClient && !this.account) {\n throw new Error(\n \"Either bundlerClient or account must be provided. \" +\n \"If bundlerClient is not provided, account (SmartAccount) is required for dynamic bundlerClient creation.\",\n );\n }\n\n // Handle signer: use provided signer or auto-create from account\n if (config.signer) {\n this.signer = config.signer;\n } else if (this.account) {\n // Auto-create signer from account if not provided\n if (!this.account.signUserOperation) {\n throw new Error(\n \"Account does not support signUserOperation. \" +\n \"Either provide a signer explicitly or use an account that supports signUserOperation.\",\n );\n }\n this.signer = new SafeAccountSigner(this.account);\n } else {\n // This should not happen due to type system, but add runtime check for safety\n throw new Error(\n \"Signer is required when bundlerClient is provided. \" +\n \"Either provide a signer explicitly or use account-based configuration.\",\n );\n }\n }\n\n /**\n * Creates a payment payload for the Exact scheme using ERC-4337 UserOperations.\n *\n * This method:\n * 1. Extracts user operation capability from payment requirements\n * 2. Creates bundlerClient dynamically if not provided (when userOperation.supported is true)\n * 3. Builds ERC20 transfer call data\n * 4. Prepares the user operation using the bundler client\n * 5. Signs the user operation\n * 6. Converts to JSON-RPC format\n * 7. Returns the x402 payment payload\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload\n * @throws Error if user operation capability is not found or required fields are missing\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"x402Version\" | \"payload\">> {\n // Extract user operation capability\n const capability = extractUserOperationCapability(paymentRequirements);\n if (!capability) {\n throw new Error(\n `UserOperation capability not found in payment requirements for asset ${paymentRequirements.asset}. ` +\n \"The server must announce UserOperation support in the requirements.\",\n );\n }\n\n // Determine which bundlerClient to use\n let bundlerClient: BundlerClient;\n\n if (this.bundlerClient) {\n // Use provided bundlerClient (explicit config, backward compatible)\n bundlerClient = this.bundlerClient;\n } else {\n // Create bundlerClient dynamically from PaymentRequirements\n if (!this.account) {\n throw new Error(\n \"Account (SmartAccount) is required when bundlerClient is not provided. \" +\n \"Either provide bundlerClient in config or account for dynamic creation.\",\n );\n }\n\n // Get bundler URL (prioritize config defaults over PaymentRequirements)\n const bundlerUrl = this.bundlerUrl ?? capability.bundlerUrl;\n if (!bundlerUrl) {\n throw new Error(\n \"Bundler URL not provided. Set it in ExactEvmSchemeERC4337Config.defaultBundlerUrl \" +\n \"or in payment requirements extra.userOperation.bundlerUrl\",\n );\n }\n\n // Derive chain from network\n const chain = getChainFromNetwork(paymentRequirements.network);\n\n // Use provided publicClient or create default from network\n const publicClient =\n this.publicClient ?? createDefaultPublicClient(paymentRequirements.network);\n\n // Create ViemBundlerClient dynamically\n bundlerClient = new ViemBundlerClient({\n publicClient,\n account: this.account,\n chain,\n bundlerUrl,\n });\n }\n\n // Get entry point (prioritize config defaults over PaymentRequirements)\n const entryPoint = this.entrypoint ?? (capability.entrypoint as `0x${string}` | undefined);\n\n if (!entryPoint) {\n throw new Error(\n \"Entry point not provided. Set it in ExactEvmSchemeERC4337Config.entrypoint \" +\n \"when payment requirements extra.userOperation.entrypoint is not provided\",\n );\n }\n\n // Get bundler URL (prioritize config defaults over PaymentRequirements)\n const bundlerUrl = this.bundlerUrl ?? capability.bundlerUrl;\n if (!bundlerUrl) {\n throw new Error(\n \"Bundler URL not provided. Set it in ExactEvmSchemeERC4337Config.defaultBundlerUrl \" +\n \"or in payment requirements extra.userOperation.bundlerUrl\",\n );\n }\n\n // Normalize addresses\n const token = getAddress(paymentRequirements.asset);\n const payTo = getAddress(paymentRequirements.payTo);\n const amount = BigInt(paymentRequirements.amount);\n\n // Build ERC20 transfer call data\n const callData = buildERC20TransferCallData(token, payTo, amount);\n\n // Prepare user operation (unsigned)\n const unsignedUserOp = await bundlerClient.prepareUserOperation(\n [\n {\n to: token,\n value: BigInt(0), // ERC20 transfers don't send ETH\n data: callData,\n },\n ],\n entryPoint,\n );\n\n // Sign the user operation\n const signature = await this.signer.signUserOperation(unsignedUserOp);\n\n // Create signed user operation\n const signedUserOp = {\n ...unsignedUserOp,\n signature,\n };\n\n // Convert to JSON-RPC format (bigint -> hex)\n const jsonUserOp = userOpToJson(signedUserOp);\n\n // Build the ERC-4337 payload\n const payload: Erc4337Payload = {\n type: \"erc4337\",\n entryPoint,\n bundlerRpcUrl: bundlerUrl,\n userOperation: jsonUserOp,\n };\n\n return {\n x402Version,\n payload,\n };\n }\n}\n","import type { Chain, PublicClient, Transport } from \"viem\";\nimport { http } from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport { createBundlerClient as createViemBundlerClient } from \"viem/account-abstraction\";\nimport type {\n BundlerClient,\n BundlerClientConfig,\n GasEstimate,\n PreparedUserOperation,\n UserOperationCall,\n} from \"./client\";\nimport type { UserOperation07Json } from \"../../facilitator/types\";\n\n/**\n * Configuration for creating a viem-based bundler client\n */\nexport interface ViemBundlerClientConfig extends BundlerClientConfig {\n /**\n * Viem public client for blockchain interactions\n */\n publicClient: PublicClient<Transport, Chain>;\n\n /**\n * Smart account for user operation preparation (must be a SmartAccount, not a regular Account)\n */\n account: SmartAccount;\n\n /**\n * Chain configuration\n */\n chain: Chain;\n\n /**\n * Bundler RPC URL\n */\n bundlerUrl: string;\n}\n\n/**\n * Viem-based implementation of BundlerClient.\n * Uses viem's account-abstraction utilities for user operation handling.\n */\nexport class ViemBundlerClient implements BundlerClient {\n private readonly bundlerClient: ReturnType<typeof createViemBundlerClient>;\n private readonly account: SmartAccount;\n private readonly entryPoint: `0x${string}`;\n\n /**\n * Creates a new ViemBundlerClient instance.\n *\n * @param config - Configuration for the bundler client\n */\n constructor(config: ViemBundlerClientConfig) {\n this.account = config.account;\n this.entryPoint = \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\" as `0x${string}`; // EntryPoint v0.7\n\n // Create viem bundler client with bundler-specific transport\n this.bundlerClient = createViemBundlerClient({\n client: config.publicClient,\n chain: config.chain,\n account: config.account,\n transport: http(config.bundlerUrl),\n });\n }\n\n /**\n * Prepares an unsigned user operation for the given calls.\n *\n * @param calls - Array of calls to execute in the user operation\n * @param _entryPoint - The entry point address (unused, viem uses the configured entry point)\n * @returns Promise resolving to a prepared (unsigned) user operation\n */\n async prepareUserOperation(\n calls: UserOperationCall[],\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _entryPoint: `0x${string}`,\n ): Promise<PreparedUserOperation> {\n const prepared = await this.bundlerClient.prepareUserOperation({\n account: this.account,\n calls: calls.map(call => ({\n to: call.to,\n value: call.value,\n data: call.data,\n })),\n });\n\n // Return in the format expected by signers (with bigints)\n // Note: viem's prepareUserOperation returns a UserOperation with bigints\n return {\n sender: prepared.sender,\n nonce: prepared.nonce,\n callData: prepared.callData,\n callGasLimit: prepared.callGasLimit,\n verificationGasLimit: prepared.verificationGasLimit,\n preVerificationGas: prepared.preVerificationGas,\n maxFeePerGas: prepared.maxFeePerGas,\n maxPriorityFeePerGas: prepared.maxPriorityFeePerGas,\n // viem uses paymasterAndData instead of separate paymaster/paymasterData\n paymaster: (prepared as { paymasterAndData?: `0x${string}` }).paymasterAndData?.slice(\n 0,\n 42,\n ) as `0x${string}` | undefined,\n paymasterData: (prepared as { paymasterAndData?: `0x${string}` }).paymasterAndData?.slice(\n 42,\n ) as `0x${string}` | undefined,\n paymasterVerificationGasLimit: (\n prepared as {\n paymasterVerificationGasLimit?: bigint;\n }\n ).paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: (prepared as { paymasterPostOpGasLimit?: bigint })\n .paymasterPostOpGasLimit,\n signature: prepared.signature,\n } as PreparedUserOperation;\n }\n\n /**\n * Estimates gas for a user operation.\n * Note: This is typically done as part of prepareUserOperation,\n * but is available as a separate method for flexibility.\n *\n * @param _userOp - The user operation to estimate gas for\n * @param _entryPoint - The entry point address\n * @returns Promise resolving to gas estimates\n */\n async estimateGas(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _userOp: UserOperation07Json,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _entryPoint: `0x${string}`,\n ): Promise<GasEstimate> {\n // Note: Gas estimation is typically done as part of prepareUserOperation\n // This method is provided for flexibility but may not be used in practice\n // The return type from estimateUserOperationGas doesn't include maxFeePerGas/maxPriorityFeePerGas\n // as those are determined by the network, not the bundler\n throw new Error(\n \"estimateGas should be called through prepareUserOperation, which includes gas estimation\",\n );\n }\n\n /**\n * Sends a user operation to the bundler.\n *\n * @param userOp - The signed user operation to send\n * @param _entryPoint - The entry point address (unused, viem uses the configured entry point)\n * @returns Promise resolving to the user operation hash\n */\n async sendUserOperation(\n userOp: UserOperation07Json,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _entryPoint: `0x${string}`,\n ): Promise<string> {\n // Convert JSON user operation to format expected by viem\n // viem's sendUserOperation accepts UserOperation fields directly (not nested)\n const hash = await this.bundlerClient.sendUserOperation({\n account: this.account,\n sender: userOp.sender as `0x${string}`,\n nonce: BigInt(userOp.nonce),\n callData: userOp.callData as `0x${string}`,\n callGasLimit: BigInt(userOp.callGasLimit),\n verificationGasLimit: BigInt(userOp.verificationGasLimit),\n preVerificationGas: BigInt(userOp.preVerificationGas),\n maxFeePerGas: BigInt(userOp.maxFeePerGas),\n maxPriorityFeePerGas: BigInt(userOp.maxPriorityFeePerGas),\n // Combine paymaster and paymasterData into paymasterAndData\n paymasterAndData:\n userOp.paymaster && userOp.paymasterData\n ? ((userOp.paymaster + userOp.paymasterData.slice(2)) as `0x${string}`)\n : userOp.paymaster\n ? (userOp.paymaster as `0x${string}`)\n : (\"0x\" as `0x${string}`),\n signature: userOp.signature as `0x${string}`,\n });\n\n return hash;\n }\n}\n","import type { SmartAccount } from \"viem/account-abstraction\";\nimport type { PreparedUserOperation } from \"../bundler\";\nimport type { UserOperationSigner } from \"./types\";\n\n/**\n * Adapter to make a SmartAccount (e.g., Safe account) work as a UserOperationSigner.\n *\n * This class wraps a SmartAccount that supports `signUserOperation` and adapts it\n * to the UserOperationSigner interface required by the x402 ERC-4337 scheme.\n *\n * @example\n * ```typescript\n * import { SafeAccountSigner } from \"@introspectivelabs/x402-evm/exact/client\";\n * import { toSafeSmartAccount } from \"permissionless/accounts\";\n *\n * const safeAccount = await toSafeSmartAccount({ ... });\n * const signer = new SafeAccountSigner(safeAccount);\n *\n * const scheme = new ExactEvmSchemeERC4337({\n * bundlerClient,\n * signer,\n * });\n * ```\n */\nexport class SafeAccountSigner implements UserOperationSigner {\n readonly address: `0x${string}`;\n\n /**\n * Creates a new SafeAccountSigner instance.\n *\n * @param account - The SmartAccount instance (e.g., from permissionless/accounts)\n * @throws Error if the account is not initialized or missing an address\n */\n constructor(private readonly account: SmartAccount) {\n if (!account?.address) {\n throw new Error(\"Smart account not initialized\");\n }\n this.address = account.address as `0x${string}`;\n }\n\n /**\n * Signs a prepared (unsigned) user operation.\n *\n * @param userOp - The prepared user operation to sign\n * @returns Promise resolving to the signature\n * @throws Error if the account does not support signUserOperation\n */\n async signUserOperation(userOp: PreparedUserOperation): Promise<`0x${string}`> {\n if (!this.account?.signUserOperation) {\n throw new Error(\"Smart account does not support signUserOperation\");\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return await this.account.signUserOperation(userOp as any);\n }\n}\n","import { PaymentRequirements } from \"@x402/core/types\";\nimport { UserOperationCapability } from \"./types\";\n\n/**\n * Extracts the user operation capability from the payment requirements.\n *\n * @param requirements - The payment requirements\n * @returns The user operation capability\n */\nexport function extractUserOperationCapability(\n requirements: PaymentRequirements,\n): UserOperationCapability | undefined {\n const userOpExtra = requirements.extra?.userOperation;\n if (\n userOpExtra &&\n typeof userOpExtra === \"object\" &&\n \"supported\" in userOpExtra &&\n userOpExtra.supported === true\n ) {\n return userOpExtra as UserOperationCapability;\n }\n return undefined;\n}\n","import { encodeFunctionData } from \"viem\";\n\n/**\n * Standard ERC20 transfer function ABI\n */\nexport const ERC20_TRANSFER_ABI = [\n {\n type: \"function\",\n name: \"transfer\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"success\", type: \"bool\" }],\n },\n] as const;\n\n/**\n * Builds ERC20 transfer call data.\n *\n * @param token - The ERC20 token contract address\n * @param to - The recipient address\n * @param amount - The amount to transfer (in token's smallest unit)\n * @returns The encoded call data for the transfer function\n */\nexport function buildERC20TransferCallData(\n token: `0x${string}`,\n to: `0x${string}`,\n amount: bigint,\n): `0x${string}` {\n return encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [to, amount],\n });\n}\n","import type { Hex } from \"viem\";\nimport type { UserOperation07Json } from \"../../facilitator/types\";\n\n/**\n * Converts a bigint value to a hex string in JSON-RPC format.\n *\n * @param value - The bigint value to convert\n * @returns The hex string representation\n */\nfunction toRpcHex(value: bigint): Hex {\n return `0x${value.toString(16)}` as Hex;\n}\n\n/**\n * Converts a user operation with bigint values to JSON-RPC compatible format.\n * This recursively converts all bigint values to hex strings.\n *\n * @param userOp - The user operation object (may contain bigints)\n * @returns The user operation in JSON-RPC format (all bigints converted to hex)\n */\nexport function userOpToJson(userOp: Record<string, unknown>): UserOperation07Json {\n const json: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(userOp)) {\n // Skip internal viem fields that bundlers reject\n if (key === \"account\") continue;\n\n if (typeof value === \"bigint\") {\n json[key] = toRpcHex(value);\n } else if (value && typeof value === \"object\" && !Array.isArray(value)) {\n // Recursively handle nested objects with bigints\n const inner: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n inner[k] = typeof v === \"bigint\" ? toRpcHex(v) : v;\n }\n json[key] = inner;\n } else {\n json[key] = value;\n }\n }\n\n return json as UserOperation07Json;\n}\n"],"mappings":"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","names":["import_viem","createViemBundlerClient","import_viem","bundlerUrl"]}