@wtflabs/x402 0.0.1-beta.0 → 0.0.1-beta.10

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 (84) hide show
  1. package/dist/cjs/client/index.d.ts +1 -1
  2. package/dist/cjs/client/index.js +7 -2
  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 +444 -87
  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 +445 -88
  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 +81 -9
  13. package/dist/cjs/schemes/index.js +633 -100
  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/cjs/{x402Specs-CYq5tSY1.d.ts → x402Specs-BtRXj67U.d.ts} +43 -10
  25. package/dist/esm/{chunk-34YNR4LY.mjs → chunk-KABV25HJ.mjs} +3 -3
  26. package/dist/esm/{chunk-LGXWNXCO.mjs → chunk-LXLCF4IW.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-RX2JKK4O.mjs → chunk-VTLJOZXM.mjs} +3 -3
  30. package/dist/esm/chunk-VTLJOZXM.mjs.map +1 -0
  31. package/dist/esm/{chunk-57UEJN5U.mjs → chunk-XGQBEMP7.mjs} +589 -103
  32. package/dist/esm/chunk-XGQBEMP7.mjs.map +1 -0
  33. package/dist/esm/client/index.d.mts +64 -0
  34. package/dist/esm/client/index.mjs +3 -3
  35. package/dist/esm/config-CFBSAuxW.d.mts +10 -0
  36. package/dist/esm/config-Dfuvno71.d.mts +19 -0
  37. package/dist/esm/facilitator/index.d.mts +42 -0
  38. package/dist/esm/facilitator/index.mjs +4 -4
  39. package/dist/esm/index.d.mts +16 -0
  40. package/dist/esm/index.mjs +5 -5
  41. package/dist/{cjs/middleware-6_1ApcJn.d.ts → esm/middleware-DSDucaQ5.d.mts} +3 -3
  42. package/dist/{cjs/network-RtNddYQk.d.ts → esm/network-FrFmmiyj.d.mts} +3 -3
  43. package/dist/esm/paywall/index.d.mts +30 -0
  44. package/dist/{cjs/rpc-Ca8eHCWz.d.ts → esm/rpc-DyKXu0SX.d.mts} +1 -1
  45. package/dist/esm/schemes/index.d.mts +605 -0
  46. package/dist/esm/schemes/index.mjs +3 -3
  47. package/dist/esm/shared/evm/index.d.mts +71 -0
  48. package/dist/esm/shared/index.d.mts +182 -0
  49. package/dist/esm/shared/index.mjs +1 -1
  50. package/dist/esm/types/index.d.mts +1604 -0
  51. package/dist/esm/types/index.mjs +1 -1
  52. package/dist/esm/verify/index.d.mts +7 -0
  53. package/dist/esm/verify/index.mjs +1 -1
  54. package/dist/esm/wallet-BTqCm9Zp.d.mts +27 -0
  55. package/dist/esm/wallet-KorGgbAj.d.mts +88 -0
  56. package/dist/{cjs/wallet-BRWfOM5D.d.ts → esm/wallet-SJKJpUgQ.d.mts} +54 -40
  57. package/dist/{cjs/x402Specs-qUBCpcuz.d.ts → esm/x402Specs-BtRXj67U.d.mts} +73 -10
  58. package/package.json +15 -15
  59. package/dist/cjs/middleware-B_ewwsQp.d.ts +0 -93
  60. package/dist/cjs/middleware-BwfW7mAs.d.ts +0 -93
  61. package/dist/cjs/middleware-CQb61c1k.d.ts +0 -93
  62. package/dist/cjs/middleware-DB9lqy9f.d.ts +0 -93
  63. package/dist/cjs/middleware-DcHctwQV.d.ts +0 -93
  64. package/dist/cjs/middleware-De0jD3Bp.d.ts +0 -93
  65. package/dist/cjs/middleware-HoFOmpgv.d.ts +0 -93
  66. package/dist/cjs/middleware-Y8AiAfYw.d.ts +0 -93
  67. package/dist/cjs/middleware-pnres9YM.d.ts +0 -93
  68. package/dist/cjs/wallet-BYRAGtOB.d.ts +0 -153
  69. package/dist/cjs/wallet-BmEtlgEf.d.ts +0 -48
  70. package/dist/cjs/wallet-CNOAmyZ6.d.ts +0 -48
  71. package/dist/cjs/wallet-D1SoxFTw.d.ts +0 -48
  72. package/dist/cjs/wallet-SJ-hbjm9.d.ts +0 -153
  73. package/dist/cjs/wallet-ecnda4Aj.d.ts +0 -48
  74. package/dist/cjs/wallet-gP8Qoi-c.d.ts +0 -74
  75. package/dist/cjs/x402Specs-B7InXo2L.d.ts +0 -1065
  76. package/dist/cjs/x402Specs-BLH3j34O.d.ts +0 -1696
  77. package/dist/cjs/x402Specs-C7LipAZg.d.ts +0 -1715
  78. package/dist/cjs/x402Specs-CeajqonG.d.ts +0 -1696
  79. package/dist/cjs/x402Specs-qMujgEV5.d.ts +0 -1715
  80. package/dist/esm/chunk-57UEJN5U.mjs.map +0 -1
  81. package/dist/esm/chunk-RX2JKK4O.mjs.map +0 -1
  82. package/dist/esm/chunk-UCBE7FDY.mjs.map +0 -1
  83. /package/dist/esm/{chunk-34YNR4LY.mjs.map → chunk-KABV25HJ.mjs.map} +0 -0
  84. /package/dist/esm/{chunk-LGXWNXCO.mjs.map → chunk-LXLCF4IW.mjs.map} +0 -0
