@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
@@ -0,0 +1,224 @@
1
+ import { SchemeNetworkFacilitator, Network, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@x402/core/types';
2
+ export { E as Erc4337Payload, U as UserOperation07Json } from '../../types-Dk5U6Xnw.js';
3
+
4
+ /**
5
+ * Configuration for the ERC-4337 facilitator
6
+ */
7
+ interface ExactEvmSchemeNetworkERC4337Config {
8
+ /**
9
+ * Default bundler URL to use if not provided in payload or requirements
10
+ */
11
+ defaultBundlerUrl?: string;
12
+ /**
13
+ * Timeout for receipt polling in milliseconds
14
+ *
15
+ * @default 30000
16
+ */
17
+ receiptPollTimeout?: number;
18
+ /**
19
+ * Interval for receipt polling in milliseconds
20
+ *
21
+ * @default 1000
22
+ */
23
+ receiptPollInterval?: number;
24
+ }
25
+ /**
26
+ * Enhanced ExactEvmScheme facilitator that supports UserOperation (ERC-4337) payments.
27
+ *
28
+ * This facilitator implements the `SchemeNetworkFacilitator` interface and handles
29
+ * verification and settlement of user operations through a bundler.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { ExactEvmSchemeNetworkERC4337 } from '@introspectivelabs/x402-evm/exact/facilitator';
34
+ * import { x402Facilitator } from '@x402/core/facilitator';
35
+ *
36
+ * const facilitator = new x402Facilitator()
37
+ * .register('eip155:84532', new ExactEvmSchemeNetworkERC4337());
38
+ * ```
39
+ */
40
+ declare class ExactEvmSchemeNetworkERC4337 implements SchemeNetworkFacilitator {
41
+ readonly scheme = "exact";
42
+ readonly caipFamily = "eip155:*";
43
+ private readonly config;
44
+ /**
45
+ * Creates a new ExactEvmSchemeNetworkERC4337 instance
46
+ *
47
+ * @param config - Optional configuration for the facilitator
48
+ */
49
+ constructor(config?: ExactEvmSchemeNetworkERC4337Config);
50
+ /**
51
+ * Get mechanism-specific extra data for the supported kinds endpoint.
52
+ * Returns user operation capability if available.
53
+ *
54
+ * @param _ - The network identifier (unused, but required by interface)
55
+ * @returns User operation capability or undefined
56
+ */
57
+ getExtra(_: Network): Record<string, unknown> | undefined;
58
+ /**
59
+ * Get signer addresses used by this facilitator.
60
+ * For user operations, no facilitator signer is needed as the user signs the operation.
61
+ *
62
+ * @param _ - The network identifier (unused, but required by interface)
63
+ * @returns Empty array (no facilitator signer needed)
64
+ */
65
+ getSigners(_: string): string[];
66
+ /**
67
+ * Verifies a payment payload containing a user operation.
68
+ *
69
+ * This method:
70
+ * - Extracts the user operation from the payload
71
+ * - Gets the bundler URL from payload, requirements, or config
72
+ * - Estimates gas using the bundler to validate the user operation
73
+ *
74
+ * @param payload - The payment payload containing the user operation
75
+ * @param requirements - The payment requirements
76
+ * @returns Promise resolving to verification response
77
+ */
78
+ verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
79
+ /**
80
+ * Settles a payment by sending the user operation to the bundler.
81
+ *
82
+ * This method:
83
+ * - Re-verifies the payment (following original pattern)
84
+ * - Sends the user operation to the bundler
85
+ * - Polls for the receipt
86
+ * - Returns the transaction hash
87
+ *
88
+ * @param payload - The payment payload containing the user operation
89
+ * @param requirements - The payment requirements
90
+ * @returns Promise resolving to settlement response
91
+ */
92
+ settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
93
+ }
94
+
95
+ /**
96
+ * Gas estimation response from bundler
97
+ */
98
+ interface GasEstimate {
99
+ [key: string]: unknown;
100
+ callGasLimit?: string;
101
+ verificationGasLimit?: string;
102
+ preVerificationGas?: string;
103
+ maxFeePerGas?: string;
104
+ maxPriorityFeePerGas?: string;
105
+ paymasterVerificationGasLimit?: string;
106
+ paymasterPostOpGasLimit?: string;
107
+ }
108
+ /**
109
+ * User operation receipt from bundler
110
+ */
111
+ interface UserOperationReceipt {
112
+ [key: string]: unknown;
113
+ userOpHash: string;
114
+ entryPoint: string;
115
+ sender: string;
116
+ nonce: string;
117
+ paymaster?: string;
118
+ actualGasCost: string;
119
+ actualGasUsed: string;
120
+ success: boolean;
121
+ reason?: string;
122
+ logs: unknown[];
123
+ receipt?: {
124
+ [key: string]: unknown;
125
+ transactionHash: string;
126
+ };
127
+ transactionHash?: string;
128
+ }
129
+ /**
130
+ * Configuration for bundler client
131
+ */
132
+ interface BundlerClientConfig {
133
+ /**
134
+ * Timeout for RPC calls in milliseconds
135
+ *
136
+ * @default 10000
137
+ */
138
+ timeout?: number;
139
+ /**
140
+ * Number of retries for failed requests
141
+ *
142
+ * @default 0
143
+ */
144
+ retries?: number;
145
+ }
146
+ /**
147
+ * Custom error class for bundler-related errors
148
+ */
149
+ declare class BundlerError extends Error {
150
+ readonly code?: number;
151
+ readonly data?: unknown;
152
+ readonly method?: string;
153
+ readonly bundlerUrl?: string;
154
+ /**
155
+ * Creates a new BundlerError instance
156
+ *
157
+ * @param message - Error message
158
+ * @param options - Optional error details
159
+ * @param options.code - Error code from bundler
160
+ * @param options.data - Additional error data
161
+ * @param options.method - RPC method that failed
162
+ * @param options.bundlerUrl - Bundler URL that was called
163
+ * @param options.cause - Original error that caused this error
164
+ */
165
+ constructor(message: string, options?: {
166
+ code?: number;
167
+ data?: unknown;
168
+ method?: string;
169
+ bundlerUrl?: string;
170
+ cause?: Error;
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Bundler RPC client for ERC-4337 user operations
176
+ */
177
+ declare class BundlerClient {
178
+ private readonly rpcUrl;
179
+ private readonly config;
180
+ /**
181
+ * Creates a new BundlerClient instance
182
+ *
183
+ * @param rpcUrl - The bundler RPC URL
184
+ * @param config - Optional configuration for the client
185
+ */
186
+ constructor(rpcUrl: string, config?: BundlerClientConfig);
187
+ /**
188
+ * Estimates gas for a user operation
189
+ *
190
+ * @param userOp - The user operation to estimate gas for
191
+ * @param entryPoint - The entry point address
192
+ * @returns Gas estimates
193
+ * @throws BundlerError if the estimation fails
194
+ */
195
+ estimateUserOperationGas(userOp: Record<string, unknown>, entryPoint: string): Promise<GasEstimate>;
196
+ /**
197
+ * Sends a user operation to the bundler
198
+ *
199
+ * @param userOp - The user operation to send
200
+ * @param entryPoint - The entry point address
201
+ * @returns The user operation hash
202
+ * @throws BundlerError if sending fails
203
+ */
204
+ sendUserOperation(userOp: Record<string, unknown>, entryPoint: string): Promise<string>;
205
+ /**
206
+ * Gets the receipt for a user operation
207
+ *
208
+ * @param userOpHash - The user operation hash
209
+ * @returns The receipt or null if not found
210
+ * @throws BundlerError if the request fails
211
+ */
212
+ getUserOperationReceipt(userOpHash: string): Promise<UserOperationReceipt | null>;
213
+ /**
214
+ * Makes a JSON-RPC call to the bundler
215
+ *
216
+ * @param method - The RPC method name
217
+ * @param params - The method parameters
218
+ * @returns The result from the RPC call
219
+ * @throws BundlerError if the call fails
220
+ */
221
+ private call;
222
+ }
223
+
224
+ export { BundlerClient, type BundlerClientConfig, BundlerError, ExactEvmSchemeNetworkERC4337, type ExactEvmSchemeNetworkERC4337Config, type GasEstimate, type UserOperationReceipt };
@@ -0,0 +1,355 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/exact/facilitator/index.ts
21
+ var facilitator_exports = {};
22
+ __export(facilitator_exports, {
23
+ BundlerClient: () => BundlerClient,
24
+ ExactEvmSchemeNetworkERC4337: () => ExactEvmSchemeNetworkERC4337
25
+ });
26
+ module.exports = __toCommonJS(facilitator_exports);
27
+
28
+ // src/exact/facilitator/bundler/types.ts
29
+ var BundlerError = class extends Error {
30
+ /**
31
+ * Creates a new BundlerError instance
32
+ *
33
+ * @param message - Error message
34
+ * @param options - Optional error details
35
+ * @param options.code - Error code from bundler
36
+ * @param options.data - Additional error data
37
+ * @param options.method - RPC method that failed
38
+ * @param options.bundlerUrl - Bundler URL that was called
39
+ * @param options.cause - Original error that caused this error
40
+ */
41
+ constructor(message, options) {
42
+ super(message);
43
+ this.name = "BundlerError";
44
+ this.code = options?.code;
45
+ this.data = options?.data;
46
+ this.method = options?.method;
47
+ this.bundlerUrl = options?.bundlerUrl;
48
+ if (options?.cause) {
49
+ this.cause = options.cause;
50
+ }
51
+ }
52
+ };
53
+
54
+ // src/exact/facilitator/bundler/client.ts
55
+ var BundlerClient = class {
56
+ /**
57
+ * Creates a new BundlerClient instance
58
+ *
59
+ * @param rpcUrl - The bundler RPC URL
60
+ * @param config - Optional configuration for the client
61
+ */
62
+ constructor(rpcUrl, config) {
63
+ this.rpcUrl = rpcUrl;
64
+ this.config = {
65
+ timeout: config?.timeout ?? 1e4,
66
+ retries: config?.retries ?? 0
67
+ };
68
+ }
69
+ /**
70
+ * Estimates gas for a user operation
71
+ *
72
+ * @param userOp - The user operation to estimate gas for
73
+ * @param entryPoint - The entry point address
74
+ * @returns Gas estimates
75
+ * @throws BundlerError if the estimation fails
76
+ */
77
+ async estimateUserOperationGas(userOp, entryPoint) {
78
+ return this.call("eth_estimateUserOperationGas", [userOp, entryPoint]);
79
+ }
80
+ /**
81
+ * Sends a user operation to the bundler
82
+ *
83
+ * @param userOp - The user operation to send
84
+ * @param entryPoint - The entry point address
85
+ * @returns The user operation hash
86
+ * @throws BundlerError if sending fails
87
+ */
88
+ async sendUserOperation(userOp, entryPoint) {
89
+ return this.call("eth_sendUserOperation", [userOp, entryPoint]);
90
+ }
91
+ /**
92
+ * Gets the receipt for a user operation
93
+ *
94
+ * @param userOpHash - The user operation hash
95
+ * @returns The receipt or null if not found
96
+ * @throws BundlerError if the request fails
97
+ */
98
+ async getUserOperationReceipt(userOpHash) {
99
+ return this.call("eth_getUserOperationReceipt", [userOpHash]);
100
+ }
101
+ /**
102
+ * Makes a JSON-RPC call to the bundler
103
+ *
104
+ * @param method - The RPC method name
105
+ * @param params - The method parameters
106
+ * @returns The result from the RPC call
107
+ * @throws BundlerError if the call fails
108
+ */
109
+ async call(method, params) {
110
+ const requestPayload = {
111
+ jsonrpc: "2.0",
112
+ id: 1,
113
+ method,
114
+ params
115
+ };
116
+ let lastError;
117
+ const maxAttempts = this.config.retries + 1;
118
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
119
+ try {
120
+ const controller = new AbortController();
121
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
122
+ const res = await fetch(this.rpcUrl, {
123
+ method: "POST",
124
+ headers: { "content-type": "application/json" },
125
+ body: JSON.stringify(requestPayload),
126
+ signal: controller.signal
127
+ });
128
+ clearTimeout(timeoutId);
129
+ if (!res.ok) {
130
+ throw new BundlerError(`Bundler HTTP error: ${res.status} ${res.statusText}`, {
131
+ method,
132
+ bundlerUrl: this.rpcUrl
133
+ });
134
+ }
135
+ const json = await res.json();
136
+ if (json.error) {
137
+ throw new BundlerError(json.error.message ?? "Bundler RPC error", {
138
+ code: json.error.code,
139
+ data: json.error.data,
140
+ method,
141
+ bundlerUrl: this.rpcUrl
142
+ });
143
+ }
144
+ if (json.result === void 0) {
145
+ throw new BundlerError("Bundler RPC returned no result", {
146
+ method,
147
+ bundlerUrl: this.rpcUrl
148
+ });
149
+ }
150
+ return json.result;
151
+ } catch (error) {
152
+ lastError = error instanceof Error ? error : new Error(String(error));
153
+ if (error instanceof Error && error.name === "AbortError") {
154
+ throw new BundlerError(`Bundler request timeout after ${this.config.timeout}ms`, {
155
+ method,
156
+ bundlerUrl: this.rpcUrl,
157
+ cause: error
158
+ });
159
+ }
160
+ if (attempt === maxAttempts - 1) {
161
+ if (error instanceof BundlerError) {
162
+ throw error;
163
+ }
164
+ throw new BundlerError(`Bundler request failed: ${lastError.message}`, {
165
+ method,
166
+ bundlerUrl: this.rpcUrl,
167
+ cause: lastError
168
+ });
169
+ }
170
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 100));
171
+ }
172
+ }
173
+ throw new BundlerError("Bundler request failed after retries", {
174
+ method,
175
+ bundlerUrl: this.rpcUrl,
176
+ cause: lastError
177
+ });
178
+ }
179
+ };
180
+
181
+ // src/exact/facilitator/scheme.ts
182
+ var ExactEvmSchemeNetworkERC4337 = class {
183
+ /**
184
+ * Creates a new ExactEvmSchemeNetworkERC4337 instance
185
+ *
186
+ * @param config - Optional configuration for the facilitator
187
+ */
188
+ constructor(config) {
189
+ this.scheme = "exact";
190
+ this.caipFamily = "eip155:*";
191
+ this.config = {
192
+ defaultBundlerUrl: config?.defaultBundlerUrl ?? "",
193
+ receiptPollTimeout: config?.receiptPollTimeout ?? 3e4,
194
+ receiptPollInterval: config?.receiptPollInterval ?? 1e3
195
+ };
196
+ }
197
+ /**
198
+ * Get mechanism-specific extra data for the supported kinds endpoint.
199
+ * Returns user operation capability if available.
200
+ *
201
+ * @param _ - The network identifier (unused, but required by interface)
202
+ * @returns User operation capability or undefined
203
+ */
204
+ getExtra(_) {
205
+ return void 0;
206
+ }
207
+ /**
208
+ * Get signer addresses used by this facilitator.
209
+ * For user operations, no facilitator signer is needed as the user signs the operation.
210
+ *
211
+ * @param _ - The network identifier (unused, but required by interface)
212
+ * @returns Empty array (no facilitator signer needed)
213
+ */
214
+ getSigners(_) {
215
+ return [];
216
+ }
217
+ /**
218
+ * Verifies a payment payload containing a user operation.
219
+ *
220
+ * This method:
221
+ * - Extracts the user operation from the payload
222
+ * - Gets the bundler URL from payload, requirements, or config
223
+ * - Estimates gas using the bundler to validate the user operation
224
+ *
225
+ * @param payload - The payment payload containing the user operation
226
+ * @param requirements - The payment requirements
227
+ * @returns Promise resolving to verification response
228
+ */
229
+ async verify(payload, requirements) {
230
+ const erc4337Payload = payload.payload;
231
+ if (!erc4337Payload.userOperation) {
232
+ return {
233
+ isValid: false,
234
+ invalidReason: "missing_user_operation",
235
+ payer: void 0
236
+ };
237
+ }
238
+ const userOp = erc4337Payload.userOperation;
239
+ const payer = userOp.sender;
240
+ const bundlerUrl = erc4337Payload.bundlerRpcUrl ?? requirements.extra?.userOperation?.bundlerUrl ?? this.config.defaultBundlerUrl;
241
+ if (!bundlerUrl) {
242
+ return {
243
+ isValid: false,
244
+ invalidReason: "missing_bundler_url",
245
+ payer
246
+ };
247
+ }
248
+ const entryPoint = erc4337Payload.entryPoint;
249
+ if (!entryPoint) {
250
+ return {
251
+ isValid: false,
252
+ invalidReason: "missing_entry_point",
253
+ payer
254
+ };
255
+ }
256
+ try {
257
+ const bundler = new BundlerClient(bundlerUrl);
258
+ await bundler.estimateUserOperationGas(userOp, entryPoint);
259
+ return {
260
+ isValid: true,
261
+ invalidReason: void 0,
262
+ payer
263
+ };
264
+ } catch {
265
+ return {
266
+ isValid: false,
267
+ invalidReason: "simulation_failed",
268
+ payer
269
+ };
270
+ }
271
+ }
272
+ /**
273
+ * Settles a payment by sending the user operation to the bundler.
274
+ *
275
+ * This method:
276
+ * - Re-verifies the payment (following original pattern)
277
+ * - Sends the user operation to the bundler
278
+ * - Polls for the receipt
279
+ * - Returns the transaction hash
280
+ *
281
+ * @param payload - The payment payload containing the user operation
282
+ * @param requirements - The payment requirements
283
+ * @returns Promise resolving to settlement response
284
+ */
285
+ async settle(payload, requirements) {
286
+ const erc4337Payload = payload.payload;
287
+ const verifyResult = await this.verify(payload, requirements);
288
+ if (!verifyResult.isValid) {
289
+ return {
290
+ success: false,
291
+ network: payload.accepted.network,
292
+ transaction: "",
293
+ errorReason: verifyResult.invalidReason ?? "invalid",
294
+ payer: verifyResult.payer
295
+ };
296
+ }
297
+ const userOp = erc4337Payload.userOperation;
298
+ const payer = userOp.sender;
299
+ const bundlerUrl = erc4337Payload.bundlerRpcUrl ?? requirements.extra?.userOperation?.bundlerUrl ?? this.config.defaultBundlerUrl;
300
+ if (!bundlerUrl) {
301
+ return {
302
+ success: false,
303
+ network: payload.accepted.network,
304
+ transaction: "",
305
+ errorReason: "missing_bundler_url",
306
+ payer
307
+ };
308
+ }
309
+ const entryPoint = erc4337Payload.entryPoint;
310
+ if (!entryPoint) {
311
+ return {
312
+ success: false,
313
+ network: payload.accepted.network,
314
+ transaction: "",
315
+ errorReason: "missing_entry_point",
316
+ payer
317
+ };
318
+ }
319
+ try {
320
+ const bundler = new BundlerClient(bundlerUrl);
321
+ const userOpHash = await bundler.sendUserOperation(userOp, entryPoint);
322
+ const deadline = Date.now() + this.config.receiptPollTimeout;
323
+ let receipt = null;
324
+ while (Date.now() < deadline) {
325
+ receipt = await bundler.getUserOperationReceipt(userOpHash);
326
+ if (receipt) {
327
+ break;
328
+ }
329
+ await new Promise((resolve) => setTimeout(resolve, this.config.receiptPollInterval));
330
+ }
331
+ const txHash = receipt?.receipt?.transactionHash ?? receipt?.transactionHash ?? userOpHash;
332
+ return {
333
+ success: true,
334
+ network: payload.accepted.network,
335
+ transaction: txHash,
336
+ payer,
337
+ errorReason: void 0
338
+ };
339
+ } catch {
340
+ return {
341
+ success: false,
342
+ network: payload.accepted.network,
343
+ transaction: "",
344
+ errorReason: "settlement_failed",
345
+ payer
346
+ };
347
+ }
348
+ }
349
+ };
350
+ // Annotate the CommonJS export names for ESM import in node:
351
+ 0 && (module.exports = {
352
+ BundlerClient,
353
+ ExactEvmSchemeNetworkERC4337
354
+ });
355
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/exact/facilitator/index.ts","../../../../src/exact/facilitator/bundler/types.ts","../../../../src/exact/facilitator/bundler/client.ts","../../../../src/exact/facilitator/scheme.ts"],"sourcesContent":["export { ExactEvmSchemeNetworkERC4337 } from \"./scheme\";\nexport type { ExactEvmSchemeNetworkERC4337Config } from \"./scheme\";\nexport { BundlerClient } from \"./bundler/client\";\nexport type {\n BundlerClientConfig,\n BundlerError,\n GasEstimate,\n UserOperationReceipt,\n} from \"./bundler/types\";\nexport type { Erc4337Payload, UserOperation07Json } from \"./types\";\n","/**\n * Gas estimation response from bundler\n */\nexport interface GasEstimate {\n [key: string]: unknown;\n callGasLimit?: string;\n verificationGasLimit?: string;\n preVerificationGas?: string;\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n paymasterVerificationGasLimit?: string;\n paymasterPostOpGasLimit?: string;\n}\n\n/**\n * User operation receipt from bundler\n */\nexport interface UserOperationReceipt {\n [key: string]: unknown;\n userOpHash: string;\n entryPoint: string;\n sender: string;\n nonce: string;\n paymaster?: string;\n actualGasCost: string;\n actualGasUsed: string;\n success: boolean;\n reason?: string;\n logs: unknown[];\n receipt?: {\n [key: string]: unknown;\n transactionHash: string;\n };\n transactionHash?: string;\n}\n\n/**\n * Configuration for bundler client\n */\nexport interface BundlerClientConfig {\n /**\n * Timeout for RPC calls in milliseconds\n *\n * @default 10000\n */\n timeout?: number;\n /**\n * Number of retries for failed requests\n *\n * @default 0\n */\n retries?: number;\n}\n\n/**\n * JSON-RPC error response\n */\nexport interface JsonRpcError {\n message?: string;\n code?: number;\n data?: unknown;\n}\n\n/**\n * JSON-RPC response wrapper\n */\nexport interface JsonRpcResponse<T> {\n result?: T;\n error?: JsonRpcError;\n}\n\n/**\n * Custom error class for bundler-related errors\n */\nexport class BundlerError extends Error {\n readonly code?: number;\n readonly data?: unknown;\n readonly method?: string;\n readonly bundlerUrl?: string;\n\n /**\n * Creates a new BundlerError instance\n *\n * @param message - Error message\n * @param options - Optional error details\n * @param options.code - Error code from bundler\n * @param options.data - Additional error data\n * @param options.method - RPC method that failed\n * @param options.bundlerUrl - Bundler URL that was called\n * @param options.cause - Original error that caused this error\n */\n constructor(\n message: string,\n options?: {\n code?: number;\n data?: unknown;\n method?: string;\n bundlerUrl?: string;\n cause?: Error;\n },\n ) {\n super(message);\n this.name = \"BundlerError\";\n this.code = options?.code;\n this.data = options?.data;\n this.method = options?.method;\n this.bundlerUrl = options?.bundlerUrl;\n if (options?.cause) {\n // @ts-expect-error - cause is a standard Error property but not in all TypeScript versions\n this.cause = options.cause;\n }\n }\n}\n","import type {\n BundlerClientConfig,\n GasEstimate,\n JsonRpcResponse,\n UserOperationReceipt,\n} from \"./types\";\nimport { BundlerError } from \"./types\";\n\n/**\n * Bundler RPC client for ERC-4337 user operations\n */\nexport class BundlerClient {\n private readonly rpcUrl: string;\n private readonly config: Required<BundlerClientConfig>;\n\n /**\n * Creates a new BundlerClient instance\n *\n * @param rpcUrl - The bundler RPC URL\n * @param config - Optional configuration for the client\n */\n constructor(rpcUrl: string, config?: BundlerClientConfig) {\n this.rpcUrl = rpcUrl;\n this.config = {\n timeout: config?.timeout ?? 10_000,\n retries: config?.retries ?? 0,\n };\n }\n\n /**\n * Estimates gas for a user operation\n *\n * @param userOp - The user operation to estimate gas for\n * @param entryPoint - The entry point address\n * @returns Gas estimates\n * @throws BundlerError if the estimation fails\n */\n async estimateUserOperationGas(\n userOp: Record<string, unknown>,\n entryPoint: string,\n ): Promise<GasEstimate> {\n return this.call<GasEstimate>(\"eth_estimateUserOperationGas\", [userOp, entryPoint]);\n }\n\n /**\n * Sends a user operation to the bundler\n *\n * @param userOp - The user operation to send\n * @param entryPoint - The entry point address\n * @returns The user operation hash\n * @throws BundlerError if sending fails\n */\n async sendUserOperation(userOp: Record<string, unknown>, entryPoint: string): Promise<string> {\n return this.call<string>(\"eth_sendUserOperation\", [userOp, entryPoint]);\n }\n\n /**\n * Gets the receipt for a user operation\n *\n * @param userOpHash - The user operation hash\n * @returns The receipt or null if not found\n * @throws BundlerError if the request fails\n */\n async getUserOperationReceipt(userOpHash: string): Promise<UserOperationReceipt | null> {\n return this.call<UserOperationReceipt | null>(\"eth_getUserOperationReceipt\", [userOpHash]);\n }\n\n /**\n * Makes a JSON-RPC call to the bundler\n *\n * @param method - The RPC method name\n * @param params - The method parameters\n * @returns The result from the RPC call\n * @throws BundlerError if the call fails\n */\n private async call<T>(method: string, params: unknown[]): Promise<T> {\n const requestPayload = {\n jsonrpc: \"2.0\" as const,\n id: 1,\n method,\n params,\n };\n\n let lastError: Error | undefined;\n const maxAttempts = this.config.retries + 1;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n const res = await fetch(this.rpcUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(requestPayload),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!res.ok) {\n throw new BundlerError(`Bundler HTTP error: ${res.status} ${res.statusText}`, {\n method,\n bundlerUrl: this.rpcUrl,\n });\n }\n\n const json = (await res.json()) as JsonRpcResponse<T>;\n\n if (json.error) {\n throw new BundlerError(json.error.message ?? \"Bundler RPC error\", {\n code: json.error.code,\n data: json.error.data,\n method,\n bundlerUrl: this.rpcUrl,\n });\n }\n\n if (json.result === undefined) {\n throw new BundlerError(\"Bundler RPC returned no result\", {\n method,\n bundlerUrl: this.rpcUrl,\n });\n }\n\n return json.result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // If it's an abort error (timeout), don't retry\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new BundlerError(`Bundler request timeout after ${this.config.timeout}ms`, {\n method,\n bundlerUrl: this.rpcUrl,\n cause: error,\n });\n }\n\n // If this is the last attempt, throw the error\n if (attempt === maxAttempts - 1) {\n if (error instanceof BundlerError) {\n throw error;\n }\n throw new BundlerError(`Bundler request failed: ${lastError.message}`, {\n method,\n bundlerUrl: this.rpcUrl,\n cause: lastError,\n });\n }\n\n // Wait before retrying (exponential backoff)\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw new BundlerError(\"Bundler request failed after retries\", {\n method,\n bundlerUrl: this.rpcUrl,\n cause: lastError,\n });\n }\n}\n","import type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport { BundlerClient } from \"./bundler/client\";\nimport type { Erc4337Payload } from \"./types\";\n\n/**\n * Configuration for the ERC-4337 facilitator\n */\nexport interface ExactEvmSchemeNetworkERC4337Config {\n /**\n * Default bundler URL to use if not provided in payload or requirements\n */\n\n defaultBundlerUrl?: string;\n\n /**\n * Timeout for receipt polling in milliseconds\n *\n * @default 30000\n */\n\n receiptPollTimeout?: number;\n\n /**\n * Interval for receipt polling in milliseconds\n *\n * @default 1000\n */\n\n receiptPollInterval?: number;\n}\n\n/**\n * Enhanced ExactEvmScheme facilitator that supports UserOperation (ERC-4337) payments.\n *\n * This facilitator implements the `SchemeNetworkFacilitator` interface and handles\n * verification and settlement of user operations through a bundler.\n *\n * @example\n * ```typescript\n * import { ExactEvmSchemeNetworkERC4337 } from '@introspectivelabs/x402-evm/exact/facilitator';\n * import { x402Facilitator } from '@x402/core/facilitator';\n *\n * const facilitator = new x402Facilitator()\n * .register('eip155:84532', new ExactEvmSchemeNetworkERC4337());\n * ```\n */\nexport class ExactEvmSchemeNetworkERC4337 implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeNetworkERC4337Config>;\n\n /**\n * Creates a new ExactEvmSchemeNetworkERC4337 instance\n *\n * @param config - Optional configuration for the facilitator\n */\n constructor(config?: ExactEvmSchemeNetworkERC4337Config) {\n this.config = {\n defaultBundlerUrl: config?.defaultBundlerUrl ?? \"\",\n receiptPollTimeout: config?.receiptPollTimeout ?? 30_000,\n receiptPollInterval: config?.receiptPollInterval ?? 1_000,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * Returns user operation capability if available.\n *\n * @param _ - The network identifier (unused, but required by interface)\n * @returns User operation capability or undefined\n */\n getExtra(_: Network): Record<string, unknown> | undefined {\n // Return undefined - user operation capability should be set by the server\n // This follows the pattern of the original ExactEvmScheme\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * For user operations, no facilitator signer is needed as the user signs the operation.\n *\n * @param _ - The network identifier (unused, but required by interface)\n * @returns Empty array (no facilitator signer needed)\n */\n getSigners(_: string): string[] {\n return [];\n }\n\n /**\n * Verifies a payment payload containing a user operation.\n *\n * This method:\n * - Extracts the user operation from the payload\n * - Gets the bundler URL from payload, requirements, or config\n * - Estimates gas using the bundler to validate the user operation\n *\n * @param payload - The payment payload containing the user operation\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const erc4337Payload = payload.payload as Erc4337Payload;\n\n // Extract user operation\n if (!erc4337Payload.userOperation) {\n return {\n isValid: false,\n invalidReason: \"missing_user_operation\",\n payer: undefined,\n };\n }\n\n const userOp = erc4337Payload.userOperation;\n const payer = userOp.sender;\n\n // Get bundler URL from payload, requirements, or config\n const bundlerUrl =\n erc4337Payload.bundlerRpcUrl ??\n (requirements.extra?.userOperation as { bundlerUrl?: string } | undefined)?.bundlerUrl ??\n this.config.defaultBundlerUrl;\n\n if (!bundlerUrl) {\n return {\n isValid: false,\n invalidReason: \"missing_bundler_url\",\n payer,\n };\n }\n\n // Get entry point\n const entryPoint = erc4337Payload.entryPoint;\n if (!entryPoint) {\n return {\n isValid: false,\n invalidReason: \"missing_entry_point\",\n payer,\n };\n }\n\n // Verify by estimating gas through bundler\n try {\n const bundler = new BundlerClient(bundlerUrl);\n await bundler.estimateUserOperationGas(userOp, entryPoint);\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"simulation_failed\",\n payer,\n };\n }\n }\n\n /**\n * Settles a payment by sending the user operation to the bundler.\n *\n * This method:\n * - Re-verifies the payment (following original pattern)\n * - Sends the user operation to the bundler\n * - Polls for the receipt\n * - Returns the transaction hash\n *\n * @param payload - The payment payload containing the user operation\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const erc4337Payload = payload.payload as Erc4337Payload;\n\n // Re-verify before settling (following original pattern)\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: verifyResult.invalidReason ?? \"invalid\",\n payer: verifyResult.payer,\n };\n }\n\n const userOp = erc4337Payload.userOperation;\n const payer = userOp.sender;\n\n // Get bundler URL\n const bundlerUrl =\n erc4337Payload.bundlerRpcUrl ??\n (requirements.extra?.userOperation as { bundlerUrl?: string } | undefined)?.bundlerUrl ??\n this.config.defaultBundlerUrl;\n\n if (!bundlerUrl) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: \"missing_bundler_url\",\n payer,\n };\n }\n\n const entryPoint = erc4337Payload.entryPoint;\n if (!entryPoint) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: \"missing_entry_point\",\n payer,\n };\n }\n\n try {\n const bundler = new BundlerClient(bundlerUrl);\n\n // Send user operation\n const userOpHash = await bundler.sendUserOperation(userOp, entryPoint);\n\n // Poll for receipt\n const deadline = Date.now() + this.config.receiptPollTimeout;\n let receipt = null;\n\n while (Date.now() < deadline) {\n receipt = await bundler.getUserOperationReceipt(userOpHash);\n if (receipt) {\n break;\n }\n await new Promise(resolve => setTimeout(resolve, this.config.receiptPollInterval));\n }\n\n // Extract transaction hash from receipt\n const txHash = receipt?.receipt?.transactionHash ?? receipt?.transactionHash ?? userOpHash;\n\n return {\n success: true,\n network: payload.accepted.network,\n transaction: txHash,\n payer,\n errorReason: undefined,\n };\n } catch {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: \"settlement_failed\",\n payer,\n };\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC0EO,IAAM,eAAN,cAA2B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBtC,YACE,SACA,SAOA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO,SAAS;AACrB,SAAK,OAAO,SAAS;AACrB,SAAK,SAAS,SAAS;AACvB,SAAK,aAAa,SAAS;AAC3B,QAAI,SAAS,OAAO;AAElB,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAAA,EACF;AACF;;;ACrGO,IAAM,gBAAN,MAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzB,YAAY,QAAgB,QAA8B;AACxD,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,MACZ,SAAS,QAAQ,WAAW;AAAA,MAC5B,SAAS,QAAQ,WAAW;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,yBACJ,QACA,YACsB;AACtB,WAAO,KAAK,KAAkB,gCAAgC,CAAC,QAAQ,UAAU,CAAC;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,kBAAkB,QAAiC,YAAqC;AAC5F,WAAO,KAAK,KAAa,yBAAyB,CAAC,QAAQ,UAAU,CAAC;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,wBAAwB,YAA0D;AACtF,WAAO,KAAK,KAAkC,+BAA+B,CAAC,UAAU,CAAC;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,KAAQ,QAAgB,QAA+B;AACnE,UAAM,iBAAiB;AAAA,MACrB,SAAS;AAAA,MACT,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,QAAI;AACJ,UAAM,cAAc,KAAK,OAAO,UAAU;AAE1C,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAI;AACF,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO,OAAO;AAE1E,cAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;AAAA,UACnC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,cAAc;AAAA,UACnC,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,qBAAa,SAAS;AAEtB,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,IAAI,aAAa,uBAAuB,IAAI,MAAM,IAAI,IAAI,UAAU,IAAI;AAAA,YAC5E;AAAA,YACA,YAAY,KAAK;AAAA,UACnB,CAAC;AAAA,QACH;AAEA,cAAM,OAAQ,MAAM,IAAI,KAAK;AAE7B,YAAI,KAAK,OAAO;AACd,gBAAM,IAAI,aAAa,KAAK,MAAM,WAAW,qBAAqB;AAAA,YAChE,MAAM,KAAK,MAAM;AAAA,YACjB,MAAM,KAAK,MAAM;AAAA,YACjB;AAAA,YACA,YAAY,KAAK;AAAA,UACnB,CAAC;AAAA,QACH;AAEA,YAAI,KAAK,WAAW,QAAW;AAC7B,gBAAM,IAAI,aAAa,kCAAkC;AAAA,YACvD;AAAA,YACA,YAAY,KAAK;AAAA,UACnB,CAAC;AAAA,QACH;AAEA,eAAO,KAAK;AAAA,MACd,SAAS,OAAO;AACd,oBAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAGpE,YAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,gBAAM,IAAI,aAAa,iCAAiC,KAAK,OAAO,OAAO,MAAM;AAAA,YAC/E;AAAA,YACA,YAAY,KAAK;AAAA,YACjB,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAGA,YAAI,YAAY,cAAc,GAAG;AAC/B,cAAI,iBAAiB,cAAc;AACjC,kBAAM;AAAA,UACR;AACA,gBAAM,IAAI,aAAa,2BAA2B,UAAU,OAAO,IAAI;AAAA,YACrE;AAAA,YACA,YAAY,KAAK;AAAA,YACjB,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAGA,cAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;AAAA,MAC9E;AAAA,IACF;AAGA,UAAM,IAAI,aAAa,wCAAwC;AAAA,MAC7D;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;AC7GO,IAAM,+BAAN,MAAuE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU5E,YAAY,QAA6C;AATzD,SAAS,SAAS;AAClB,SAAS,aAAa;AASpB,SAAK,SAAS;AAAA,MACZ,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,oBAAoB,QAAQ,sBAAsB;AAAA,MAClD,qBAAqB,QAAQ,uBAAuB;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,GAAiD;AAGxD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,GAAqB;AAC9B,WAAO,CAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,iBAAiB,QAAQ;AAG/B,QAAI,CAAC,eAAe,eAAe;AACjC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,SAAS,eAAe;AAC9B,UAAM,QAAQ,OAAO;AAGrB,UAAM,aACJ,eAAe,iBACd,aAAa,OAAO,eAAuD,cAC5E,KAAK,OAAO;AAEd,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAGA,UAAM,aAAa,eAAe;AAClC,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAGA,QAAI;AACF,YAAM,UAAU,IAAI,cAAc,UAAU;AAC5C,YAAM,QAAQ,yBAAyB,QAAQ,UAAU;AAEzD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,iBAAiB,QAAQ;AAG/B,UAAM,eAAe,MAAM,KAAK,OAAO,SAAS,YAAY;AAC5D,QAAI,CAAC,aAAa,SAAS;AACzB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb,aAAa,aAAa,iBAAiB;AAAA,QAC3C,OAAO,aAAa;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,SAAS,eAAe;AAC9B,UAAM,QAAQ,OAAO;AAGrB,UAAM,aACJ,eAAe,iBACd,aAAa,OAAO,eAAuD,cAC5E,KAAK,OAAO;AAEd,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb,aAAa;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,eAAe;AAClC,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb,aAAa;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,IAAI,cAAc,UAAU;AAG5C,YAAM,aAAa,MAAM,QAAQ,kBAAkB,QAAQ,UAAU;AAGrE,YAAM,WAAW,KAAK,IAAI,IAAI,KAAK,OAAO;AAC1C,UAAI,UAAU;AAEd,aAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,kBAAU,MAAM,QAAQ,wBAAwB,UAAU;AAC1D,YAAI,SAAS;AACX;AAAA,QACF;AACA,cAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,KAAK,OAAO,mBAAmB,CAAC;AAAA,MACnF;AAGA,YAAM,SAAS,SAAS,SAAS,mBAAmB,SAAS,mBAAmB;AAEhF,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb,aAAa;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,47 @@
1
+ import { PaymentRequirements, Network } from '@x402/core/types';
2
+ import { ExactEvmScheme } from '@x402/evm/exact/server';
3
+
4
+ /**
5
+ * Enhanced ExactEvmScheme that preserves UserOperation capability in payment requirements.
6
+ *
7
+ * This class extends ExactEvmScheme and enhances the `enhancePaymentRequirements` method
8
+ * to preserve `userOperation` from `paymentRequirements.extra`. This ensures that when routes
9
+ * are transformed using `transformRoutesForUserOperation`, the userOperation data flows through
10
+ * the entire payment requirements pipeline.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { ExactEvmSchemeERC4337 } from '@introspectivelabs/x402-evm/exact/server';
15
+ * import { x402ResourceServer } from '@x402/core/server';
16
+ *
17
+ * const schemeServer = new ExactEvmSchemeERC4337();
18
+ * const server = new x402ResourceServer(facilitatorClient);
19
+ * server.register('eip155:84532', schemeServer);
20
+ * ```
21
+ */
22
+ declare class ExactEvmSchemeERC4337 extends ExactEvmScheme {
23
+ /**
24
+ * Enhance payment requirements while preserving UserOperation capability.
25
+ *
26
+ * This method calls the parent's enhancePaymentRequirements and then ensures
27
+ * that any userOperation from the original paymentRequirements.extra is preserved
28
+ * in the returned requirements.
29
+ *
30
+ * @param paymentRequirements - The base payment requirements
31
+ * @param supportedKind - The supported kind from facilitator
32
+ * @param supportedKind.x402Version - The x402 version supported by the facilitator
33
+ * @param supportedKind.scheme - The scheme supported by the facilitator
34
+ * @param supportedKind.network - The network supported by the facilitator
35
+ * @param supportedKind.extra - The extra supported by the facilitator
36
+ * @param extensionKeys - Extension keys supported by the facilitator
37
+ * @returns Enhanced payment requirements with userOperation preserved
38
+ */
39
+ enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
40
+ x402Version: number;
41
+ scheme: string;
42
+ network: Network;
43
+ extra?: Record<string, unknown>;
44
+ }, extensionKeys: string[]): Promise<PaymentRequirements>;
45
+ }
46
+
47
+ export { ExactEvmSchemeERC4337 };