@x402x/extensions 2.3.0 → 2.3.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.
@@ -0,0 +1,183 @@
1
+ import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@x402/core/types';
2
+ import { x402Client } from '@x402/core/client';
3
+
4
+ /**
5
+ * x402x EVM Client Scheme with Router Settlement
6
+ *
7
+ * This scheme extends the standard EVM exact scheme to support x402x router settlement.
8
+ * The key difference is using a commitment hash (binding all settlement parameters)
9
+ * as the EIP-3009 nonce instead of a random value.
10
+ */
11
+
12
+ /**
13
+ * Client EVM signer interface
14
+ * Compatible with viem WalletClient and LocalAccount
15
+ */
16
+ type ClientEvmSigner = {
17
+ readonly address: `0x${string}`;
18
+ signTypedData(message: {
19
+ domain: Record<string, unknown>;
20
+ types: Record<string, unknown>;
21
+ primaryType: string;
22
+ message: Record<string, unknown>;
23
+ }): Promise<`0x${string}`>;
24
+ };
25
+ /**
26
+ * EVM client implementation for the Exact payment scheme with x402x router settlement.
27
+ *
28
+ * This scheme uses a commitment hash as the EIP-3009 nonce to cryptographically bind
29
+ * all settlement parameters (salt, hook, hookData, etc.) to the user's signature,
30
+ * preventing parameter tampering attacks.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { ExactEvmSchemeWithRouterSettlement } from '@x402x/extensions/client';
35
+ * import { x402Client } from '@x402/core/client';
36
+ *
37
+ * const signer = { address, signTypedData }; // viem WalletClient or LocalAccount
38
+ * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
39
+ *
40
+ * const client = new x402Client()
41
+ * .register('eip155:84532', scheme);
42
+ * ```
43
+ */
44
+ declare class ExactEvmSchemeWithRouterSettlement implements SchemeNetworkClient {
45
+ private readonly signer;
46
+ readonly scheme = "exact";
47
+ /**
48
+ * Per-request router settlement extension (typically sourced from PaymentRequired.extensions).
49
+ *
50
+ * IMPORTANT: We do NOT put this on `paymentRequirements.extra`, because for x402 v2 the
51
+ * server matches paid requests by deep-equality between `paymentPayload.accepted` and the
52
+ * server-side `accepts[]`. Mutating `accepted` will cause "No matching payment requirements".
53
+ */
54
+ private routerSettlementFromPaymentRequired?;
55
+ /**
56
+ * Creates a new ExactEvmSchemeWithRouterSettlement instance.
57
+ *
58
+ * @param signer - The EVM signer for client operations (viem WalletClient or LocalAccount)
59
+ */
60
+ constructor(signer: ClientEvmSigner);
61
+ /**
62
+ * Set router-settlement extension data for the next payment payload creation.
63
+ *
64
+ * Intended to be called from an `x402Client.onBeforePaymentCreation` hook, which has access
65
+ * to `paymentRequired.extensions`.
66
+ */
67
+ setRouterSettlementExtensionFromPaymentRequired(ext: unknown | undefined): void;
68
+ /**
69
+ * Creates a payment payload for the Exact scheme with router settlement.
70
+ *
71
+ * This method:
72
+ * 1. Extracts settlement parameters from PaymentRequired.extensions
73
+ * 2. Calculates a commitment hash binding all parameters
74
+ * 3. Uses the commitment as the EIP-3009 nonce
75
+ * 4. Signs with settlementRouter as the 'to' address
76
+ *
77
+ * @param x402Version - The x402 protocol version (must be 2)
78
+ * @param paymentRequirements - The payment requirements from the server
79
+ * @returns Promise resolving to a payment payload
80
+ *
81
+ * @throws Error if x402Version is not 2
82
+ * @throws Error if x402x-router-settlement extension is missing
83
+ * @throws Error if required settlement parameters are missing
84
+ */
85
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
86
+ /**
87
+ * Sign the EIP-3009 authorization using EIP-712
88
+ *
89
+ * @param authorization - The authorization to sign
90
+ * @param requirements - The payment requirements
91
+ * @param chainId - The chain ID
92
+ * @returns Promise resolving to the signature
93
+ */
94
+ private signAuthorization;
95
+ }
96
+
97
+ /**
98
+ * x402x Extension Handler
99
+ *
100
+ * Provides utilities to integrate x402x router settlement with official x402 SDK.
101
+ *
102
+ * The challenge: x402 v2 spec places extensions at root level in PaymentRequired,
103
+ * but x402x scheme needs settlement parameters from PaymentRequirements.extra.
104
+ *
105
+ * Solution: Provide two-layer API:
106
+ * 1. High-level: registerX402xScheme() - one line setup (recommended)
107
+ * 2. Low-level: injectX402xExtensionHandler() - flexible configuration
108
+ */
109
+
110
+ /**
111
+ * Injects x402x extension handler into x402Client (Low-level API).
112
+ *
113
+ * IMPORTANT (x402 v2 + x402x multi-network):
114
+ * - Server returns per-option x402x info in `accepts[i].extra["x402x-router-settlement"]`
115
+ * - x402Client only passes `PaymentRequirements` to scheme (no root extensions)
116
+ * - Facilitator v2 reads from `paymentPayload.extensions["x402x-router-settlement"]`
117
+ *
118
+ * Solution: Copy the selected option's x402x info from `selectedRequirements.extra`
119
+ * into `paymentRequired.extensions` so it gets included in `paymentPayload.extensions`.
120
+ *
121
+ * This does NOT mutate `selectedRequirements` (which becomes `paymentPayload.accepted`),
122
+ * so v2 deepEqual matching still works.
123
+ *
124
+ * @param client - x402Client instance to inject handler into
125
+ * @param onRouterSettlementExtension - Callback to receive the per-request extension object
126
+ * @returns The same client instance for chaining
127
+ *
128
+ * @example Low-level API (for advanced users)
129
+ * ```typescript
130
+ * import { x402Client } from '@x402/core/client';
131
+ * import {
132
+ * injectX402xExtensionHandler,
133
+ * ExactEvmSchemeWithRouterSettlement
134
+ * } from '@x402x/extensions';
135
+ *
136
+ * const client = new x402Client();
137
+ * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
138
+ * injectX402xExtensionHandler(client, (ext) => scheme.setRouterSettlementExtensionFromPaymentRequired(ext))
139
+ * .register('eip155:84532', scheme);
140
+ * ```
141
+ */
142
+ declare function injectX402xExtensionHandler(client: x402Client, onRouterSettlementExtension?: (extension: unknown | undefined) => void): x402Client;
143
+ /**
144
+ * Register x402x router settlement scheme with automatic extension handling (High-level API).
145
+ *
146
+ * This is the recommended way to set up x402x payments. It combines:
147
+ * 1. Extension handler injection (injectX402xExtensionHandler)
148
+ * 2. Scheme registration (ExactEvmSchemeWithRouterSettlement)
149
+ *
150
+ * Use this for the simplest integration - just provide your signer and network.
151
+ *
152
+ * @param client - x402Client instance
153
+ * @param network - Network identifier in CAIP-2 format (e.g., "eip155:84532")
154
+ * @param signer - EVM signer with address and signTypedData method
155
+ * @returns The client instance for chaining
156
+ *
157
+ * @example High-level API (recommended)
158
+ * ```typescript
159
+ * import { x402Client } from '@x402/core/client';
160
+ * import { registerX402xScheme } from '@x402x/extensions';
161
+ * import { useWalletClient } from 'wagmi';
162
+ *
163
+ * const { data: walletClient } = useWalletClient();
164
+ *
165
+ * const client = new x402Client();
166
+ * registerX402xScheme(client, 'eip155:84532', {
167
+ * address: walletClient.account.address,
168
+ * signTypedData: walletClient.signTypedData,
169
+ * });
170
+ *
171
+ * // That's it! Client is ready for x402x payments
172
+ * ```
173
+ *
174
+ * @example Multiple networks
175
+ * ```typescript
176
+ * const client = new x402Client();
177
+ * registerX402xScheme(client, 'eip155:84532', signer); // Base Sepolia
178
+ * registerX402xScheme(client, 'eip155:8453', signer); // Base Mainnet
179
+ * ```
180
+ */
181
+ declare function registerX402xScheme(client: x402Client, network: Network, signer: ClientEvmSigner): x402Client;
182
+
183
+ export { type ClientEvmSigner, ExactEvmSchemeWithRouterSettlement, injectX402xExtensionHandler, registerX402xScheme };
@@ -0,0 +1,183 @@
1
+ import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@x402/core/types';
2
+ import { x402Client } from '@x402/core/client';
3
+
4
+ /**
5
+ * x402x EVM Client Scheme with Router Settlement
6
+ *
7
+ * This scheme extends the standard EVM exact scheme to support x402x router settlement.
8
+ * The key difference is using a commitment hash (binding all settlement parameters)
9
+ * as the EIP-3009 nonce instead of a random value.
10
+ */
11
+
12
+ /**
13
+ * Client EVM signer interface
14
+ * Compatible with viem WalletClient and LocalAccount
15
+ */
16
+ type ClientEvmSigner = {
17
+ readonly address: `0x${string}`;
18
+ signTypedData(message: {
19
+ domain: Record<string, unknown>;
20
+ types: Record<string, unknown>;
21
+ primaryType: string;
22
+ message: Record<string, unknown>;
23
+ }): Promise<`0x${string}`>;
24
+ };
25
+ /**
26
+ * EVM client implementation for the Exact payment scheme with x402x router settlement.
27
+ *
28
+ * This scheme uses a commitment hash as the EIP-3009 nonce to cryptographically bind
29
+ * all settlement parameters (salt, hook, hookData, etc.) to the user's signature,
30
+ * preventing parameter tampering attacks.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { ExactEvmSchemeWithRouterSettlement } from '@x402x/extensions/client';
35
+ * import { x402Client } from '@x402/core/client';
36
+ *
37
+ * const signer = { address, signTypedData }; // viem WalletClient or LocalAccount
38
+ * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
39
+ *
40
+ * const client = new x402Client()
41
+ * .register('eip155:84532', scheme);
42
+ * ```
43
+ */
44
+ declare class ExactEvmSchemeWithRouterSettlement implements SchemeNetworkClient {
45
+ private readonly signer;
46
+ readonly scheme = "exact";
47
+ /**
48
+ * Per-request router settlement extension (typically sourced from PaymentRequired.extensions).
49
+ *
50
+ * IMPORTANT: We do NOT put this on `paymentRequirements.extra`, because for x402 v2 the
51
+ * server matches paid requests by deep-equality between `paymentPayload.accepted` and the
52
+ * server-side `accepts[]`. Mutating `accepted` will cause "No matching payment requirements".
53
+ */
54
+ private routerSettlementFromPaymentRequired?;
55
+ /**
56
+ * Creates a new ExactEvmSchemeWithRouterSettlement instance.
57
+ *
58
+ * @param signer - The EVM signer for client operations (viem WalletClient or LocalAccount)
59
+ */
60
+ constructor(signer: ClientEvmSigner);
61
+ /**
62
+ * Set router-settlement extension data for the next payment payload creation.
63
+ *
64
+ * Intended to be called from an `x402Client.onBeforePaymentCreation` hook, which has access
65
+ * to `paymentRequired.extensions`.
66
+ */
67
+ setRouterSettlementExtensionFromPaymentRequired(ext: unknown | undefined): void;
68
+ /**
69
+ * Creates a payment payload for the Exact scheme with router settlement.
70
+ *
71
+ * This method:
72
+ * 1. Extracts settlement parameters from PaymentRequired.extensions
73
+ * 2. Calculates a commitment hash binding all parameters
74
+ * 3. Uses the commitment as the EIP-3009 nonce
75
+ * 4. Signs with settlementRouter as the 'to' address
76
+ *
77
+ * @param x402Version - The x402 protocol version (must be 2)
78
+ * @param paymentRequirements - The payment requirements from the server
79
+ * @returns Promise resolving to a payment payload
80
+ *
81
+ * @throws Error if x402Version is not 2
82
+ * @throws Error if x402x-router-settlement extension is missing
83
+ * @throws Error if required settlement parameters are missing
84
+ */
85
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
86
+ /**
87
+ * Sign the EIP-3009 authorization using EIP-712
88
+ *
89
+ * @param authorization - The authorization to sign
90
+ * @param requirements - The payment requirements
91
+ * @param chainId - The chain ID
92
+ * @returns Promise resolving to the signature
93
+ */
94
+ private signAuthorization;
95
+ }
96
+
97
+ /**
98
+ * x402x Extension Handler
99
+ *
100
+ * Provides utilities to integrate x402x router settlement with official x402 SDK.
101
+ *
102
+ * The challenge: x402 v2 spec places extensions at root level in PaymentRequired,
103
+ * but x402x scheme needs settlement parameters from PaymentRequirements.extra.
104
+ *
105
+ * Solution: Provide two-layer API:
106
+ * 1. High-level: registerX402xScheme() - one line setup (recommended)
107
+ * 2. Low-level: injectX402xExtensionHandler() - flexible configuration
108
+ */
109
+
110
+ /**
111
+ * Injects x402x extension handler into x402Client (Low-level API).
112
+ *
113
+ * IMPORTANT (x402 v2 + x402x multi-network):
114
+ * - Server returns per-option x402x info in `accepts[i].extra["x402x-router-settlement"]`
115
+ * - x402Client only passes `PaymentRequirements` to scheme (no root extensions)
116
+ * - Facilitator v2 reads from `paymentPayload.extensions["x402x-router-settlement"]`
117
+ *
118
+ * Solution: Copy the selected option's x402x info from `selectedRequirements.extra`
119
+ * into `paymentRequired.extensions` so it gets included in `paymentPayload.extensions`.
120
+ *
121
+ * This does NOT mutate `selectedRequirements` (which becomes `paymentPayload.accepted`),
122
+ * so v2 deepEqual matching still works.
123
+ *
124
+ * @param client - x402Client instance to inject handler into
125
+ * @param onRouterSettlementExtension - Callback to receive the per-request extension object
126
+ * @returns The same client instance for chaining
127
+ *
128
+ * @example Low-level API (for advanced users)
129
+ * ```typescript
130
+ * import { x402Client } from '@x402/core/client';
131
+ * import {
132
+ * injectX402xExtensionHandler,
133
+ * ExactEvmSchemeWithRouterSettlement
134
+ * } from '@x402x/extensions';
135
+ *
136
+ * const client = new x402Client();
137
+ * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
138
+ * injectX402xExtensionHandler(client, (ext) => scheme.setRouterSettlementExtensionFromPaymentRequired(ext))
139
+ * .register('eip155:84532', scheme);
140
+ * ```
141
+ */
142
+ declare function injectX402xExtensionHandler(client: x402Client, onRouterSettlementExtension?: (extension: unknown | undefined) => void): x402Client;
143
+ /**
144
+ * Register x402x router settlement scheme with automatic extension handling (High-level API).
145
+ *
146
+ * This is the recommended way to set up x402x payments. It combines:
147
+ * 1. Extension handler injection (injectX402xExtensionHandler)
148
+ * 2. Scheme registration (ExactEvmSchemeWithRouterSettlement)
149
+ *
150
+ * Use this for the simplest integration - just provide your signer and network.
151
+ *
152
+ * @param client - x402Client instance
153
+ * @param network - Network identifier in CAIP-2 format (e.g., "eip155:84532")
154
+ * @param signer - EVM signer with address and signTypedData method
155
+ * @returns The client instance for chaining
156
+ *
157
+ * @example High-level API (recommended)
158
+ * ```typescript
159
+ * import { x402Client } from '@x402/core/client';
160
+ * import { registerX402xScheme } from '@x402x/extensions';
161
+ * import { useWalletClient } from 'wagmi';
162
+ *
163
+ * const { data: walletClient } = useWalletClient();
164
+ *
165
+ * const client = new x402Client();
166
+ * registerX402xScheme(client, 'eip155:84532', {
167
+ * address: walletClient.account.address,
168
+ * signTypedData: walletClient.signTypedData,
169
+ * });
170
+ *
171
+ * // That's it! Client is ready for x402x payments
172
+ * ```
173
+ *
174
+ * @example Multiple networks
175
+ * ```typescript
176
+ * const client = new x402Client();
177
+ * registerX402xScheme(client, 'eip155:84532', signer); // Base Sepolia
178
+ * registerX402xScheme(client, 'eip155:8453', signer); // Base Mainnet
179
+ * ```
180
+ */
181
+ declare function registerX402xScheme(client: x402Client, network: Network, signer: ClientEvmSigner): x402Client;
182
+
183
+ export { type ClientEvmSigner, ExactEvmSchemeWithRouterSettlement, injectX402xExtensionHandler, registerX402xScheme };
@@ -0,0 +1,255 @@
1
+ 'use strict';
2
+
3
+ var viem = require('viem');
4
+
5
+ // src/client/exact-evm-scheme.ts
6
+ function calculateCommitment(params) {
7
+ return viem.keccak256(
8
+ viem.encodePacked(
9
+ [
10
+ "string",
11
+ // Protocol identifier
12
+ "uint256",
13
+ // Chain ID
14
+ "address",
15
+ // Hub address
16
+ "address",
17
+ // Token address
18
+ "address",
19
+ // From (payer)
20
+ "uint256",
21
+ // Value
22
+ "uint256",
23
+ // Valid after
24
+ "uint256",
25
+ // Valid before
26
+ "bytes32",
27
+ // Salt
28
+ "address",
29
+ // Pay to
30
+ "uint256",
31
+ // Facilitator fee
32
+ "address",
33
+ // Hook
34
+ "bytes32"
35
+ // keccak256(hookData)
36
+ ],
37
+ [
38
+ "X402/settle/v1",
39
+ BigInt(params.chainId),
40
+ params.hub,
41
+ params.asset,
42
+ params.from,
43
+ BigInt(params.value),
44
+ BigInt(params.validAfter),
45
+ BigInt(params.validBefore),
46
+ params.salt,
47
+ params.payTo,
48
+ BigInt(params.facilitatorFee),
49
+ params.hook,
50
+ viem.keccak256(params.hookData)
51
+ ]
52
+ )
53
+ );
54
+ }
55
+
56
+ // src/server-extension.ts
57
+ var ROUTER_SETTLEMENT_KEY = "x402x-router-settlement";
58
+
59
+ // src/client/exact-evm-scheme.ts
60
+ var authorizationTypes = {
61
+ TransferWithAuthorization: [
62
+ { name: "from", type: "address" },
63
+ { name: "to", type: "address" },
64
+ { name: "value", type: "uint256" },
65
+ { name: "validAfter", type: "uint256" },
66
+ { name: "validBefore", type: "uint256" },
67
+ { name: "nonce", type: "bytes32" }
68
+ ]
69
+ };
70
+ var ExactEvmSchemeWithRouterSettlement = class {
71
+ /**
72
+ * Creates a new ExactEvmSchemeWithRouterSettlement instance.
73
+ *
74
+ * @param signer - The EVM signer for client operations (viem WalletClient or LocalAccount)
75
+ */
76
+ constructor(signer) {
77
+ this.signer = signer;
78
+ this.scheme = "exact";
79
+ }
80
+ /**
81
+ * Set router-settlement extension data for the next payment payload creation.
82
+ *
83
+ * Intended to be called from an `x402Client.onBeforePaymentCreation` hook, which has access
84
+ * to `paymentRequired.extensions`.
85
+ */
86
+ setRouterSettlementExtensionFromPaymentRequired(ext) {
87
+ if (!ext) {
88
+ this.routerSettlementFromPaymentRequired = void 0;
89
+ return;
90
+ }
91
+ this.routerSettlementFromPaymentRequired = ext;
92
+ }
93
+ /**
94
+ * Creates a payment payload for the Exact scheme with router settlement.
95
+ *
96
+ * This method:
97
+ * 1. Extracts settlement parameters from PaymentRequired.extensions
98
+ * 2. Calculates a commitment hash binding all parameters
99
+ * 3. Uses the commitment as the EIP-3009 nonce
100
+ * 4. Signs with settlementRouter as the 'to' address
101
+ *
102
+ * @param x402Version - The x402 protocol version (must be 2)
103
+ * @param paymentRequirements - The payment requirements from the server
104
+ * @returns Promise resolving to a payment payload
105
+ *
106
+ * @throws Error if x402Version is not 2
107
+ * @throws Error if x402x-router-settlement extension is missing
108
+ * @throws Error if required settlement parameters are missing
109
+ */
110
+ async createPaymentPayload(x402Version, paymentRequirements) {
111
+ if (x402Version !== 2) {
112
+ throw new Error(
113
+ `ExactEvmSchemeWithRouterSettlement only supports x402 version 2, got: ${x402Version}`
114
+ );
115
+ }
116
+ const routerSettlement = paymentRequirements.extra?.[ROUTER_SETTLEMENT_KEY] ?? this.routerSettlementFromPaymentRequired;
117
+ if (!routerSettlement?.info) {
118
+ throw new Error(
119
+ "x402x-router-settlement extension not available for scheme signing. Ensure the resource server includes the extension in PaymentRequired.extensions and the client registered x402x via registerX402xScheme() (or injected the handler)."
120
+ );
121
+ }
122
+ const { salt, settlementRouter, hook, hookData, finalPayTo, facilitatorFee } = routerSettlement.info;
123
+ this.routerSettlementFromPaymentRequired = void 0;
124
+ if (!salt) throw new Error("Missing required parameter: salt");
125
+ if (!settlementRouter) throw new Error("Missing required parameter: settlementRouter");
126
+ if (!hook) throw new Error("Missing required parameter: hook");
127
+ if (hookData === void 0) throw new Error("Missing required parameter: hookData");
128
+ if (!finalPayTo) throw new Error("Missing required parameter: finalPayTo");
129
+ const resolvedFacilitatorFee = facilitatorFee ?? "0";
130
+ const chainId = parseInt(paymentRequirements.network.split(":")[1]);
131
+ if (isNaN(chainId)) {
132
+ throw new Error(`Invalid network format: ${paymentRequirements.network}`);
133
+ }
134
+ const now = Math.floor(Date.now() / 1e3);
135
+ const validAfter = (now - 600).toString();
136
+ const validBefore = (now + paymentRequirements.maxTimeoutSeconds).toString();
137
+ const commitmentParams = {
138
+ chainId,
139
+ hub: settlementRouter,
140
+ asset: paymentRequirements.asset,
141
+ from: this.signer.address,
142
+ value: paymentRequirements.amount,
143
+ validAfter,
144
+ validBefore,
145
+ salt,
146
+ payTo: finalPayTo,
147
+ facilitatorFee: resolvedFacilitatorFee,
148
+ hook,
149
+ hookData
150
+ };
151
+ const nonce = calculateCommitment(commitmentParams);
152
+ const authorization = {
153
+ from: this.signer.address,
154
+ to: viem.getAddress(settlementRouter),
155
+ value: paymentRequirements.amount,
156
+ validAfter,
157
+ validBefore,
158
+ nonce
159
+ };
160
+ const signature = await this.signAuthorization(authorization, paymentRequirements, chainId);
161
+ const payload = {
162
+ authorization,
163
+ signature
164
+ };
165
+ return {
166
+ x402Version,
167
+ payload
168
+ };
169
+ }
170
+ /**
171
+ * Sign the EIP-3009 authorization using EIP-712
172
+ *
173
+ * @param authorization - The authorization to sign
174
+ * @param requirements - The payment requirements
175
+ * @param chainId - The chain ID
176
+ * @returns Promise resolving to the signature
177
+ */
178
+ async signAuthorization(authorization, requirements, chainId) {
179
+ if (!requirements.extra?.name || !requirements.extra?.version) {
180
+ throw new Error(
181
+ `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
182
+ );
183
+ }
184
+ const { name, version } = requirements.extra;
185
+ const domain = {
186
+ name,
187
+ version,
188
+ chainId,
189
+ verifyingContract: viem.getAddress(requirements.asset)
190
+ };
191
+ const message = {
192
+ from: viem.getAddress(authorization.from),
193
+ to: viem.getAddress(authorization.to),
194
+ value: BigInt(authorization.value),
195
+ validAfter: BigInt(authorization.validAfter),
196
+ validBefore: BigInt(authorization.validBefore),
197
+ nonce: authorization.nonce
198
+ };
199
+ return await this.signer.signTypedData({
200
+ domain,
201
+ types: authorizationTypes,
202
+ primaryType: "TransferWithAuthorization",
203
+ message
204
+ });
205
+ }
206
+ };
207
+
208
+ // src/client/extension-handler.ts
209
+ function injectX402xExtensionHandler(client, onRouterSettlementExtension) {
210
+ return client.onBeforePaymentCreation(async (context) => {
211
+ const { paymentRequired, selectedRequirements } = context;
212
+ console.log("[x402x-handler] onBeforePaymentCreation called");
213
+ console.log("[x402x-handler] selectedRequirements.network:", selectedRequirements.network);
214
+ console.log(
215
+ "[x402x-handler] selectedRequirements.extra keys:",
216
+ Object.keys(selectedRequirements.extra || {})
217
+ );
218
+ const perOptionExtension = selectedRequirements.extra?.[ROUTER_SETTLEMENT_KEY];
219
+ if (perOptionExtension) {
220
+ if (!paymentRequired.extensions) {
221
+ paymentRequired.extensions = {};
222
+ }
223
+ paymentRequired.extensions[ROUTER_SETTLEMENT_KEY] = perOptionExtension;
224
+ console.log(
225
+ "[x402x-handler] \u2705 Copied per-option x402x info into PaymentRequired.extensions"
226
+ );
227
+ console.log("[x402x-handler] Extension info:", JSON.stringify(perOptionExtension, null, 2));
228
+ } else {
229
+ console.warn(
230
+ "[x402x-handler] \u26A0\uFE0F No per-option x402x info found in selectedRequirements.extra"
231
+ );
232
+ console.warn(
233
+ "[x402x-handler] This may cause facilitator errors. Check server-side createSettlementRouteConfig."
234
+ );
235
+ }
236
+ if (onRouterSettlementExtension) {
237
+ const extensionToUse = perOptionExtension || paymentRequired.extensions?.[ROUTER_SETTLEMENT_KEY];
238
+ onRouterSettlementExtension(extensionToUse);
239
+ }
240
+ });
241
+ }
242
+ function registerX402xScheme(client, network, signer) {
243
+ const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
244
+ injectX402xExtensionHandler(client, (ext) => {
245
+ scheme.setRouterSettlementExtensionFromPaymentRequired(ext);
246
+ });
247
+ client.register(network, scheme);
248
+ return client;
249
+ }
250
+
251
+ exports.ExactEvmSchemeWithRouterSettlement = ExactEvmSchemeWithRouterSettlement;
252
+ exports.injectX402xExtensionHandler = injectX402xExtensionHandler;
253
+ exports.registerX402xScheme = registerX402xScheme;
254
+ //# sourceMappingURL=index.js.map
255
+ //# sourceMappingURL=index.js.map