@wtflabs/x402 0.0.1-beta.4 → 0.0.1-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/client/index.d.ts +1 -1
  2. package/dist/cjs/client/index.js +6 -1
  3. package/dist/cjs/client/index.js.map +1 -1
  4. package/dist/cjs/facilitator/index.d.ts +1 -1
  5. package/dist/cjs/facilitator/index.js +119 -6
  6. package/dist/cjs/facilitator/index.js.map +1 -1
  7. package/dist/cjs/index.d.ts +1 -1
  8. package/dist/cjs/index.js +119 -6
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/{middleware-Brgsx32F.d.ts → middleware-nzDe-TDJ.d.ts} +1 -1
  11. package/dist/cjs/paywall/index.d.ts +1 -1
  12. package/dist/cjs/schemes/index.d.ts +25 -7
  13. package/dist/cjs/schemes/index.js +151 -13
  14. package/dist/cjs/schemes/index.js.map +1 -1
  15. package/dist/cjs/shared/index.d.ts +2 -2
  16. package/dist/cjs/shared/index.js +6 -1
  17. package/dist/cjs/shared/index.js.map +1 -1
  18. package/dist/cjs/types/index.d.ts +93 -4
  19. package/dist/cjs/types/index.js +64 -1
  20. package/dist/cjs/types/index.js.map +1 -1
  21. package/dist/cjs/verify/index.d.ts +2 -2
  22. package/dist/cjs/verify/index.js +6 -1
  23. package/dist/cjs/verify/index.js.map +1 -1
  24. package/dist/{esm/x402Specs-CYq5tSY1.d.mts → cjs/x402Specs-BtRXj67U.d.ts} +43 -10
  25. package/dist/esm/{chunk-RX2JKK4O.mjs → chunk-J3FMDNC3.mjs} +2 -2
  26. package/dist/esm/{chunk-34YNR4LY.mjs → chunk-K5SAFQCZ.mjs} +3 -3
  27. package/dist/esm/{chunk-UCBE7FDY.mjs → chunk-NPWDNT2P.mjs} +67 -2
  28. package/dist/esm/chunk-NPWDNT2P.mjs.map +1 -0
  29. package/dist/esm/{chunk-G6WN2WYX.mjs → chunk-TAYXZJPR.mjs} +101 -16
  30. package/dist/esm/chunk-TAYXZJPR.mjs.map +1 -0
  31. package/dist/esm/{chunk-2AM3S66N.mjs → chunk-URGZOTVQ.mjs} +3 -3
  32. package/dist/esm/client/index.d.mts +1 -1
  33. package/dist/esm/client/index.mjs +3 -3
  34. package/dist/esm/facilitator/index.d.mts +1 -1
  35. package/dist/esm/facilitator/index.mjs +4 -4
  36. package/dist/esm/index.d.mts +1 -1
  37. package/dist/esm/index.mjs +5 -5
  38. package/dist/esm/{middleware-BSjsPDKM.d.mts → middleware-DSDucaQ5.d.mts} +1 -1
  39. package/dist/esm/paywall/index.d.mts +1 -1
  40. package/dist/esm/schemes/index.d.mts +25 -7
  41. package/dist/esm/schemes/index.mjs +3 -3
  42. package/dist/esm/shared/index.d.mts +2 -2
  43. package/dist/esm/shared/index.mjs +1 -1
  44. package/dist/esm/types/index.d.mts +93 -4
  45. package/dist/esm/types/index.mjs +1 -1
  46. package/dist/esm/verify/index.d.mts +2 -2
  47. package/dist/esm/verify/index.mjs +1 -1
  48. package/dist/{cjs/x402Specs-CYq5tSY1.d.ts → esm/x402Specs-BtRXj67U.d.mts} +43 -10
  49. package/package.json +15 -15
  50. package/dist/cjs/middleware-6_1ApcJn.d.ts +0 -93
  51. package/dist/cjs/middleware-B_ewwsQp.d.ts +0 -93
  52. package/dist/cjs/middleware-BwfW7mAs.d.ts +0 -93
  53. package/dist/cjs/middleware-CQb61c1k.d.ts +0 -93
  54. package/dist/cjs/middleware-DB9lqy9f.d.ts +0 -93
  55. package/dist/cjs/middleware-DcHctwQV.d.ts +0 -93
  56. package/dist/cjs/middleware-De0jD3Bp.d.ts +0 -93
  57. package/dist/cjs/middleware-HoFOmpgv.d.ts +0 -93
  58. package/dist/cjs/middleware-Y8AiAfYw.d.ts +0 -93
  59. package/dist/cjs/middleware-pnres9YM.d.ts +0 -93
  60. package/dist/cjs/network-RtNddYQk.d.ts +0 -11
  61. package/dist/cjs/rpc-Ca8eHCWz.d.ts +0 -35
  62. package/dist/cjs/wallet-BRWfOM5D.d.ts +0 -153
  63. package/dist/cjs/wallet-BYRAGtOB.d.ts +0 -153
  64. package/dist/cjs/wallet-BmEtlgEf.d.ts +0 -48
  65. package/dist/cjs/wallet-CNOAmyZ6.d.ts +0 -48
  66. package/dist/cjs/wallet-D1SoxFTw.d.ts +0 -48
  67. package/dist/cjs/wallet-SJ-hbjm9.d.ts +0 -153
  68. package/dist/cjs/wallet-ecnda4Aj.d.ts +0 -48
  69. package/dist/cjs/wallet-gP8Qoi-c.d.ts +0 -74
  70. package/dist/cjs/x402Specs-B7InXo2L.d.ts +0 -1065
  71. package/dist/cjs/x402Specs-BLH3j34O.d.ts +0 -1696
  72. package/dist/cjs/x402Specs-C7LipAZg.d.ts +0 -1715
  73. package/dist/cjs/x402Specs-CeajqonG.d.ts +0 -1696
  74. package/dist/cjs/x402Specs-qMujgEV5.d.ts +0 -1715
  75. package/dist/cjs/x402Specs-qUBCpcuz.d.ts +0 -1715
  76. package/dist/esm/chunk-G6WN2WYX.mjs.map +0 -1
  77. package/dist/esm/chunk-UCBE7FDY.mjs.map +0 -1
  78. /package/dist/esm/{chunk-RX2JKK4O.mjs.map → chunk-J3FMDNC3.mjs.map} +0 -0
  79. /package/dist/esm/{chunk-34YNR4LY.mjs.map → chunk-K5SAFQCZ.mjs.map} +0 -0
  80. /package/dist/esm/{chunk-2AM3S66N.mjs.map → chunk-URGZOTVQ.mjs.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { N as Network } from './network-FrFmmiyj.js';
3
3
  import { E as EvmSigner } from './wallet-SJKJpUgQ.js';
4
- import { a as PaymentPayload, P as PaymentRequirements, J as VerifyResponse, S as SettleResponse, X as SupportedPaymentKindsResponse, M as ListDiscoveryResourcesRequest, O as ListDiscoveryResourcesResponse, z as HTTPRequestStructure } from './x402Specs-CYq5tSY1.js';
4
+ import { a as PaymentPayload, P as PaymentRequirements, J as VerifyResponse, S as SettleResponse, X as SupportedPaymentKindsResponse, M as ListDiscoveryResourcesRequest, O as ListDiscoveryResourcesResponse, z as HTTPRequestStructure } from './x402Specs-BtRXj67U.js';
5
5
 
6
6
  declare const moneySchema: z.ZodPipeline<z.ZodUnion<[z.ZodEffects<z.ZodString, string, string>, z.ZodNumber]>, z.ZodNumber>;
7
7
  type Money = z.input<typeof moneySchema>;
@@ -1,4 +1,4 @@
1
- import { P as PaymentRequirements } from '../x402Specs-CYq5tSY1.js';
1
+ import { P as PaymentRequirements } from '../x402Specs-BtRXj67U.js';
2
2
  import 'zod';
3
3
 
4
4
  interface PaywallOptions {
@@ -1,6 +1,6 @@
1
1
  import { Address, Transport, Chain, LocalAccount, Hex, Account } from 'viem';
2
2
  import { S as SignerWallet, C as ConnectedClient } from '../wallet-SJKJpUgQ.js';
3
- import { P as PaymentRequirements, p as UnsignedEip3009PaymentPayload, o as Eip3009PaymentPayload, e as ExactEvmPayloadAuthorization, J as VerifyResponse, S as SettleResponse, r as UnsignedPermitPaymentPayload, q as PermitPaymentPayload, g as PermitEvmPayloadAuthorization, u as UnsignedPermit2PaymentPayload, t as Permit2PaymentPayload, i as Permit2EvmPayloadAuthorization, a as PaymentPayload, b as ErrorReasons, E as ExactSvmPayload } from '../x402Specs-CYq5tSY1.js';
3
+ import { P as PaymentRequirements, p as UnsignedEip3009PaymentPayload, o as Eip3009PaymentPayload, e as ExactEvmPayloadAuthorization, J as VerifyResponse, S as SettleResponse, r as UnsignedPermitPaymentPayload, q as PermitPaymentPayload, g as PermitEvmPayloadAuthorization, u as UnsignedPermit2PaymentPayload, t as Permit2PaymentPayload, i as Permit2EvmPayloadAuthorization, a as PaymentPayload, b as ErrorReasons, E as ExactSvmPayload } from '../x402Specs-BtRXj67U.js';
4
4
  import { X as X402Config } from '../config-Dfuvno71.js';
5
5
  import { KeyPairSigner, signTransaction, RpcDevnet, SolanaRpcApiDevnet, RpcMainnet, SolanaRpcApiMainnet, SendTransactionApi, CompilableTransactionMessage, Instruction, AccountLookupMeta, AccountMeta } from '@solana/kit';
6
6
  import { b as getRpcSubscriptions } from '../rpc-BMvnNNHd.js';
@@ -204,17 +204,23 @@ declare namespace index$4 {
204
204
  }
205
205
 
206
206
  /**
207
- * Prepares an unsigned Permit2 payment header
207
+ * Prepares an unsigned Permit2 payment header with witness support
208
+ *
209
+ * By default, this function enables witness mode which binds the recipient address
210
+ * to the signature, preventing the facilitator from changing the payment destination.
208
211
  *
209
212
  * @param from - The token owner's address
210
213
  * @param x402Version - The version of the X402 protocol to use
211
214
  * @param paymentRequirements - The payment requirements containing scheme and network information
212
- * @returns An unsigned Permit2 payment payload containing permit2 authorization details
215
+ * @returns An unsigned Permit2 payment payload containing permit2 authorization details with witness
213
216
  */
214
217
  declare function preparePaymentHeader(from: Address, x402Version: number, paymentRequirements: PaymentRequirements): UnsignedPermit2PaymentPayload;
215
218
  /**
216
219
  * Signs a Permit2 payment header using the provided client and payment requirements.
217
220
  *
221
+ * Supports both witness and non-witness modes based on the presence of the `to` field
222
+ * in the unsigned payment header.
223
+ *
218
224
  * @param client - The signer wallet instance used to sign the permit2
219
225
  * @param paymentRequirements - The payment requirements containing scheme and network information
220
226
  * @param unsignedPaymentHeader - The unsigned Permit2 payment payload to be signed
@@ -241,7 +247,11 @@ declare function createPayment<transport extends Transport, chain extends Chain>
241
247
  declare function createPaymentHeader$1(client: SignerWallet | LocalAccount, x402Version: number, paymentRequirements: PaymentRequirements): Promise<string>;
242
248
 
243
249
  /**
244
- * Signs a Permit2 PermitTransferFrom authorization
250
+ * Signs a Permit2 authorization (PermitTransferFrom or PermitWitnessTransferFrom)
251
+ *
252
+ * Automatically detects witness mode based on the presence of the `to` field.
253
+ * - If `to` is provided: Uses PermitWitnessTransferFrom (binds recipient to signature)
254
+ * - If `to` is omitted: Uses PermitTransferFrom (legacy mode)
245
255
  *
246
256
  * @param walletClient - The wallet client that will sign the permit
247
257
  * @param params - The permit2 parameters
@@ -250,11 +260,12 @@ declare function createPaymentHeader$1(client: SignerWallet | LocalAccount, x402
250
260
  * @param params.token - The address of the token to transfer
251
261
  * @param params.amount - The amount of tokens to transfer (in base units)
252
262
  * @param params.deadline - Unix timestamp after which the permit is no longer valid
263
+ * @param params.to - Optional recipient address for witness mode
253
264
  * @param paymentRequirements - The payment requirements containing network information
254
265
  * @param paymentRequirements.network - The network where the token exists
255
266
  * @returns The signature and nonce for the permit2
256
267
  */
257
- declare function signPermit2<transport extends Transport, chain extends Chain>(walletClient: SignerWallet<chain, transport> | LocalAccount, { owner, spender, token, amount, deadline }: Omit<Permit2EvmPayloadAuthorization, "nonce">, { network }: PaymentRequirements): Promise<{
268
+ declare function signPermit2<transport extends Transport, chain extends Chain>(walletClient: SignerWallet<chain, transport> | LocalAccount, { owner, spender, token, amount, deadline, to }: Omit<Permit2EvmPayloadAuthorization, "nonce">, { network }: PaymentRequirements): Promise<{
258
269
  signature: Hex;
259
270
  nonce: string;
260
271
  }>;
@@ -269,7 +280,11 @@ declare function signPermit2<transport extends Transport, chain extends Chain>(w
269
280
  declare function createPermit2Nonce<transport extends Transport, chain extends Chain>(walletClient: SignerWallet<chain, transport> | LocalAccount, ownerAddress: `0x${string}`): Promise<bigint>;
270
281
 
271
282
  /**
272
- * Verifies a Permit2 payment payload
283
+ * Verifies a Permit2 payment payload (with or without witness)
284
+ *
285
+ * Supports both witness and non-witness modes:
286
+ * - Witness mode: Verifies that the recipient address is bound to the signature
287
+ * - Non-witness mode: Uses standard PermitTransferFrom verification
273
288
  *
274
289
  * @param client - The public client used for blockchain interactions
275
290
  * @param payload - The signed payment payload containing permit2 parameters and signature
@@ -278,7 +293,10 @@ declare function createPermit2Nonce<transport extends Transport, chain extends C
278
293
  */
279
294
  declare function verify$2<transport extends Transport, chain extends Chain, account extends Account | undefined>(client: ConnectedClient<transport, chain, account>, payload: Permit2PaymentPayload, paymentRequirements: PaymentRequirements): Promise<VerifyResponse>;
280
295
  /**
281
- * Settles a Permit2 payment by calling permitTransferFrom()
296
+ * Settles a Permit2 payment by calling permitTransferFrom() or permitWitnessTransferFrom()
297
+ *
298
+ * Automatically selects the appropriate function based on whether the payment includes
299
+ * a witness (recipient address binding).
282
300
  *
283
301
  * @param wallet - The facilitator wallet that will execute the permit transfer
284
302
  * @param paymentPayload - The signed payment payload containing permit2 parameters and signature
@@ -357,6 +357,21 @@ var permit2Types = {
357
357
  { name: "amount", type: "uint256" }
358
358
  ]
359
359
  };
360
+ var permit2WitnessTypes = {
361
+ PermitWitnessTransferFrom: [
362
+ { name: "permitted", type: "TokenPermissions" },
363
+ { name: "spender", type: "address" },
364
+ { name: "nonce", type: "uint256" },
365
+ { name: "deadline", type: "uint256" },
366
+ { name: "witness", type: "Witness" }
367
+ ],
368
+ TokenPermissions: [
369
+ { name: "token", type: "address" },
370
+ { name: "amount", type: "uint256" }
371
+ ],
372
+ Witness: [{ name: "to", type: "address" }]
373
+ };
374
+ var WITNESS_TYPE_STRING = "Witness(address to)";
360
375
  var permit2ABI = [
361
376
  {
362
377
  inputs: [
@@ -426,6 +441,45 @@ var permit2ABI = [
426
441
  outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
427
442
  stateMutability: "view",
428
443
  type: "function"
444
+ },
445
+ {
446
+ inputs: [
447
+ {
448
+ components: [
449
+ {
450
+ components: [
451
+ { internalType: "address", name: "token", type: "address" },
452
+ { internalType: "uint256", name: "amount", type: "uint256" }
453
+ ],
454
+ internalType: "struct ISignatureTransfer.TokenPermissions",
455
+ name: "permitted",
456
+ type: "tuple"
457
+ },
458
+ { internalType: "uint256", name: "nonce", type: "uint256" },
459
+ { internalType: "uint256", name: "deadline", type: "uint256" }
460
+ ],
461
+ internalType: "struct ISignatureTransfer.PermitTransferFrom",
462
+ name: "permit",
463
+ type: "tuple"
464
+ },
465
+ {
466
+ components: [
467
+ { internalType: "address", name: "to", type: "address" },
468
+ { internalType: "uint256", name: "requestedAmount", type: "uint256" }
469
+ ],
470
+ internalType: "struct ISignatureTransfer.SignatureTransferDetails",
471
+ name: "transferDetails",
472
+ type: "tuple"
473
+ },
474
+ { internalType: "address", name: "owner", type: "address" },
475
+ { internalType: "bytes32", name: "witness", type: "bytes32" },
476
+ { internalType: "string", name: "witnessTypeString", type: "string" },
477
+ { internalType: "bytes", name: "signature", type: "bytes" }
478
+ ],
479
+ name: "permitWitnessTransferFrom",
480
+ outputs: [],
481
+ stateMutability: "nonpayable",
482
+ type: "function"
429
483
  }
430
484
  ];
431
485
 
@@ -1243,6 +1297,8 @@ var ErrorReasons = [
1243
1297
  "invalid_authorization_type",
1244
1298
  "invalid_permit_signature",
1245
1299
  "invalid_permit2_signature",
1300
+ "invalid_permit2_witness_signature",
1301
+ "witness_recipient_mismatch",
1246
1302
  "permit_expired",
1247
1303
  "permit2_expired",
1248
1304
  "permit2_not_approved",
@@ -1250,6 +1306,7 @@ var ErrorReasons = [
1250
1306
  "invalid_spender_address",
1251
1307
  "token_mismatch",
1252
1308
  "insufficient_payment_amount",
1309
+ "insufficient_token_balance",
1253
1310
  "transaction_failed",
1254
1311
  "settlement_failed"
1255
1312
  ];
@@ -1292,7 +1349,9 @@ var Permit2EvmPayloadAuthorizationSchema = import_zod3.z.object({
1292
1349
  token: import_zod3.z.string().regex(EvmAddressRegex),
1293
1350
  amount: import_zod3.z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)),
1294
1351
  deadline: import_zod3.z.string().refine(isInteger),
1295
- nonce: import_zod3.z.string().refine(isInteger)
1352
+ nonce: import_zod3.z.string().refine(isInteger),
1353
+ to: import_zod3.z.string().regex(EvmAddressRegex).optional()
1354
+ // Witness: binds recipient address to signature
1296
1355
  });
1297
1356
  var ExactEvmPayloadSchema = import_zod3.z.discriminatedUnion("authorizationType", [
1298
1357
  import_zod3.z.object({
@@ -2041,11 +2100,41 @@ async function verify3(client, payload, paymentRequirements) {
2041
2100
  };
2042
2101
  }
2043
2102
  const permit2Payload = payload.payload;
2044
- const { owner, spender, token, amount, deadline, nonce } = permit2Payload.authorization;
2103
+ const { owner, spender, token, amount, deadline, nonce, to } = permit2Payload.authorization;
2045
2104
  const chainId = getNetworkId(payload.network);
2046
2105
  const tokenAddress = (0, import_viem5.getAddress)(token);
2047
2106
  const ownerAddress = (0, import_viem5.getAddress)(owner);
2048
- const permit2TypedData = {
2107
+ const hasWitness = !!to;
2108
+ if (hasWitness) {
2109
+ if ((0, import_viem5.getAddress)(to) !== (0, import_viem5.getAddress)(paymentRequirements.payTo)) {
2110
+ return {
2111
+ isValid: false,
2112
+ invalidReason: "witness_recipient_mismatch",
2113
+ payer: owner
2114
+ };
2115
+ }
2116
+ }
2117
+ const permit2TypedData = hasWitness ? {
2118
+ types: permit2WitnessTypes,
2119
+ domain: {
2120
+ name: "Permit2",
2121
+ chainId,
2122
+ verifyingContract: PERMIT2_ADDRESS
2123
+ },
2124
+ primaryType: "PermitWitnessTransferFrom",
2125
+ message: {
2126
+ permitted: {
2127
+ token: tokenAddress,
2128
+ amount
2129
+ },
2130
+ spender: (0, import_viem5.getAddress)(spender),
2131
+ nonce,
2132
+ deadline,
2133
+ witness: {
2134
+ to: (0, import_viem5.getAddress)(to)
2135
+ }
2136
+ }
2137
+ } : {
2049
2138
  types: permit2Types,
2050
2139
  domain: {
2051
2140
  name: "Permit2",
@@ -2071,7 +2160,7 @@ async function verify3(client, payload, paymentRequirements) {
2071
2160
  if (!recoveredAddress) {
2072
2161
  return {
2073
2162
  isValid: false,
2074
- invalidReason: "invalid_permit2_signature",
2163
+ invalidReason: hasWitness ? "invalid_permit2_witness_signature" : "invalid_permit2_signature",
2075
2164
  payer: owner
2076
2165
  };
2077
2166
  }
@@ -2146,10 +2235,34 @@ async function settle3(wallet, paymentPayload, paymentRequirements) {
2146
2235
  payer: permit2Payload.authorization.owner
2147
2236
  };
2148
2237
  }
2149
- const { owner, token, amount, deadline, nonce } = permit2Payload.authorization;
2238
+ const { owner, token, amount, deadline, nonce, to } = permit2Payload.authorization;
2150
2239
  const tokenAddress = (0, import_viem5.getAddress)(token);
2151
2240
  const ownerAddress = (0, import_viem5.getAddress)(owner);
2152
- const tx = await wallet.writeContract({
2241
+ const hasWitness = !!to;
2242
+ const tx = hasWitness ? await wallet.writeContract({
2243
+ address: PERMIT2_ADDRESS,
2244
+ abi: permit2ABI,
2245
+ functionName: "permitWitnessTransferFrom",
2246
+ args: [
2247
+ {
2248
+ permitted: {
2249
+ token: tokenAddress,
2250
+ amount: BigInt(amount)
2251
+ },
2252
+ nonce: BigInt(nonce),
2253
+ deadline: BigInt(deadline)
2254
+ },
2255
+ {
2256
+ to: paymentRequirements.payTo,
2257
+ requestedAmount: BigInt(amount)
2258
+ },
2259
+ ownerAddress,
2260
+ (0, import_viem5.keccak256)((0, import_viem5.encodeAbiParameters)([{ type: "address", name: "to" }], [(0, import_viem5.getAddress)(to)])),
2261
+ WITNESS_TYPE_STRING,
2262
+ permit2Payload.signature
2263
+ ],
2264
+ chain: wallet.chain
2265
+ }) : await wallet.writeContract({
2153
2266
  address: PERMIT2_ADDRESS,
2154
2267
  abi: permit2ABI,
2155
2268
  functionName: "permitTransferFrom",
@@ -2393,7 +2506,7 @@ function preparePaymentHeader2(from, x402Version, paymentRequirements) {
2393
2506
  signature: void 0,
2394
2507
  authorization: {
2395
2508
  owner: from,
2396
- spender: paymentRequirements.extra?.feePayer,
2509
+ spender: paymentRequirements.extra?.relayer,
2397
2510
  value: paymentRequirements.maxAmountRequired,
2398
2511
  deadline
2399
2512
  }
@@ -2447,13 +2560,34 @@ __export(permit2_exports, {
2447
2560
 
2448
2561
  // src/schemes/exact/evm/permit2/sign.ts
2449
2562
  var import_viem7 = require("viem");
2450
- async function signPermit2(walletClient, { owner, spender, token, amount, deadline }, { network }) {
2563
+ async function signPermit2(walletClient, { owner, spender, token, amount, deadline, to }, { network }) {
2451
2564
  const chainId = getNetworkId(network);
2452
2565
  const tokenAddress = (0, import_viem7.getAddress)(token);
2453
2566
  const ownerAddress = (0, import_viem7.getAddress)(owner);
2454
2567
  const spenderAddress = (0, import_viem7.getAddress)(spender);
2455
2568
  const nonce = await createPermit2Nonce(walletClient, ownerAddress);
2456
- const data = {
2569
+ const hasWitness = !!to;
2570
+ const data = hasWitness ? {
2571
+ types: permit2WitnessTypes,
2572
+ domain: {
2573
+ name: "Permit2",
2574
+ chainId,
2575
+ verifyingContract: PERMIT2_ADDRESS
2576
+ },
2577
+ primaryType: "PermitWitnessTransferFrom",
2578
+ message: {
2579
+ permitted: {
2580
+ token: tokenAddress,
2581
+ amount: BigInt(amount)
2582
+ },
2583
+ spender: spenderAddress,
2584
+ nonce,
2585
+ deadline: BigInt(deadline),
2586
+ witness: {
2587
+ to: (0, import_viem7.getAddress)(to)
2588
+ }
2589
+ }
2590
+ } : {
2457
2591
  types: permit2Types,
2458
2592
  domain: {
2459
2593
  name: "Permit2",
@@ -2531,16 +2665,18 @@ function preparePaymentHeader3(from, x402Version, paymentRequirements) {
2531
2665
  spender: paymentRequirements.payTo,
2532
2666
  token: paymentRequirements.asset,
2533
2667
  amount: paymentRequirements.maxAmountRequired,
2534
- deadline
2668
+ deadline,
2669
+ to: paymentRequirements.payTo
2670
+ // Witness: bind recipient to signature
2535
2671
  }
2536
2672
  }
2537
2673
  };
2538
2674
  }
2539
2675
  async function signPaymentHeader3(client, paymentRequirements, unsignedPaymentHeader) {
2540
- const { owner, spender, token, amount, deadline } = unsignedPaymentHeader.payload.authorization;
2676
+ const { owner, spender, token, amount, deadline, to } = unsignedPaymentHeader.payload.authorization;
2541
2677
  const { signature, nonce } = await signPermit2(
2542
2678
  client,
2543
- { owner, spender, token, amount, deadline },
2679
+ { owner, spender, token, amount, deadline, to },
2544
2680
  paymentRequirements
2545
2681
  );
2546
2682
  return {
@@ -2554,7 +2690,9 @@ async function signPaymentHeader3(client, paymentRequirements, unsignedPaymentHe
2554
2690
  token,
2555
2691
  amount,
2556
2692
  deadline,
2557
- nonce
2693
+ nonce,
2694
+ ...to ? { to } : {}
2695
+ // Include `to` field if present (witness mode)
2558
2696
  }
2559
2697
  }
2560
2698
  };