@@ -9,11 +9,12 @@ import {
9
9
  preparePaymentHeader,
10
10
  signAuthorization,
11
11
  signPaymentHeader
12
- } from "./chunk-RX2JKK4O.mjs";
12
+ } from "./chunk-VTLJOZXM.mjs";
13
13
  import {
14
14
  ErrorReasons,
15
15
  PERMIT2_ADDRESS,
16
16
  SupportedSVMNetworks,
17
+ WITNESS_TYPE_STRING,
17
18
  authorizationTypes,
18
19
  decodeTransactionFromPayload,
19
20
  erc20PermitABI,
@@ -24,9 +25,10 @@ import {
24
25
  isSignerWallet,
25
26
  permit2ABI,
26
27
  permit2Types,
28
+ permit2WitnessTypes,
27
29
  permitTypes,
28
30
  signAndSimulateTransaction
29
- } from "./chunk-UCBE7FDY.mjs";
31
+ } from "./chunk-NPWDNT2P.mjs";
30
32
  import {
31
33
  getERC20Allowance,
32
34
  getERC20Balance,
@@ -50,8 +52,11 @@ __export(exact_exports, {
50
52
  var evm_exports = {};
51
53
  __export(evm_exports, {
52
54
  decodePayment: () => decodePayment,
55
+ detectTokenPaymentMethods: () => detectTokenPaymentMethods,
53
56
  eip3009: () => eip3009_exports,
54
57
  encodePayment: () => encodePayment,
58
+ getRecommendedPaymentMethod: () => getRecommendedPaymentMethod,
59
+ getTokenInfo: () => getTokenInfo,
55
60
  permit: () => permit_exports,
56
61
  permit2: () => permit2_exports,
57
62
  settle: () => settle4,
@@ -59,7 +64,271 @@ __export(evm_exports, {
59
64
  });
60
65
 
61
66
  // src/schemes/exact/evm/eip3009/facilitator.ts
62
- import { getAddress, parseErc6492Signature } from "viem";
67
+ import {
68
+ getAddress,
69
+ parseErc6492Signature,
70
+ hexToSignature
71
+ } from "viem";
72
+
73
+ // src/types/shared/evm/permitProxyABI.ts
74
+ var permitProxyContractABI = [
75
+ // settleWithPermit - 使用 EIP-2612 Permit 进行结算
76
+ {
77
+ inputs: [
78
+ {
79
+ internalType: "address",
80
+ name: "token",
81
+ type: "address"
82
+ },
83
+ {
84
+ internalType: "address",
85
+ name: "payer",
86
+ type: "address"
87
+ },
88
+ {
89
+ internalType: "address",
90
+ name: "seller",
91
+ type: "address"
92
+ },
93
+ {
94
+ internalType: "uint256",
95
+ name: "amount",
96
+ type: "uint256"
97
+ },
98
+ {
99
+ internalType: "uint256",
100
+ name: "deadline",
101
+ type: "uint256"
102
+ },
103
+ {
104
+ internalType: "uint8",
105
+ name: "v",
106
+ type: "uint8"
107
+ },
108
+ {
109
+ internalType: "bytes32",
110
+ name: "r",
111
+ type: "bytes32"
112
+ },
113
+ {
114
+ internalType: "bytes32",
115
+ name: "s",
116
+ type: "bytes32"
117
+ }
118
+ ],
119
+ name: "settleWithPermit",
120
+ outputs: [],
121
+ stateMutability: "nonpayable",
122
+ type: "function"
123
+ },
124
+ // settleWithERC3009 - 使用 EIP-3009 TransferWithAuthorization 进行结算
125
+ {
126
+ inputs: [
127
+ {
128
+ internalType: "address",
129
+ name: "token",
130
+ type: "address"
131
+ },
132
+ {
133
+ internalType: "address",
134
+ name: "payer",
135
+ type: "address"
136
+ },
137
+ {
138
+ internalType: "address",
139
+ name: "seller",
140
+ type: "address"
141
+ },
142
+ {
143
+ internalType: "uint256",
144
+ name: "amount",
145
+ type: "uint256"
146
+ },
147
+ {
148
+ internalType: "uint256",
149
+ name: "validAfter",
150
+ type: "uint256"
151
+ },
152
+ {
153
+ internalType: "uint256",
154
+ name: "validBefore",
155
+ type: "uint256"
156
+ },
157
+ {
158
+ internalType: "bytes32",
159
+ name: "nonce",
160
+ type: "bytes32"
161
+ },
162
+ {
163
+ internalType: "uint8",
164
+ name: "v",
165
+ type: "uint8"
166
+ },
167
+ {
168
+ internalType: "bytes32",
169
+ name: "r",
170
+ type: "bytes32"
171
+ },
172
+ {
173
+ internalType: "bytes32",
174
+ name: "s",
175
+ type: "bytes32"
176
+ }
177
+ ],
178
+ name: "settleWithERC3009",
179
+ outputs: [],
180
+ stateMutability: "nonpayable",
181
+ type: "function"
182
+ },
183
+ // settleWithERC3009Direct - 直接结算(无手续费)
184
+ {
185
+ inputs: [
186
+ {
187
+ internalType: "address",
188
+ name: "token",
189
+ type: "address"
190
+ },
191
+ {
192
+ internalType: "address",
193
+ name: "payer",
194
+ type: "address"
195
+ },
196
+ {
197
+ internalType: "address",
198
+ name: "seller",
199
+ type: "address"
200
+ },
201
+ {
202
+ internalType: "uint256",
203
+ name: "amount",
204
+ type: "uint256"
205
+ },
206
+ {
207
+ internalType: "uint256",
208
+ name: "validAfter",
209
+ type: "uint256"
210
+ },
211
+ {
212
+ internalType: "uint256",
213
+ name: "validBefore",
214
+ type: "uint256"
215
+ },
216
+ {
217
+ internalType: "bytes32",
218
+ name: "nonce",
219
+ type: "bytes32"
220
+ },
221
+ {
222
+ internalType: "uint8",
223
+ name: "v",
224
+ type: "uint8"
225
+ },
226
+ {
227
+ internalType: "bytes32",
228
+ name: "r",
229
+ type: "bytes32"
230
+ },
231
+ {
232
+ internalType: "bytes32",
233
+ name: "s",
234
+ type: "bytes32"
235
+ }
236
+ ],
237
+ name: "settleWithERC3009Direct",
238
+ outputs: [],
239
+ stateMutability: "nonpayable",
240
+ type: "function"
241
+ },
242
+ // Events
243
+ {
244
+ anonymous: false,
245
+ inputs: [
246
+ {
247
+ indexed: true,
248
+ internalType: "address",
249
+ name: "token",
250
+ type: "address"
251
+ },
252
+ {
253
+ indexed: true,
254
+ internalType: "address",
255
+ name: "payer",
256
+ type: "address"
257
+ },
258
+ {
259
+ indexed: true,
260
+ internalType: "address",
261
+ name: "seller",
262
+ type: "address"
263
+ },
264
+ {
265
+ indexed: false,
266
+ internalType: "uint256",
267
+ name: "amount",
268
+ type: "uint256"
269
+ },
270
+ {
271
+ indexed: false,
272
+ internalType: "uint256",
273
+ name: "sellerAmount",
274
+ type: "uint256"
275
+ },
276
+ {
277
+ indexed: false,
278
+ internalType: "uint256",
279
+ name: "feeAmount",
280
+ type: "uint256"
281
+ },
282
+ {
283
+ indexed: false,
284
+ internalType: "string",
285
+ name: "path",
286
+ type: "string"
287
+ }
288
+ ],
289
+ name: "SettledSplit",
290
+ type: "event"
291
+ },
292
+ {
293
+ anonymous: false,
294
+ inputs: [
295
+ {
296
+ indexed: true,
297
+ internalType: "address",
298
+ name: "token",
299
+ type: "address"
300
+ },
301
+ {
302
+ indexed: true,
303
+ internalType: "address",
304
+ name: "payer",
305
+ type: "address"
306
+ },
307
+ {
308
+ indexed: true,
309
+ internalType: "address",
310
+ name: "seller",
311
+ type: "address"
312
+ },
313
+ {
314
+ indexed: false,
315
+ internalType: "uint256",
316
+ name: "amount",
317
+ type: "uint256"
318
+ },
319
+ {
320
+ indexed: false,
321
+ internalType: "string",
322
+ name: "path",
323
+ type: "string"
324
+ }
325
+ ],
326
+ name: "SettledDirect",
327
+ type: "event"
328
+ }
329
+ ];
330
+
331
+ // src/schemes/exact/evm/eip3009/facilitator.ts
63
332
  async function verify(client, payload, paymentRequirements) {
64
333
  const exactEvmPayload = payload.payload;
65
334
  if (exactEvmPayload.authorizationType !== "eip3009") {
@@ -123,7 +392,7 @@ async function verify(client, payload, paymentRequirements) {
123
392
  payer: exactEvmPayload.authorization.from
124
393
  };
125
394
  }
126
- if (getAddress(exactEvmPayload.authorization.to) !== getAddress(paymentRequirements.payTo)) {
395
+ if (getAddress(exactEvmPayload.authorization.to) !== getAddress(paymentRequirements.payTo) && getAddress(exactEvmPayload.authorization.to) !== getAddress(paymentRequirements.extra?.relayer)) {
127
396
  return {
128
397
  isValid: false,
129
398
  invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
@@ -196,21 +465,57 @@ async function settle(wallet, paymentPayload, paymentRequirements) {
196
465
  };
197
466
  }
198
467
  const { signature } = parseErc6492Signature(payload.signature);
199
- const tx = await wallet.writeContract({
200
- address: paymentRequirements.asset,
201
- abi: usdcABI,
202
- functionName: "transferWithAuthorization",
203
- args: [
204
- payload.authorization.from,
205
- payload.authorization.to,
206
- BigInt(payload.authorization.value),
207
- BigInt(payload.authorization.validAfter),
208
- BigInt(payload.authorization.validBefore),
209
- payload.authorization.nonce,
210
- signature
211
- ],
212
- chain: wallet.chain
213
- });
468
+ let tx;
469
+ if (paymentRequirements.extra?.relayer) {
470
+ const sig = hexToSignature(signature);
471
+ const v = Number(sig.v);
472
+ const r = sig.r;
473
+ const s = sig.s;
474
+ tx = await wallet.writeContract({
475
+ address: paymentRequirements.extra.relayer,
476
+ abi: permitProxyContractABI,
477
+ functionName: "settleWithERC3009",
478
+ args: [
479
+ paymentRequirements.asset,
480
+ // token
481
+ payload.authorization.from,
482
+ // payer
483
+ payload.authorization.to,
484
+ // seller
485
+ BigInt(payload.authorization.value),
486
+ // amount
487
+ BigInt(payload.authorization.validAfter),
488
+ // validAfter
489
+ BigInt(payload.authorization.validBefore),
490
+ // validBefore
491
+ payload.authorization.nonce,
492
+ // nonce
493
+ v,
494
+ // v (uint8)
495
+ r,
496
+ // r (bytes32)
497
+ s
498
+ // s (bytes32)
499
+ ],
500
+ chain: wallet.chain
501
+ });
502
+ } else {
503
+ tx = await wallet.writeContract({
504
+ address: paymentRequirements.asset,
505
+ abi: usdcABI,
506
+ functionName: "transferWithAuthorization",
507
+ args: [
508
+ payload.authorization.from,
509
+ payload.authorization.to,
510
+ BigInt(payload.authorization.value),
511
+ BigInt(payload.authorization.validAfter),
512
+ BigInt(payload.authorization.validBefore),
513
+ payload.authorization.nonce,
514
+ signature
515
+ ],
516
+ chain: wallet.chain
517
+ });
518
+ }
214
519
  const receipt = await wallet.waitForTransactionReceipt({ hash: tx });
215
520
  if (receipt.status !== "success") {
216
521
  return {
@@ -254,11 +559,7 @@ async function signPermit(walletClient, { owner, spender, value, deadline }, { a
254
559
  abi: erc20PermitABI,
255
560
  functionName: "name"
256
561
  }),
257
- walletClient.readContract({
258
- address: tokenAddress,
259
- abi: erc20PermitABI,
260
- functionName: "version"
261
- })
562
+ getVersion(walletClient, tokenAddress)
262
563
  ]);
263
564
  } else {
264
565
  throw new Error("Local account signing for permit requires a connected client");
@@ -308,63 +609,6 @@ function splitSignature(signature) {
308
609
  return { v, r, s };
309
610
  }
310
611
 
311
- // src/types/shared/evm/permitProxyABI.ts
312
- var permitProxyContractABI = [
313
- {
314
- inputs: [
315
- {
316
- internalType: "address",
317
- name: "token",
318
- type: "address"
319
- },
320
- {
321
- internalType: "address",
322
- name: "owner",
323
- type: "address"
324
- },
325
- {
326
- internalType: "address",
327
- name: "spender",
328
- type: "address"
329
- },
330
- {
331
- internalType: "uint256",
332
- name: "value",
333
- type: "uint256"
334
- },
335
- {
336
- internalType: "uint256",
337
- name: "deadline",
338
- type: "uint256"
339
- },
340
- {
341
- internalType: "uint8",
342
- name: "v",
343
- type: "uint8"
344
- },
345
- {
346
- internalType: "bytes32",
347
- name: "r",
348
- type: "bytes32"
349
- },
350
- {
351
- internalType: "bytes32",
352
- name: "s",
353
- type: "bytes32"
354
- },
355
- {
356
- internalType: "address",
357
- name: "to",
358
- type: "address"
359
- }
360
- ],
361
- name: "permitAndTransfer",
362
- outputs: [],
363
- stateMutability: "nonpayable",
364
- type: "function"
365
- }
366
- ];
367
-
368
612
  // src/schemes/exact/evm/permit/facilitator.ts
369
613
  async function verify2(client, payload, paymentRequirements) {
370
614
  if (payload.payload.authorizationType !== "permit" || payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {
@@ -432,8 +676,8 @@ async function verify2(client, payload, paymentRequirements) {
432
676
  payer: owner
433
677
  };
434
678
  }
435
- if (paymentRequirements.extra?.proxyAddress) {
436
- if (getAddress3(spender) !== getAddress3(paymentRequirements.extra?.proxyAddress)) {
679
+ if (paymentRequirements.extra?.relayer) {
680
+ if (getAddress3(spender) !== getAddress3(paymentRequirements.extra?.relayer)) {
437
681
  return {
438
682
  isValid: false,
439
683
  invalidReason: "invalid_spender_address",
@@ -497,21 +741,28 @@ async function settle2(wallet, paymentPayload, paymentRequirements) {
497
741
  address: wallet.account.address
498
742
  });
499
743
  let transactionHash;
500
- if (paymentRequirements.extra?.proxyAddress) {
744
+ if (paymentRequirements.extra?.relayer) {
501
745
  transactionHash = await wallet.writeContract({
502
- address: paymentRequirements.extra.proxyAddress,
746
+ address: paymentRequirements.extra.relayer,
503
747
  abi: permitProxyContractABI,
504
- functionName: "permitAndTransfer",
748
+ functionName: "settleWithPermit",
505
749
  args: [
506
750
  tokenAddress,
751
+ // token
507
752
  owner,
508
- spender,
753
+ // payer
754
+ paymentRequirements.payTo,
755
+ // seller
509
756
  BigInt(value),
757
+ // amount
510
758
  BigInt(deadline),
759
+ // deadline
511
760
  v,
761
+ // v
512
762
  r,
513
- s,
514
- paymentRequirements.payTo
763
+ // r
764
+ s
765
+ // s
515
766
  ],
516
767
  chain: wallet.chain,
517
768
  nonce: txNonce
@@ -571,7 +822,11 @@ async function settle2(wallet, paymentPayload, paymentRequirements) {
571
822
  }
572
823
 
573
824
  // src/schemes/exact/evm/permit2/facilitator.ts
574
- import { getAddress as getAddress4 } from "viem";
825
+ import {
826
+ encodeAbiParameters,
827
+ getAddress as getAddress4,
828
+ keccak256
829
+ } from "viem";
575
830
  async function verify3(client, payload, paymentRequirements) {
576
831
  if (payload.payload.authorizationType !== "permit2" || payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {
577
832
  return {
@@ -580,11 +835,41 @@ async function verify3(client, payload, paymentRequirements) {
580
835
  };
581
836
  }
582
837
  const permit2Payload = payload.payload;
583
- const { owner, spender, token, amount, deadline, nonce } = permit2Payload.authorization;
838
+ const { owner, spender, token, amount, deadline, nonce, to } = permit2Payload.authorization;
584
839
  const chainId = getNetworkId(payload.network);
585
840
  const tokenAddress = getAddress4(token);
586
841
  const ownerAddress = getAddress4(owner);
587
- const permit2TypedData = {
842
+ const hasWitness = !!to;
843
+ if (hasWitness) {
844
+ if (getAddress4(to) !== getAddress4(paymentRequirements.payTo)) {
845
+ return {
846
+ isValid: false,
847
+ invalidReason: "witness_recipient_mismatch",
848
+ payer: owner
849
+ };
850
+ }
851
+ }
852
+ const permit2TypedData = hasWitness ? {
853
+ types: permit2WitnessTypes,
854
+ domain: {
855
+ name: "Permit2",
856
+ chainId,
857
+ verifyingContract: PERMIT2_ADDRESS
858
+ },
859
+ primaryType: "PermitWitnessTransferFrom",
860
+ message: {
861
+ permitted: {
862
+ token: tokenAddress,
863
+ amount
864
+ },
865
+ spender: getAddress4(spender),
866
+ nonce,
867
+ deadline,
868
+ witness: {
869
+ to: getAddress4(to)
870
+ }
871
+ }
872
+ } : {
588
873
  types: permit2Types,
589
874
  domain: {
590
875
  name: "Permit2",
@@ -610,7 +895,7 @@ async function verify3(client, payload, paymentRequirements) {
610
895
  if (!recoveredAddress) {
611
896
  return {
612
897
  isValid: false,
613
- invalidReason: "invalid_permit2_signature",
898
+ invalidReason: hasWitness ? "invalid_permit2_witness_signature" : "invalid_permit2_signature",
614
899
  payer: owner
615
900
  };
616
901
  }
@@ -685,10 +970,34 @@ async function settle3(wallet, paymentPayload, paymentRequirements) {
685
970
  payer: permit2Payload.authorization.owner
686
971
  };
687
972
  }
688
- const { owner, token, amount, deadline, nonce } = permit2Payload.authorization;
973
+ const { owner, token, amount, deadline, nonce, to } = permit2Payload.authorization;
689
974
  const tokenAddress = getAddress4(token);
690
975
  const ownerAddress = getAddress4(owner);
691
- const tx = await wallet.writeContract({
976
+ const hasWitness = !!to;
977
+ const tx = hasWitness ? await wallet.writeContract({
978
+ address: PERMIT2_ADDRESS,
979
+ abi: permit2ABI,
980
+ functionName: "permitWitnessTransferFrom",
981
+ args: [
982
+ {
983
+ permitted: {
984
+ token: tokenAddress,
985
+ amount: BigInt(amount)
986
+ },
987
+ nonce: BigInt(nonce),
988
+ deadline: BigInt(deadline)
989
+ },
990
+ {
991
+ to: paymentRequirements.payTo,
992
+ requestedAmount: BigInt(amount)
993
+ },
994
+ ownerAddress,
995
+ keccak256(encodeAbiParameters([{ type: "address", name: "to" }], [getAddress4(to)])),
996
+ WITNESS_TYPE_STRING,
997
+ permit2Payload.signature
998
+ ],
999
+ chain: wallet.chain
1000
+ }) : await wallet.writeContract({
692
1001
  address: PERMIT2_ADDRESS,
693
1002
  abi: permit2ABI,
694
1003
  functionName: "permitTransferFrom",
@@ -768,7 +1077,7 @@ function preparePaymentHeader2(from, x402Version, paymentRequirements) {
768
1077
  signature: void 0,
769
1078
  authorization: {
770
1079
  owner: from,
771
- spender: paymentRequirements.payTo,
1080
+ spender: paymentRequirements.extra?.relayer || paymentRequirements.payTo,
772
1081
  value: paymentRequirements.maxAmountRequired,
773
1082
  deadline
774
1083
  }
@@ -822,13 +1131,34 @@ __export(permit2_exports, {
822
1131
 
823
1132
  // src/schemes/exact/evm/permit2/sign.ts
824
1133
  import { getAddress as getAddress5 } from "viem";
825
- async function signPermit2(walletClient, { owner, spender, token, amount, deadline }, { network }) {
1134
+ async function signPermit2(walletClient, { owner, spender, token, amount, deadline, to }, { network }) {
826
1135
  const chainId = getNetworkId(network);
827
1136
  const tokenAddress = getAddress5(token);
828
1137
  const ownerAddress = getAddress5(owner);
829
1138
  const spenderAddress = getAddress5(spender);
830
1139
  const nonce = await createPermit2Nonce(walletClient, ownerAddress);
831
- const data = {
1140
+ const hasWitness = !!to;
1141
+ const data = hasWitness ? {
1142
+ types: permit2WitnessTypes,
1143
+ domain: {
1144
+ name: "Permit2",
1145
+ chainId,
1146
+ verifyingContract: PERMIT2_ADDRESS
1147
+ },
1148
+ primaryType: "PermitWitnessTransferFrom",
1149
+ message: {
1150
+ permitted: {
1151
+ token: tokenAddress,
1152
+ amount: BigInt(amount)
1153
+ },
1154
+ spender: spenderAddress,
1155
+ nonce,
1156
+ deadline: BigInt(deadline),
1157
+ witness: {
1158
+ to: getAddress5(to)
1159
+ }
1160
+ }
1161
+ } : {
832
1162
  types: permit2Types,
833
1163
  domain: {
834
1164
  name: "Permit2",
@@ -906,16 +1236,18 @@ function preparePaymentHeader3(from, x402Version, paymentRequirements) {
906
1236
  spender: paymentRequirements.payTo,
907
1237
  token: paymentRequirements.asset,
908
1238
  amount: paymentRequirements.maxAmountRequired,
909
- deadline
1239
+ deadline,
1240
+ to: paymentRequirements.payTo
1241
+ // Witness: bind recipient to signature
910
1242
  }
911
1243
  }
912
1244
  };
913
1245
  }
914
1246
  async function signPaymentHeader3(client, paymentRequirements, unsignedPaymentHeader) {
915
- const { owner, spender, token, amount, deadline } = unsignedPaymentHeader.payload.authorization;
1247
+ const { owner, spender, token, amount, deadline, to } = unsignedPaymentHeader.payload.authorization;
916
1248
  const { signature, nonce } = await signPermit2(
917
1249
  client,
918
- { owner, spender, token, amount, deadline },
1250
+ { owner, spender, token, amount, deadline, to },
919
1251
  paymentRequirements
920
1252
  );
921
1253
  return {
@@ -929,7 +1261,9 @@ async function signPaymentHeader3(client, paymentRequirements, unsignedPaymentHe
929
1261
  token,
930
1262
  amount,
931
1263
  deadline,
932
- nonce
1264
+ nonce,
1265
+ ...to ? { to } : {}
1266
+ // Include `to` field if present (witness mode)
933
1267
  }
934
1268
  }
935
1269
  };
@@ -944,6 +1278,158 @@ async function createPaymentHeader4(client, x402Version, paymentRequirements) {
944
1278
  return encodePayment(payment);
945
1279
  }
946
1280
 
1281
+ // src/schemes/exact/evm/utils/tokenDetection.ts
1282
+ var EIP3009_SIGNATURES = ["0xe3ee160e", "0xcf092995"];
1283
+ var EIP2612_PERMIT = "0xd505accf";
1284
+ var PERMIT2_ADDRESS2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
1285
+ async function hasMethod(client, tokenAddress, methodSelector) {
1286
+ try {
1287
+ const code = await client.getBytecode({ address: tokenAddress });
1288
+ if (!code) return false;
1289
+ return code.toLowerCase().includes(methodSelector.slice(2).toLowerCase());
1290
+ } catch (error) {
1291
+ console.error(`Error checking method ${methodSelector}:`, error);
1292
+ return false;
1293
+ }
1294
+ }
1295
+ async function hasAnyMethod(client, tokenAddress, methodSelectors) {
1296
+ try {
1297
+ const code = await client.getBytecode({ address: tokenAddress });
1298
+ if (!code) return false;
1299
+ const codeLower = code.toLowerCase();
1300
+ return methodSelectors.some((selector) => codeLower.includes(selector.slice(2).toLowerCase()));
1301
+ } catch (error) {
1302
+ console.error(`Error checking methods ${methodSelectors.join(", ")}:`, error);
1303
+ return false;
1304
+ }
1305
+ }
1306
+ async function checkPermit2Support(client) {
1307
+ try {
1308
+ const permit2Code = await client.getBytecode({ address: PERMIT2_ADDRESS2 });
1309
+ if (!permit2Code) return false;
1310
+ return true;
1311
+ } catch (error) {
1312
+ console.error("Error checking Permit2 support:", error);
1313
+ return false;
1314
+ }
1315
+ }
1316
+ async function detectTokenPaymentMethods(tokenAddress, client) {
1317
+ const address = tokenAddress.toLowerCase();
1318
+ console.log(`\u{1F50D} Detecting payment methods for token ${address}...`);
1319
+ const [hasEIP3009, hasPermit, hasPermit2Approval] = await Promise.all([
1320
+ hasAnyMethod(client, address, EIP3009_SIGNATURES),
1321
+ hasMethod(client, address, EIP2612_PERMIT),
1322
+ checkPermit2Support(client)
1323
+ ]);
1324
+ const supportedMethods = [];
1325
+ if (hasEIP3009) {
1326
+ supportedMethods.push("eip3009");
1327
+ console.log(" \u2705 EIP-3009 (transferWithAuthorization) detected");
1328
+ }
1329
+ if (hasPermit) {
1330
+ supportedMethods.push("permit");
1331
+ console.log(" \u2705 EIP-2612 (permit) detected");
1332
+ }
1333
+ if (hasPermit2Approval) {
1334
+ supportedMethods.push("permit2");
1335
+ supportedMethods.push("permit2-witness");
1336
+ console.log(" \u2705 Permit2 support available (universal)");
1337
+ }
1338
+ if (supportedMethods.length === 0) {
1339
+ console.log(" \u26A0\uFE0F No advanced payment methods detected (standard ERC-20 only)");
1340
+ }
1341
+ return {
1342
+ address,
1343
+ supportedMethods,
1344
+ details: {
1345
+ hasEIP3009,
1346
+ hasPermit,
1347
+ hasPermit2Approval
1348
+ }
1349
+ };
1350
+ }
1351
+ async function getRecommendedPaymentMethod(tokenAddress, client) {
1352
+ const capabilities = await detectTokenPaymentMethods(tokenAddress, client);
1353
+ const { supportedMethods } = capabilities;
1354
+ if (supportedMethods.includes("eip3009")) return "eip3009";
1355
+ if (supportedMethods.includes("permit")) return "permit";
1356
+ if (supportedMethods.includes("permit2") || supportedMethods.includes("permit2-witness")) {
1357
+ return "permit2";
1358
+ }
1359
+ return null;
1360
+ }
1361
+ async function getTokenInfo(tokenAddress, client) {
1362
+ const address = tokenAddress.toLowerCase();
1363
+ const erc20ABI = [
1364
+ {
1365
+ inputs: [],
1366
+ name: "name",
1367
+ outputs: [{ name: "", type: "string" }],
1368
+ stateMutability: "view",
1369
+ type: "function"
1370
+ }
1371
+ ];
1372
+ const eip712DomainABI = [
1373
+ {
1374
+ inputs: [],
1375
+ name: "eip712Domain",
1376
+ outputs: [
1377
+ { name: "fields", type: "bytes1" },
1378
+ { name: "name", type: "string" },
1379
+ { name: "version", type: "string" },
1380
+ { name: "chainId", type: "uint256" },
1381
+ { name: "verifyingContract", type: "address" },
1382
+ { name: "salt", type: "bytes32" },
1383
+ { name: "extensions", type: "uint256[]" }
1384
+ ],
1385
+ stateMutability: "view",
1386
+ type: "function"
1387
+ }
1388
+ ];
1389
+ const versionABI = [
1390
+ {
1391
+ inputs: [],
1392
+ name: "version",
1393
+ outputs: [{ name: "", type: "string" }],
1394
+ stateMutability: "view",
1395
+ type: "function"
1396
+ }
1397
+ ];
1398
+ try {
1399
+ const name = await client.readContract({
1400
+ address,
1401
+ abi: erc20ABI,
1402
+ functionName: "name"
1403
+ });
1404
+ let version = "1";
1405
+ try {
1406
+ const result = await client.readContract({
1407
+ address,
1408
+ abi: eip712DomainABI,
1409
+ functionName: "eip712Domain"
1410
+ });
1411
+ version = result[2];
1412
+ } catch {
1413
+ try {
1414
+ version = await client.readContract({
1415
+ address,
1416
+ abi: versionABI,
1417
+ functionName: "version"
1418
+ });
1419
+ } catch {
1420
+ console.log(` \u2139\uFE0F Using default version "1" for token ${address}`);
1421
+ }
1422
+ }
1423
+ return {
1424
+ name,
1425
+ version
1426
+ };
1427
+ } catch (error) {
1428
+ console.error(`Error getting token info for ${address}:`, error);
1429
+ throw new Error(`Failed to get token info: ${error}`);
1430
+ }
1431
+ }
1432
+
947
1433
  // src/schemes/exact/evm/index.ts
948
1434
  async function verify4(client, payload, paymentRequirements) {
949
1435
  const exactEvmPayload = payload.payload;
@@ -1413,4 +1899,4 @@ export {
1413
1899
  verify4 as verify2,
1414
1900
  settle4 as settle2
1415
1901
  };
1416
- //# sourceMappingURL=chunk-57UEJN5U.mjs.map
1902
+ //# sourceMappingURL=chunk-XGQBEMP7.mjs.map