uvd-x402-sdk 2.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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +782 -0
  3. package/dist/index-BrBqP1I8.d.ts +199 -0
  4. package/dist/index-D6Sr4ARD.d.mts +429 -0
  5. package/dist/index-D6Sr4ARD.d.ts +429 -0
  6. package/dist/index-DJ4Cvrev.d.mts +199 -0
  7. package/dist/index.d.mts +3 -0
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.js +1178 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/index.mjs +1146 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/providers/evm/index.d.mts +84 -0
  14. package/dist/providers/evm/index.d.ts +84 -0
  15. package/dist/providers/evm/index.js +740 -0
  16. package/dist/providers/evm/index.js.map +1 -0
  17. package/dist/providers/evm/index.mjs +735 -0
  18. package/dist/providers/evm/index.mjs.map +1 -0
  19. package/dist/providers/near/index.d.mts +99 -0
  20. package/dist/providers/near/index.d.ts +99 -0
  21. package/dist/providers/near/index.js +483 -0
  22. package/dist/providers/near/index.js.map +1 -0
  23. package/dist/providers/near/index.mjs +478 -0
  24. package/dist/providers/near/index.mjs.map +1 -0
  25. package/dist/providers/solana/index.d.mts +115 -0
  26. package/dist/providers/solana/index.d.ts +115 -0
  27. package/dist/providers/solana/index.js +771 -0
  28. package/dist/providers/solana/index.js.map +1 -0
  29. package/dist/providers/solana/index.mjs +765 -0
  30. package/dist/providers/solana/index.mjs.map +1 -0
  31. package/dist/providers/stellar/index.d.mts +67 -0
  32. package/dist/providers/stellar/index.d.ts +67 -0
  33. package/dist/providers/stellar/index.js +306 -0
  34. package/dist/providers/stellar/index.js.map +1 -0
  35. package/dist/providers/stellar/index.mjs +301 -0
  36. package/dist/providers/stellar/index.mjs.map +1 -0
  37. package/dist/react/index.d.mts +73 -0
  38. package/dist/react/index.d.ts +73 -0
  39. package/dist/react/index.js +1218 -0
  40. package/dist/react/index.js.map +1 -0
  41. package/dist/react/index.mjs +1211 -0
  42. package/dist/react/index.mjs.map +1 -0
  43. package/dist/utils/index.d.mts +103 -0
  44. package/dist/utils/index.d.ts +103 -0
  45. package/dist/utils/index.js +575 -0
  46. package/dist/utils/index.js.map +1 -0
  47. package/dist/utils/index.mjs +562 -0
  48. package/dist/utils/index.mjs.map +1 -0
  49. package/package.json +149 -0
  50. package/src/chains/index.ts +539 -0
  51. package/src/client/X402Client.ts +663 -0
  52. package/src/client/index.ts +1 -0
  53. package/src/index.ts +166 -0
  54. package/src/providers/evm/index.ts +394 -0
  55. package/src/providers/near/index.ts +664 -0
  56. package/src/providers/solana/index.ts +489 -0
  57. package/src/providers/stellar/index.ts +376 -0
  58. package/src/react/index.tsx +417 -0
  59. package/src/types/index.ts +561 -0
  60. package/src/utils/index.ts +20 -0
  61. package/src/utils/x402.ts +295 -0
