@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.mjs';
|
|
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 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","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 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Hex } from 'viem';
|
|
2
|
+
import { PaymentRequirements } from '@x402/core/types';
|
|
3
|
+
import { RoutesConfig, RouteConfig } from '@x402/core/server';
|
|
4
|
+
import { ExactEvmSchemeERC4337 } from './exact/server/index.mjs';
|
|
5
|
+
export { BundlerError, ExactEvmSchemeNetworkERC4337, ExactEvmSchemeNetworkERC4337Config, BundlerClient as FacilitatorBundlerClient, BundlerClientConfig as FacilitatorBundlerClientConfig, GasEstimate as FacilitatorGasEstimate, UserOperationReceipt } from './exact/facilitator/index.mjs';
|
|
6
|
+
export { E as Erc4337Payload, U as UserOperation07Json } from './types-Dk5U6Xnw.mjs';
|
|
7
|
+
export { B as ClientBundlerClient, b as ClientBundlerClientConfig, G as ClientGasEstimate, f as ERC20_TRANSFER_ABI, E as ExactEvmSchemeERC4337Client, a as ExactEvmSchemeERC4337Config, P as PreparedUserOperation, c as UserOperationCall, U as UserOperationSigner, V as ViemBundlerClient, d as ViemBundlerClientConfig, e as buildERC20TransferCallData, u as userOpToJson } from './userOperation-B2UUp3K6.mjs';
|
|
8
|
+
import '@x402/evm/exact/server';
|
|
9
|
+
import 'viem/account-abstraction';
|
|
10
|
+
|
|
11
|
+
interface UserOperationCapability {
|
|
12
|
+
/**
|
|
13
|
+
* Whether the UserOperation capability is supported
|
|
14
|
+
*/
|
|
15
|
+
supported: true;
|
|
16
|
+
/**
|
|
17
|
+
* Bundler URL for submitting UserOperations
|
|
18
|
+
*/
|
|
19
|
+
bundlerUrl?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Paymaster address for sponsored transactions
|
|
22
|
+
*/
|
|
23
|
+
paymaster?: Hex;
|
|
24
|
+
/**
|
|
25
|
+
* Suggested entrypoint for the UserOperation
|
|
26
|
+
*/
|
|
27
|
+
entrypoint?: Hex;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Extracts the user operation capability from the payment requirements.
|
|
32
|
+
*
|
|
33
|
+
* @param requirements - The payment requirements
|
|
34
|
+
* @returns The user operation capability
|
|
35
|
+
*/
|
|
36
|
+
declare function extractUserOperationCapability(requirements: PaymentRequirements): UserOperationCapability | undefined;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Transforms routes to move userOperation from PaymentOption.extra to price.extra.
|
|
40
|
+
*
|
|
41
|
+
* This transformation enables userOperation to flow through the natural price.extra
|
|
42
|
+
* path into PaymentRequirements.extra, allowing the official middleware to work
|
|
43
|
+
* without modification.
|
|
44
|
+
*
|
|
45
|
+
* This is a workaround to allow the official middleware to work without modification.
|
|
46
|
+
* and support this proposal https://github.com/coinbase/x402/issues/639
|
|
47
|
+
*
|
|
48
|
+
* @param routes - The routes configuration to transform (single RouteConfig or RoutesConfig object)
|
|
49
|
+
* @param schemeServer - The scheme server instance used for parsing prices
|
|
50
|
+
* @returns Transformed routes with userOperation moved to price.extra
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { transformRoutesForUserOperation } from '@introspectivelabs/x402-evm/exact/utils';
|
|
55
|
+
* import { ExactEvmSchemeERC4337Server } from '@introspectivelabs/x402-evm/exact/server';
|
|
56
|
+
*
|
|
57
|
+
* const schemeServer = new ExactEvmSchemeERC4337Server();
|
|
58
|
+
* const transformedRoutes = await transformRoutesForUserOperation(routes, schemeServer);
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare function transformRoutesForUserOperation(routes: RoutesConfig, schemeServer: ExactEvmSchemeERC4337): Promise<RoutesConfig>;
|
|
62
|
+
/**
|
|
63
|
+
* Transforms a single RouteConfig to move userOperation from PaymentOption.extra to price.extra.
|
|
64
|
+
*
|
|
65
|
+
* @param routeConfig - The RouteConfig to transform
|
|
66
|
+
* @param schemeServer - The scheme server instance used for parsing prices
|
|
67
|
+
* @returns The transformed RouteConfig
|
|
68
|
+
*/
|
|
69
|
+
declare function transformRouteForUserOperation(routeConfig: RouteConfig, schemeServer: ExactEvmSchemeERC4337): Promise<RouteConfig>;
|
|
70
|
+
|
|
71
|
+
export { ExactEvmSchemeERC4337 as ExactEvmSchemeERC4337Server, type UserOperationCapability, extractUserOperationCapability, transformRouteForUserOperation, transformRoutesForUserOperation };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ERC20_TRANSFER_ABI,
|
|
3
|
+
ExactEvmSchemeERC4337 as ExactEvmSchemeERC43372,
|
|
4
|
+
ViemBundlerClient,
|
|
5
|
+
buildERC20TransferCallData,
|
|
6
|
+
userOpToJson
|
|
7
|
+
} from "./chunk-56L4QUDN.mjs";
|
|
8
|
+
import {
|
|
9
|
+
ExactEvmSchemeERC4337
|
|
10
|
+
} from "./chunk-E3XDJP7M.mjs";
|
|
11
|
+
import {
|
|
12
|
+
extractUserOperationCapability
|
|
13
|
+
} from "./chunk-GGPRPAM4.mjs";
|
|
14
|
+
import {
|
|
15
|
+
BundlerClient,
|
|
16
|
+
ExactEvmSchemeNetworkERC4337
|
|
17
|
+
} from "./chunk-5HWFMQYG.mjs";
|
|
18
|
+
|
|
19
|
+
// src/exact/utils/transformRoutes.ts
|
|
20
|
+
async function transformRoutesForUserOperation(routes, schemeServer) {
|
|
21
|
+
if ("accepts" in routes) {
|
|
22
|
+
return await transformRouteForUserOperation(routes, schemeServer);
|
|
23
|
+
}
|
|
24
|
+
const transformed = {};
|
|
25
|
+
for (const [path, routeConfig] of Object.entries(routes)) {
|
|
26
|
+
transformed[path] = await transformRouteForUserOperation(routeConfig, schemeServer);
|
|
27
|
+
}
|
|
28
|
+
return transformed;
|
|
29
|
+
}
|
|
30
|
+
async function transformRouteForUserOperation(routeConfig, schemeServer) {
|
|
31
|
+
if (!Array.isArray(routeConfig.accepts)) {
|
|
32
|
+
return {
|
|
33
|
+
...routeConfig,
|
|
34
|
+
accepts: await transformPaymentOption(routeConfig.accepts, schemeServer)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const transformedAccepts = await Promise.all(
|
|
38
|
+
routeConfig.accepts.map((option) => transformPaymentOption(option, schemeServer))
|
|
39
|
+
);
|
|
40
|
+
return {
|
|
41
|
+
...routeConfig,
|
|
42
|
+
accepts: transformedAccepts
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async function transformPaymentOption(option, schemeServer) {
|
|
46
|
+
const userOperation = option.extra?.userOperation;
|
|
47
|
+
if (!userOperation || !userOperation.supported) {
|
|
48
|
+
return option;
|
|
49
|
+
}
|
|
50
|
+
const transformedPrice = await transformPrice(
|
|
51
|
+
option.price,
|
|
52
|
+
option.network,
|
|
53
|
+
userOperation,
|
|
54
|
+
schemeServer
|
|
55
|
+
);
|
|
56
|
+
const { userOperation: _, ...restExtra } = option.extra || {};
|
|
57
|
+
return {
|
|
58
|
+
...option,
|
|
59
|
+
price: transformedPrice,
|
|
60
|
+
extra: Object.keys(restExtra).length > 0 ? restExtra : void 0
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function transformPrice(price, network, userOperation, schemeServer) {
|
|
64
|
+
if (typeof price === "function") {
|
|
65
|
+
return async (context) => {
|
|
66
|
+
const resolvedPrice = await price(context);
|
|
67
|
+
return await injectUserOperationIntoPrice(
|
|
68
|
+
resolvedPrice,
|
|
69
|
+
network,
|
|
70
|
+
userOperation,
|
|
71
|
+
schemeServer
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return await injectUserOperationIntoPrice(price, network, userOperation, schemeServer);
|
|
76
|
+
}
|
|
77
|
+
async function injectUserOperationIntoPrice(price, network, userOperation, schemeServer) {
|
|
78
|
+
if (typeof price === "object" && "asset" in price && "amount" in price) {
|
|
79
|
+
const assetAmount2 = price;
|
|
80
|
+
return {
|
|
81
|
+
...assetAmount2,
|
|
82
|
+
extra: {
|
|
83
|
+
...assetAmount2.extra,
|
|
84
|
+
userOperation
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const assetAmount = await schemeServer.parsePrice(price, network);
|
|
89
|
+
return {
|
|
90
|
+
...assetAmount,
|
|
91
|
+
extra: {
|
|
92
|
+
...assetAmount.extra,
|
|
93
|
+
userOperation
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
ERC20_TRANSFER_ABI,
|
|
99
|
+
ExactEvmSchemeERC43372 as ExactEvmSchemeERC4337Client,
|
|
100
|
+
ExactEvmSchemeERC4337 as ExactEvmSchemeERC4337Server,
|
|
101
|
+
ExactEvmSchemeNetworkERC4337,
|
|
102
|
+
BundlerClient as FacilitatorBundlerClient,
|
|
103
|
+
ViemBundlerClient,
|
|
104
|
+
buildERC20TransferCallData,
|
|
105
|
+
extractUserOperationCapability,
|
|
106
|
+
transformRouteForUserOperation,
|
|
107
|
+
transformRoutesForUserOperation,
|
|
108
|
+
userOpToJson
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/utils/transformRoutes.ts"],"sourcesContent":["import type { RoutesConfig, RouteConfig, HTTPRequestContext } from \"@x402/core/server\";\nimport type { Price, Network, AssetAmount } from \"@x402/core/types\";\nimport type { ExactEvmSchemeERC4337 } from \"../server/scheme\";\nimport type { PaymentOption, DynamicPrice } from \"@x402/core/http\";\nimport type { UserOperationCapability } from \"../types\";\n\n/**\n * Transforms routes to move userOperation from PaymentOption.extra to price.extra.\n *\n * This transformation enables userOperation to flow through the natural price.extra\n * path into PaymentRequirements.extra, allowing the official middleware to work\n * without modification.\n *\n * This is a workaround to allow the official middleware to work without modification.\n * and support this proposal https://github.com/coinbase/x402/issues/639\n *\n * @param routes - The routes configuration to transform (single RouteConfig or RoutesConfig object)\n * @param schemeServer - The scheme server instance used for parsing prices\n * @returns Transformed routes with userOperation moved to price.extra\n *\n * @example\n * ```typescript\n * import { transformRoutesForUserOperation } from '@introspectivelabs/x402-evm/exact/utils';\n * import { ExactEvmSchemeERC4337Server } from '@introspectivelabs/x402-evm/exact/server';\n *\n * const schemeServer = new ExactEvmSchemeERC4337Server();\n * const transformedRoutes = await transformRoutesForUserOperation(routes, schemeServer);\n * ```\n */\nexport async function transformRoutesForUserOperation(\n routes: RoutesConfig,\n schemeServer: ExactEvmSchemeERC4337,\n): Promise<RoutesConfig> {\n // Handle single RouteConfig\n if (\"accepts\" in routes) {\n return await transformRouteForUserOperation(routes as RouteConfig, schemeServer);\n }\n\n // Handle RoutesConfig object (Record<string, RouteConfig>)\n const transformed: Record<string, RouteConfig> = {};\n for (const [path, routeConfig] of Object.entries(routes as Record<string, RouteConfig>)) {\n transformed[path] = await transformRouteForUserOperation(routeConfig, schemeServer);\n }\n return transformed;\n}\n\n/**\n * Transforms a single RouteConfig to move userOperation from PaymentOption.extra to price.extra.\n *\n * @param routeConfig - The RouteConfig to transform\n * @param schemeServer - The scheme server instance used for parsing prices\n * @returns The transformed RouteConfig\n */\nexport async function transformRouteForUserOperation(\n routeConfig: RouteConfig,\n schemeServer: ExactEvmSchemeERC4337,\n): Promise<RouteConfig> {\n // Handle single PaymentOption\n if (!Array.isArray(routeConfig.accepts)) {\n return {\n ...routeConfig,\n accepts: await transformPaymentOption(routeConfig.accepts, schemeServer),\n };\n }\n\n // Handle array of PaymentOptions\n const transformedAccepts = await Promise.all(\n routeConfig.accepts.map(option => transformPaymentOption(option, schemeServer)),\n );\n\n return {\n ...routeConfig,\n accepts: transformedAccepts,\n };\n}\n\n/**\n * Transforms a PaymentOption to move userOperation from extra to price.extra.\n *\n * @param option - The PaymentOption to transform\n * @param schemeServer - The scheme server instance used for parsing prices\n * @returns The transformed PaymentOption\n */\nasync function transformPaymentOption(\n option: PaymentOption,\n schemeServer: ExactEvmSchemeERC4337,\n): Promise<PaymentOption> {\n // Extract userOperation from PaymentOption.extra\n const userOperation = option.extra?.userOperation as UserOperationCapability | undefined;\n\n // If no userOperation, return option as-is\n if (!userOperation || !userOperation.supported) {\n return option;\n }\n\n // Transform price to include userOperation in extra\n const transformedPrice = await transformPrice(\n option.price,\n option.network,\n userOperation,\n schemeServer,\n );\n\n // Remove userOperation from PaymentOption.extra\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { userOperation: _, ...restExtra } = option.extra || {};\n\n return {\n ...option,\n price: transformedPrice,\n extra: Object.keys(restExtra).length > 0 ? restExtra : undefined,\n };\n}\n\n/**\n * Transforms a price to include userOperation in its extra field.\n *\n * @param price - The price to transform\n * @param network - The network the price is for\n * @param userOperation - The user operation to include in the price\n * @param schemeServer - The scheme server instance used for parsing prices\n * @returns The transformed price\n */\nasync function transformPrice(\n price: Price | DynamicPrice,\n network: Network,\n userOperation: UserOperationCapability,\n schemeServer: ExactEvmSchemeERC4337,\n): Promise<Price | DynamicPrice> {\n // Handle function price (DynamicPrice)\n if (typeof price === \"function\") {\n return async (context: HTTPRequestContext): Promise<Price> => {\n const resolvedPrice = await price(context);\n return await injectUserOperationIntoPrice(\n resolvedPrice,\n network,\n userOperation,\n schemeServer,\n );\n };\n }\n\n // Handle static price (string, number, or AssetAmount)\n return await injectUserOperationIntoPrice(price, network, userOperation, schemeServer);\n}\n\n/**\n * Injects userOperation into a price's extra field.\n * Handles both string/number prices (parsed to AssetAmount) and AssetAmount prices.\n *\n * @param price - The price to inject the user operation into\n * @param network - The network the price is for\n * @param userOperation - The user operation to include in the price\n * @param schemeServer - The scheme server instance used for parsing prices\n * @returns The transformed price\n */\nasync function injectUserOperationIntoPrice(\n price: Price,\n network: Network,\n userOperation: UserOperationCapability,\n schemeServer: ExactEvmSchemeERC4337,\n): Promise<Price> {\n // If price is already an AssetAmount, add userOperation to extra\n if (typeof price === \"object\" && \"asset\" in price && \"amount\" in price) {\n const assetAmount = price as AssetAmount;\n return {\n ...assetAmount,\n extra: {\n ...assetAmount.extra,\n userOperation,\n },\n };\n }\n\n // If price is string or number, parse it to AssetAmount\n // Note: We need to preserve the original format if possible\n // For now, we'll parse and return as AssetAmount\n // The scheme server will handle the conversion back if needed\n const assetAmount = await schemeServer.parsePrice(price, network);\n\n return {\n ...assetAmount,\n extra: {\n ...assetAmount.extra,\n userOperation,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA6BA,eAAsB,gCACpB,QACA,cACuB;AAEvB,MAAI,aAAa,QAAQ;AACvB,WAAO,MAAM,+BAA+B,QAAuB,YAAY;AAAA,EACjF;AAGA,QAAM,cAA2C,CAAC;AAClD,aAAW,CAAC,MAAM,WAAW,KAAK,OAAO,QAAQ,MAAqC,GAAG;AACvF,gBAAY,IAAI,IAAI,MAAM,+BAA+B,aAAa,YAAY;AAAA,EACpF;AACA,SAAO;AACT;AASA,eAAsB,+BACpB,aACA,cACsB;AAEtB,MAAI,CAAC,MAAM,QAAQ,YAAY,OAAO,GAAG;AACvC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,MAAM,uBAAuB,YAAY,SAAS,YAAY;AAAA,IACzE;AAAA,EACF;AAGA,QAAM,qBAAqB,MAAM,QAAQ;AAAA,IACvC,YAAY,QAAQ,IAAI,YAAU,uBAAuB,QAAQ,YAAY,CAAC;AAAA,EAChF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS;AAAA,EACX;AACF;AASA,eAAe,uBACb,QACA,cACwB;AAExB,QAAM,gBAAgB,OAAO,OAAO;AAGpC,MAAI,CAAC,iBAAiB,CAAC,cAAc,WAAW;AAC9C,WAAO;AAAA,EACT;AAGA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF;AAIA,QAAM,EAAE,eAAe,GAAG,GAAG,UAAU,IAAI,OAAO,SAAS,CAAC;AAE5D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,IACP,OAAO,OAAO,KAAK,SAAS,EAAE,SAAS,IAAI,YAAY;AAAA,EACzD;AACF;AAWA,eAAe,eACb,OACA,SACA,eACA,cAC+B;AAE/B,MAAI,OAAO,UAAU,YAAY;AAC/B,WAAO,OAAO,YAAgD;AAC5D,YAAM,gBAAgB,MAAM,MAAM,OAAO;AACzC,aAAO,MAAM;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,MAAM,6BAA6B,OAAO,SAAS,eAAe,YAAY;AACvF;AAYA,eAAe,6BACb,OACA,SACA,eACA,cACgB;AAEhB,MAAI,OAAO,UAAU,YAAY,WAAW,SAAS,YAAY,OAAO;AACtE,UAAMA,eAAc;AACpB,WAAO;AAAA,MACL,GAAGA;AAAA,MACH,OAAO;AAAA,QACL,GAAGA,aAAY;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAMA,QAAM,cAAc,MAAM,aAAa,WAAW,OAAO,OAAO;AAEhE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,YAAY;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;","names":["assetAmount"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ERC-4337 v0.7 User Operation structure
|
|
3
|
+
*/
|
|
4
|
+
interface UserOperation07Json {
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
sender: string;
|
|
7
|
+
nonce: string;
|
|
8
|
+
factory?: string;
|
|
9
|
+
factoryData?: string;
|
|
10
|
+
callData: string;
|
|
11
|
+
callGasLimit: string;
|
|
12
|
+
verificationGasLimit: string;
|
|
13
|
+
preVerificationGas: string;
|
|
14
|
+
maxFeePerGas: string;
|
|
15
|
+
maxPriorityFeePerGas: string;
|
|
16
|
+
paymaster?: string;
|
|
17
|
+
paymasterData?: string;
|
|
18
|
+
paymasterVerificationGasLimit?: string;
|
|
19
|
+
paymasterPostOpGasLimit?: string;
|
|
20
|
+
signature: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* ERC-4337 payload structure for x402 payments
|
|
24
|
+
*/
|
|
25
|
+
interface Erc4337Payload {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
type?: "erc4337";
|
|
28
|
+
entryPoint: string;
|
|
29
|
+
bundlerRpcUrl?: string;
|
|
30
|
+
userOperation: UserOperation07Json;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type { Erc4337Payload as E, UserOperation07Json as U };
|