@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.
- package/README.md +16 -0
- package/dist/cjs/exact/client/index.d.ts +48 -0
- package/dist/cjs/exact/client/index.js +403 -0
- package/dist/cjs/exact/client/index.js.map +1 -0
- package/dist/cjs/exact/facilitator/index.d.ts +224 -0
- package/dist/cjs/exact/facilitator/index.js +355 -0
- package/dist/cjs/exact/facilitator/index.js.map +1 -0
- package/dist/cjs/exact/server/index.d.ts +47 -0
- package/dist/cjs/exact/server/index.js +86 -0
- package/dist/cjs/exact/server/index.js.map +1 -0
- package/dist/cjs/index.d.ts +71 -0
- package/dist/cjs/index.js +860 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types-Dk5U6Xnw.d.ts +33 -0
- package/dist/cjs/userOperation-Dh1zucfd.d.ts +409 -0
- package/dist/esm/chunk-56L4QUDN.mjs +359 -0
- package/dist/esm/chunk-56L4QUDN.mjs.map +1 -0
- package/dist/esm/chunk-5HWFMQYG.mjs +328 -0
- package/dist/esm/chunk-5HWFMQYG.mjs.map +1 -0
- package/dist/esm/chunk-E3XDJP7M.mjs +53 -0
- package/dist/esm/chunk-E3XDJP7M.mjs.map +1 -0
- package/dist/esm/chunk-GGPRPAM4.mjs +13 -0
- package/dist/esm/chunk-GGPRPAM4.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +48 -0
- package/dist/esm/exact/client/index.mjs +18 -0
- package/dist/esm/exact/client/index.mjs.map +1 -0
- package/dist/esm/exact/facilitator/index.d.mts +224 -0
- package/dist/esm/exact/facilitator/index.mjs +9 -0
- package/dist/esm/exact/facilitator/index.mjs.map +1 -0
- package/dist/esm/exact/server/index.d.mts +47 -0
- package/dist/esm/exact/server/index.mjs +8 -0
- package/dist/esm/exact/server/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +71 -0
- package/dist/esm/index.mjs +110 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/types-Dk5U6Xnw.d.mts +33 -0
- package/dist/esm/userOperation-B2UUp3K6.d.mts +409 -0
- 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":"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","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 };
|