@@ -0,0 +1,735 @@
1
+ import { ethers } from 'ethers';
2
+
3
+ // src/providers/evm/index.ts
4
+
5
+ // src/types/index.ts
6
+ var CAIP2_IDENTIFIERS = {
7
+ // EVM chains
8
+ base: "eip155:8453",
9
+ ethereum: "eip155:1",
10
+ polygon: "eip155:137",
11
+ arbitrum: "eip155:42161",
12
+ optimism: "eip155:10",
13
+ avalanche: "eip155:43114",
14
+ celo: "eip155:42220",
15
+ hyperevm: "eip155:999",
16
+ unichain: "eip155:130",
17
+ monad: "eip155:143",
18
+ bsc: "eip155:56",
19
+ // SVM chains
20
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
21
+ fogo: "svm:fogo",
22
+ // Stellar
23
+ stellar: "stellar:pubnet",
24
+ // NEAR
25
+ near: "near:mainnet"
26
+ };
27
+ Object.fromEntries(
28
+ Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])
29
+ );
30
+ var X402Error = class _X402Error extends Error {
31
+ code;
32
+ details;
33
+ constructor(message, code, details) {
34
+ super(message);
35
+ this.name = "X402Error";
36
+ this.code = code;
37
+ this.details = details;
38
+ if (Error.captureStackTrace) {
39
+ Error.captureStackTrace(this, _X402Error);
40
+ }
41
+ }
42
+ };
43
+
44
+ // src/chains/index.ts
45
+ var DEFAULT_FACILITATOR_URL = "https://facilitator.ultravioletadao.xyz";
46
+ var SUPPORTED_CHAINS = {
47
+ // ============================================================================
48
+ // EVM CHAINS (11 networks)
49
+ // ============================================================================
50
+ base: {
51
+ chainId: 8453,
52
+ chainIdHex: "0x2105",
53
+ name: "base",
54
+ displayName: "Base",
55
+ networkType: "evm",
56
+ rpcUrl: "https://mainnet.base.org",
57
+ explorerUrl: "https://basescan.org",
58
+ nativeCurrency: {
59
+ name: "Ethereum",
60
+ symbol: "ETH",
61
+ decimals: 18
62
+ },
63
+ usdc: {
64
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
65
+ decimals: 6,
66
+ name: "USD Coin",
67
+ version: "2"
68
+ },
69
+ x402: {
70
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
71
+ enabled: true
72
+ }
73
+ },
74
+ avalanche: {
75
+ chainId: 43114,
76
+ chainIdHex: "0xa86a",
77
+ name: "avalanche",
78
+ displayName: "Avalanche C-Chain",
79
+ networkType: "evm",
80
+ rpcUrl: "https://avalanche-c-chain-rpc.publicnode.com",
81
+ explorerUrl: "https://snowtrace.io",
82
+ nativeCurrency: {
83
+ name: "Avalanche",
84
+ symbol: "AVAX",
85
+ decimals: 18
86
+ },
87
+ usdc: {
88
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
89
+ decimals: 6,
90
+ name: "USD Coin",
91
+ version: "2"
92
+ },
93
+ x402: {
94
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
95
+ enabled: true
96
+ }
97
+ },
98
+ ethereum: {
99
+ chainId: 1,
100
+ chainIdHex: "0x1",
101
+ name: "ethereum",
102
+ displayName: "Ethereum",
103
+ networkType: "evm",
104
+ rpcUrl: "https://eth.llamarpc.com",
105
+ explorerUrl: "https://etherscan.io",
106
+ nativeCurrency: {
107
+ name: "Ethereum",
108
+ symbol: "ETH",
109
+ decimals: 18
110
+ },
111
+ usdc: {
112
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
113
+ decimals: 6,
114
+ name: "USD Coin",
115
+ version: "2"
116
+ },
117
+ x402: {
118
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
119
+ enabled: true
120
+ }
121
+ },
122
+ polygon: {
123
+ chainId: 137,
124
+ chainIdHex: "0x89",
125
+ name: "polygon",
126
+ displayName: "Polygon",
127
+ networkType: "evm",
128
+ rpcUrl: "https://polygon-rpc.com",
129
+ explorerUrl: "https://polygonscan.com",
130
+ nativeCurrency: {
131
+ name: "Polygon",
132
+ symbol: "POL",
133
+ decimals: 18
134
+ },
135
+ usdc: {
136
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
137
+ decimals: 6,
138
+ name: "USD Coin",
139
+ version: "2"
140
+ },
141
+ x402: {
142
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
143
+ enabled: true
144
+ }
145
+ },
146
+ arbitrum: {
147
+ chainId: 42161,
148
+ chainIdHex: "0xa4b1",
149
+ name: "arbitrum",
150
+ displayName: "Arbitrum One",
151
+ networkType: "evm",
152
+ rpcUrl: "https://arb1.arbitrum.io/rpc",
153
+ explorerUrl: "https://arbiscan.io",
154
+ nativeCurrency: {
155
+ name: "Ethereum",
156
+ symbol: "ETH",
157
+ decimals: 18
158
+ },
159
+ usdc: {
160
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
161
+ decimals: 6,
162
+ name: "USD Coin",
163
+ version: "2"
164
+ },
165
+ x402: {
166
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
167
+ enabled: true
168
+ }
169
+ },
170
+ optimism: {
171
+ chainId: 10,
172
+ chainIdHex: "0xa",
173
+ name: "optimism",
174
+ displayName: "Optimism",
175
+ networkType: "evm",
176
+ rpcUrl: "https://mainnet.optimism.io",
177
+ explorerUrl: "https://optimistic.etherscan.io",
178
+ nativeCurrency: {
179
+ name: "Ethereum",
180
+ symbol: "ETH",
181
+ decimals: 18
182
+ },
183
+ usdc: {
184
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
185
+ decimals: 6,
186
+ name: "USD Coin",
187
+ version: "2"
188
+ },
189
+ x402: {
190
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
191
+ enabled: true
192
+ }
193
+ },
194
+ celo: {
195
+ chainId: 42220,
196
+ chainIdHex: "0xa4ec",
197
+ name: "celo",
198
+ displayName: "Celo",
199
+ networkType: "evm",
200
+ rpcUrl: "https://forno.celo.org",
201
+ explorerUrl: "https://celoscan.io",
202
+ nativeCurrency: {
203
+ name: "Celo",
204
+ symbol: "CELO",
205
+ decimals: 18
206
+ },
207
+ usdc: {
208
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
209
+ decimals: 6,
210
+ name: "USDC",
211
+ // Celo uses "USDC" not "USD Coin" for EIP-712
212
+ version: "2"
213
+ },
214
+ x402: {
215
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
216
+ enabled: true
217
+ }
218
+ },
219
+ hyperevm: {
220
+ chainId: 999,
221
+ chainIdHex: "0x3e7",
222
+ name: "hyperevm",
223
+ displayName: "HyperEVM",
224
+ networkType: "evm",
225
+ rpcUrl: "https://rpc.hyperliquid.xyz/evm",
226
+ explorerUrl: "https://hyperevmscan.io",
227
+ nativeCurrency: {
228
+ name: "Ethereum",
229
+ symbol: "ETH",
230
+ decimals: 18
231
+ },
232
+ usdc: {
233
+ address: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
234
+ decimals: 6,
235
+ name: "USDC",
236
+ // HyperEVM uses "USDC" not "USD Coin"
237
+ version: "2"
238
+ },
239
+ x402: {
240
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
241
+ enabled: true
242
+ }
243
+ },
244
+ unichain: {
245
+ chainId: 130,
246
+ chainIdHex: "0x82",
247
+ name: "unichain",
248
+ displayName: "Unichain",
249
+ networkType: "evm",
250
+ rpcUrl: "https://unichain-rpc.publicnode.com",
251
+ explorerUrl: "https://uniscan.xyz",
252
+ nativeCurrency: {
253
+ name: "Ethereum",
254
+ symbol: "ETH",
255
+ decimals: 18
256
+ },
257
+ usdc: {
258
+ address: "0x078d782b760474a361dda0af3839290b0ef57ad6",
259
+ decimals: 6,
260
+ name: "USDC",
261
+ // Unichain uses "USDC" not "USD Coin"
262
+ version: "2"
263
+ },
264
+ x402: {
265
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
266
+ enabled: true
267
+ }
268
+ },
269
+ monad: {
270
+ chainId: 143,
271
+ chainIdHex: "0x8f",
272
+ name: "monad",
273
+ displayName: "Monad",
274
+ networkType: "evm",
275
+ rpcUrl: "https://rpc.monad.xyz",
276
+ explorerUrl: "https://monad.socialscan.io",
277
+ nativeCurrency: {
278
+ name: "Monad",
279
+ symbol: "MON",
280
+ decimals: 18
281
+ },
282
+ usdc: {
283
+ address: "0x754704bc059f8c67012fed69bc8a327a5aafb603",
284
+ decimals: 6,
285
+ name: "USDC",
286
+ // Monad uses "USDC" not "USD Coin"
287
+ version: "2"
288
+ },
289
+ x402: {
290
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
291
+ enabled: true
292
+ }
293
+ },
294
+ // BSC disabled: USDC doesn't support ERC-3009 transferWithAuthorization
295
+ bsc: {
296
+ chainId: 56,
297
+ chainIdHex: "0x38",
298
+ name: "bsc",
299
+ displayName: "BNB Smart Chain",
300
+ networkType: "evm",
301
+ rpcUrl: "https://binance.llamarpc.com",
302
+ explorerUrl: "https://bscscan.com",
303
+ nativeCurrency: {
304
+ name: "Binance Coin",
305
+ symbol: "BNB",
306
+ decimals: 18
307
+ },
308
+ usdc: {
309
+ address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
310
+ decimals: 18,
311
+ // BSC USDC uses 18 decimals
312
+ name: "USD Coin",
313
+ version: "2"
314
+ },
315
+ x402: {
316
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
317
+ enabled: false
318
+ // Disabled: BSC USDC doesn't support ERC-3009
319
+ }
320
+ },
321
+ // ============================================================================
322
+ // SVM CHAINS (2 networks) - Solana Virtual Machine
323
+ // ============================================================================
324
+ solana: {
325
+ chainId: 0,
326
+ // Non-EVM
327
+ chainIdHex: "0x0",
328
+ name: "solana",
329
+ displayName: "Solana",
330
+ networkType: "svm",
331
+ rpcUrl: "https://api.mainnet-beta.solana.com",
332
+ explorerUrl: "https://solscan.io",
333
+ nativeCurrency: {
334
+ name: "Solana",
335
+ symbol: "SOL",
336
+ decimals: 9
337
+ },
338
+ usdc: {
339
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
340
+ // USDC SPL token mint
341
+ decimals: 6,
342
+ name: "USD Coin",
343
+ version: "1"
344
+ },
345
+ x402: {
346
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
347
+ enabled: true
348
+ }
349
+ },
350
+ fogo: {
351
+ chainId: 0,
352
+ // Non-EVM (SVM)
353
+ chainIdHex: "0x0",
354
+ name: "fogo",
355
+ displayName: "Fogo",
356
+ networkType: "svm",
357
+ rpcUrl: "https://rpc.fogo.nightly.app/",
358
+ explorerUrl: "https://explorer.fogo.nightly.app",
359
+ nativeCurrency: {
360
+ name: "Fogo",
361
+ symbol: "FOGO",
362
+ decimals: 9
363
+ },
364
+ usdc: {
365
+ address: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
366
+ // Fogo USDC mint
367
+ decimals: 6,
368
+ name: "USDC",
369
+ version: "1"
370
+ },
371
+ x402: {
372
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
373
+ enabled: true
374
+ }
375
+ },
376
+ // ============================================================================
377
+ // STELLAR (1 network)
378
+ // ============================================================================
379
+ stellar: {
380
+ chainId: 0,
381
+ // Non-EVM
382
+ chainIdHex: "0x0",
383
+ name: "stellar",
384
+ displayName: "Stellar",
385
+ networkType: "stellar",
386
+ rpcUrl: "https://horizon.stellar.org",
387
+ explorerUrl: "https://stellar.expert/explorer/public",
388
+ nativeCurrency: {
389
+ name: "Lumens",
390
+ symbol: "XLM",
391
+ decimals: 7
392
+ // Stellar uses 7 decimals (stroops)
393
+ },
394
+ usdc: {
395
+ address: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
396
+ // Soroban Asset Contract
397
+ decimals: 7,
398
+ // Stellar USDC uses 7 decimals
399
+ name: "USDC",
400
+ version: "1"
401
+ },
402
+ x402: {
403
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
404
+ enabled: true
405
+ }
406
+ },
407
+ // ============================================================================
408
+ // NEAR (1 network) - Uses NEP-366 meta-transactions
409
+ // ============================================================================
410
+ near: {
411
+ chainId: 0,
412
+ // Non-EVM
413
+ chainIdHex: "0x0",
414
+ name: "near",
415
+ displayName: "NEAR Protocol",
416
+ networkType: "near",
417
+ rpcUrl: "https://rpc.mainnet.near.org",
418
+ explorerUrl: "https://nearblocks.io",
419
+ nativeCurrency: {
420
+ name: "NEAR",
421
+ symbol: "NEAR",
422
+ decimals: 24
423
+ // NEAR uses 24 decimals (yoctoNEAR)
424
+ },
425
+ usdc: {
426
+ address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
427
+ // Native Circle USDC
428
+ decimals: 6,
429
+ name: "USDC",
430
+ version: "1"
431
+ },
432
+ x402: {
433
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
434
+ enabled: true
435
+ // NEP-366 meta-transactions supported
436
+ }
437
+ }
438
+ };
439
+ function getChainById(chainId) {
440
+ return Object.values(SUPPORTED_CHAINS).find((chain) => chain.chainId === chainId);
441
+ }
442
+ function getChainByName(name) {
443
+ return SUPPORTED_CHAINS[name.toLowerCase()];
444
+ }
445
+
446
+ // src/providers/evm/index.ts
447
+ var EVMProvider = class {
448
+ id = "injected";
449
+ name = "EVM Wallet";
450
+ networkType = "evm";
451
+ provider = null;
452
+ signer = null;
453
+ address = null;
454
+ chainId = null;
455
+ chainName = null;
456
+ /**
457
+ * Check if an EVM wallet is available
458
+ */
459
+ isAvailable() {
460
+ if (typeof window === "undefined") return false;
461
+ return typeof window.ethereum !== "undefined";
462
+ }
463
+ /**
464
+ * Connect to an EVM wallet
465
+ */
466
+ async connect(chainName) {
467
+ const targetChainName = chainName || "base";
468
+ const chain = getChainByName(targetChainName);
469
+ if (!chain) {
470
+ throw new X402Error(`Unsupported chain: ${targetChainName}`, "CHAIN_NOT_SUPPORTED");
471
+ }
472
+ if (chain.networkType !== "evm") {
473
+ throw new X402Error(`${targetChainName} is not an EVM chain`, "CHAIN_NOT_SUPPORTED");
474
+ }
475
+ const ethereum = window.ethereum;
476
+ if (!ethereum) {
477
+ throw new X402Error(
478
+ "No Ethereum wallet found. Please install MetaMask or another EVM wallet.",
479
+ "WALLET_NOT_FOUND"
480
+ );
481
+ }
482
+ try {
483
+ this.provider = new ethers.BrowserProvider(ethereum);
484
+ await this.provider.send("eth_requestAccounts", []);
485
+ await this.switchChain(targetChainName);
486
+ this.signer = await this.provider.getSigner();
487
+ this.address = await this.signer.getAddress();
488
+ return this.address;
489
+ } catch (error) {
490
+ if (error instanceof Error) {
491
+ if (error.message.includes("User rejected") || error.code === 4001) {
492
+ throw new X402Error("Connection rejected by user", "WALLET_CONNECTION_REJECTED");
493
+ }
494
+ }
495
+ throw new X402Error(
496
+ `Failed to connect wallet: ${error instanceof Error ? error.message : "Unknown error"}`,
497
+ "UNKNOWN_ERROR",
498
+ error
499
+ );
500
+ }
501
+ }
502
+ /**
503
+ * Disconnect from wallet
504
+ */
505
+ async disconnect() {
506
+ this.provider = null;
507
+ this.signer = null;
508
+ this.address = null;
509
+ this.chainId = null;
510
+ this.chainName = null;
511
+ }
512
+ /**
513
+ * Switch to a different EVM chain
514
+ */
515
+ async switchChain(chainName) {
516
+ const chain = getChainByName(chainName);
517
+ if (!chain) {
518
+ throw new X402Error(`Unsupported chain: ${chainName}`, "CHAIN_NOT_SUPPORTED");
519
+ }
520
+ if (!this.provider) {
521
+ throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
522
+ }
523
+ try {
524
+ await this.provider.send("wallet_switchEthereumChain", [{ chainId: chain.chainIdHex }]);
525
+ } catch (switchError) {
526
+ if (switchError.code === 4902) {
527
+ try {
528
+ await this.provider.send("wallet_addEthereumChain", [
529
+ {
530
+ chainId: chain.chainIdHex,
531
+ chainName: chain.displayName,
532
+ nativeCurrency: chain.nativeCurrency,
533
+ rpcUrls: [chain.rpcUrl],
534
+ blockExplorerUrls: [chain.explorerUrl]
535
+ }
536
+ ]);
537
+ } catch (addError) {
538
+ throw new X402Error(
539
+ `Failed to add ${chain.displayName} network`,
540
+ "CHAIN_SWITCH_REJECTED",
541
+ addError
542
+ );
543
+ }
544
+ } else if (switchError.code === 4001) {
545
+ throw new X402Error("Network switch rejected by user", "CHAIN_SWITCH_REJECTED");
546
+ } else {
547
+ throw new X402Error(
548
+ `Failed to switch to ${chain.displayName}`,
549
+ "CHAIN_SWITCH_REJECTED",
550
+ switchError
551
+ );
552
+ }
553
+ }
554
+ this.chainId = chain.chainId;
555
+ this.chainName = chain.name;
556
+ }
557
+ /**
558
+ * Get current address
559
+ */
560
+ getAddress() {
561
+ return this.address;
562
+ }
563
+ /**
564
+ * Get current chain ID
565
+ */
566
+ getChainId() {
567
+ return this.chainId;
568
+ }
569
+ /**
570
+ * Get current chain name
571
+ */
572
+ getChainName() {
573
+ return this.chainName;
574
+ }
575
+ /**
576
+ * Get USDC balance
577
+ */
578
+ async getBalance(chainConfig) {
579
+ if (!this.address) {
580
+ throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
581
+ }
582
+ const publicProvider = new ethers.JsonRpcProvider(chainConfig.rpcUrl);
583
+ const usdcAbi = ["function balanceOf(address owner) view returns (uint256)"];
584
+ const usdcContract = new ethers.Contract(chainConfig.usdc.address, usdcAbi, publicProvider);
585
+ try {
586
+ const balance = await usdcContract.balanceOf(this.address);
587
+ const formatted = ethers.formatUnits(balance, chainConfig.usdc.decimals);
588
+ return parseFloat(formatted).toFixed(2);
589
+ } catch {
590
+ return "0.00";
591
+ }
592
+ }
593
+ /**
594
+ * Create EVM payment (EIP-712 TransferWithAuthorization)
595
+ */
596
+ async signPayment(paymentInfo, chainConfig) {
597
+ if (!this.signer || !this.address) {
598
+ throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
599
+ }
600
+ const recipient = paymentInfo.recipients?.evm || paymentInfo.recipient;
601
+ const nonceBytes = new Uint8Array(32);
602
+ if (typeof window !== "undefined" && window.crypto) {
603
+ window.crypto.getRandomValues(nonceBytes);
604
+ } else {
605
+ for (let i = 0; i < 32; i++) {
606
+ nonceBytes[i] = Math.floor(Math.random() * 256);
607
+ }
608
+ }
609
+ const nonce = ethers.hexlify(nonceBytes);
610
+ const validAfter = 0;
611
+ const validityWindowSeconds = chainConfig.name === "base" ? 300 : 60;
612
+ const validBefore = Math.floor(Date.now() / 1e3) + validityWindowSeconds;
613
+ const domain = {
614
+ name: chainConfig.usdc.name,
615
+ version: chainConfig.usdc.version,
616
+ chainId: chainConfig.chainId,
617
+ verifyingContract: chainConfig.usdc.address
618
+ };
619
+ const types = {
620
+ TransferWithAuthorization: [
621
+ { name: "from", type: "address" },
622
+ { name: "to", type: "address" },
623
+ { name: "value", type: "uint256" },
624
+ { name: "validAfter", type: "uint256" },
625
+ { name: "validBefore", type: "uint256" },
626
+ { name: "nonce", type: "bytes32" }
627
+ ]
628
+ };
629
+ const value = ethers.parseUnits(paymentInfo.amount, chainConfig.usdc.decimals);
630
+ const from = this.address;
631
+ const to = ethers.getAddress(recipient);
632
+ const message = {
633
+ from,
634
+ to,
635
+ value,
636
+ validAfter,
637
+ validBefore,
638
+ nonce
639
+ };
640
+ let signature;
641
+ try {
642
+ signature = await this.signer.signTypedData(domain, types, message);
643
+ } catch (error) {
644
+ if (error instanceof Error && (error.message.includes("User rejected") || error.code === 4001)) {
645
+ throw new X402Error("Signature rejected by user", "SIGNATURE_REJECTED");
646
+ }
647
+ throw new X402Error(
648
+ `Failed to sign payment: ${error instanceof Error ? error.message : "Unknown error"}`,
649
+ "PAYMENT_FAILED",
650
+ error
651
+ );
652
+ }
653
+ const sig = ethers.Signature.from(signature);
654
+ const payload = {
655
+ from,
656
+ to,
657
+ value: value.toString(),
658
+ validAfter,
659
+ validBefore,
660
+ nonce,
661
+ v: sig.v,
662
+ r: sig.r,
663
+ s: sig.s,
664
+ chainId: chainConfig.chainId,
665
+ token: chainConfig.usdc.address
666
+ };
667
+ return JSON.stringify(payload);
668
+ }
669
+ /**
670
+ * Encode EVM payment as X-PAYMENT header
671
+ */
672
+ encodePaymentHeader(paymentPayload, chainConfig) {
673
+ const payload = JSON.parse(paymentPayload);
674
+ const fullSignature = payload.r + payload.s.slice(2) + payload.v.toString(16).padStart(2, "0");
675
+ const x402Payload = {
676
+ x402Version: 1,
677
+ scheme: "exact",
678
+ network: chainConfig.name,
679
+ payload: {
680
+ signature: fullSignature,
681
+ authorization: {
682
+ from: payload.from,
683
+ to: payload.to,
684
+ value: payload.value,
685
+ validAfter: payload.validAfter.toString(),
686
+ validBefore: payload.validBefore.toString(),
687
+ nonce: payload.nonce
688
+ }
689
+ }
690
+ };
691
+ return btoa(JSON.stringify(x402Payload));
692
+ }
693
+ /**
694
+ * Setup event listeners for wallet events
695
+ */
696
+ setupEventListeners(onAccountsChanged, onChainChanged) {
697
+ const ethereum = window.ethereum;
698
+ if (!ethereum?.on || !ethereum?.removeListener) {
699
+ return () => {
700
+ };
701
+ }
702
+ const handleAccountsChanged = (accounts) => {
703
+ if (Array.isArray(accounts)) {
704
+ if (accounts.length === 0) {
705
+ this.disconnect();
706
+ } else if (accounts[0] !== this.address) {
707
+ this.address = accounts[0];
708
+ }
709
+ onAccountsChanged?.(accounts);
710
+ }
711
+ };
712
+ const handleChainChanged = (chainIdHex) => {
713
+ if (typeof chainIdHex === "string") {
714
+ const chainId = parseInt(chainIdHex, 16);
715
+ const chain = getChainById(chainId);
716
+ if (chain) {
717
+ this.chainId = chainId;
718
+ this.chainName = chain.name;
719
+ }
720
+ onChainChanged?.(chainId);
721
+ }
722
+ };
723
+ ethereum.on("accountsChanged", handleAccountsChanged);
724
+ ethereum.on("chainChanged", handleChainChanged);
725
+ return () => {
726
+ ethereum.removeListener("accountsChanged", handleAccountsChanged);
727
+ ethereum.removeListener("chainChanged", handleChainChanged);
728
+ };
729
+ }
730
+ };
731
+ var evm_default = EVMProvider;
732
+
733
+ export { EVMProvider, evm_default as default };
734
+ //# sourceMappingURL=index.mjs.map
735
+ //# sourceMappingURL=index.mjs.map