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,765 @@
1
+ // src/types/index.ts
2
+ var CAIP2_IDENTIFIERS = {
3
+ // EVM chains
4
+ base: "eip155:8453",
5
+ ethereum: "eip155:1",
6
+ polygon: "eip155:137",
7
+ arbitrum: "eip155:42161",
8
+ optimism: "eip155:10",
9
+ avalanche: "eip155:43114",
10
+ celo: "eip155:42220",
11
+ hyperevm: "eip155:999",
12
+ unichain: "eip155:130",
13
+ monad: "eip155:143",
14
+ bsc: "eip155:56",
15
+ // SVM chains
16
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
17
+ fogo: "svm:fogo",
18
+ // Stellar
19
+ stellar: "stellar:pubnet",
20
+ // NEAR
21
+ near: "near:mainnet"
22
+ };
23
+ Object.fromEntries(
24
+ Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])
25
+ );
26
+ var X402Error = class _X402Error extends Error {
27
+ code;
28
+ details;
29
+ constructor(message, code, details) {
30
+ super(message);
31
+ this.name = "X402Error";
32
+ this.code = code;
33
+ this.details = details;
34
+ if (Error.captureStackTrace) {
35
+ Error.captureStackTrace(this, _X402Error);
36
+ }
37
+ }
38
+ };
39
+
40
+ // src/chains/index.ts
41
+ var DEFAULT_FACILITATOR_URL = "https://facilitator.ultravioletadao.xyz";
42
+ var SUPPORTED_CHAINS = {
43
+ // ============================================================================
44
+ // EVM CHAINS (11 networks)
45
+ // ============================================================================
46
+ base: {
47
+ chainId: 8453,
48
+ chainIdHex: "0x2105",
49
+ name: "base",
50
+ displayName: "Base",
51
+ networkType: "evm",
52
+ rpcUrl: "https://mainnet.base.org",
53
+ explorerUrl: "https://basescan.org",
54
+ nativeCurrency: {
55
+ name: "Ethereum",
56
+ symbol: "ETH",
57
+ decimals: 18
58
+ },
59
+ usdc: {
60
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
61
+ decimals: 6,
62
+ name: "USD Coin",
63
+ version: "2"
64
+ },
65
+ x402: {
66
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
67
+ enabled: true
68
+ }
69
+ },
70
+ avalanche: {
71
+ chainId: 43114,
72
+ chainIdHex: "0xa86a",
73
+ name: "avalanche",
74
+ displayName: "Avalanche C-Chain",
75
+ networkType: "evm",
76
+ rpcUrl: "https://avalanche-c-chain-rpc.publicnode.com",
77
+ explorerUrl: "https://snowtrace.io",
78
+ nativeCurrency: {
79
+ name: "Avalanche",
80
+ symbol: "AVAX",
81
+ decimals: 18
82
+ },
83
+ usdc: {
84
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
85
+ decimals: 6,
86
+ name: "USD Coin",
87
+ version: "2"
88
+ },
89
+ x402: {
90
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
91
+ enabled: true
92
+ }
93
+ },
94
+ ethereum: {
95
+ chainId: 1,
96
+ chainIdHex: "0x1",
97
+ name: "ethereum",
98
+ displayName: "Ethereum",
99
+ networkType: "evm",
100
+ rpcUrl: "https://eth.llamarpc.com",
101
+ explorerUrl: "https://etherscan.io",
102
+ nativeCurrency: {
103
+ name: "Ethereum",
104
+ symbol: "ETH",
105
+ decimals: 18
106
+ },
107
+ usdc: {
108
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
109
+ decimals: 6,
110
+ name: "USD Coin",
111
+ version: "2"
112
+ },
113
+ x402: {
114
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
115
+ enabled: true
116
+ }
117
+ },
118
+ polygon: {
119
+ chainId: 137,
120
+ chainIdHex: "0x89",
121
+ name: "polygon",
122
+ displayName: "Polygon",
123
+ networkType: "evm",
124
+ rpcUrl: "https://polygon-rpc.com",
125
+ explorerUrl: "https://polygonscan.com",
126
+ nativeCurrency: {
127
+ name: "Polygon",
128
+ symbol: "POL",
129
+ decimals: 18
130
+ },
131
+ usdc: {
132
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
133
+ decimals: 6,
134
+ name: "USD Coin",
135
+ version: "2"
136
+ },
137
+ x402: {
138
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
139
+ enabled: true
140
+ }
141
+ },
142
+ arbitrum: {
143
+ chainId: 42161,
144
+ chainIdHex: "0xa4b1",
145
+ name: "arbitrum",
146
+ displayName: "Arbitrum One",
147
+ networkType: "evm",
148
+ rpcUrl: "https://arb1.arbitrum.io/rpc",
149
+ explorerUrl: "https://arbiscan.io",
150
+ nativeCurrency: {
151
+ name: "Ethereum",
152
+ symbol: "ETH",
153
+ decimals: 18
154
+ },
155
+ usdc: {
156
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
157
+ decimals: 6,
158
+ name: "USD Coin",
159
+ version: "2"
160
+ },
161
+ x402: {
162
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
163
+ enabled: true
164
+ }
165
+ },
166
+ optimism: {
167
+ chainId: 10,
168
+ chainIdHex: "0xa",
169
+ name: "optimism",
170
+ displayName: "Optimism",
171
+ networkType: "evm",
172
+ rpcUrl: "https://mainnet.optimism.io",
173
+ explorerUrl: "https://optimistic.etherscan.io",
174
+ nativeCurrency: {
175
+ name: "Ethereum",
176
+ symbol: "ETH",
177
+ decimals: 18
178
+ },
179
+ usdc: {
180
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
181
+ decimals: 6,
182
+ name: "USD Coin",
183
+ version: "2"
184
+ },
185
+ x402: {
186
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
187
+ enabled: true
188
+ }
189
+ },
190
+ celo: {
191
+ chainId: 42220,
192
+ chainIdHex: "0xa4ec",
193
+ name: "celo",
194
+ displayName: "Celo",
195
+ networkType: "evm",
196
+ rpcUrl: "https://forno.celo.org",
197
+ explorerUrl: "https://celoscan.io",
198
+ nativeCurrency: {
199
+ name: "Celo",
200
+ symbol: "CELO",
201
+ decimals: 18
202
+ },
203
+ usdc: {
204
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
205
+ decimals: 6,
206
+ name: "USDC",
207
+ // Celo uses "USDC" not "USD Coin" for EIP-712
208
+ version: "2"
209
+ },
210
+ x402: {
211
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
212
+ enabled: true
213
+ }
214
+ },
215
+ hyperevm: {
216
+ chainId: 999,
217
+ chainIdHex: "0x3e7",
218
+ name: "hyperevm",
219
+ displayName: "HyperEVM",
220
+ networkType: "evm",
221
+ rpcUrl: "https://rpc.hyperliquid.xyz/evm",
222
+ explorerUrl: "https://hyperevmscan.io",
223
+ nativeCurrency: {
224
+ name: "Ethereum",
225
+ symbol: "ETH",
226
+ decimals: 18
227
+ },
228
+ usdc: {
229
+ address: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
230
+ decimals: 6,
231
+ name: "USDC",
232
+ // HyperEVM uses "USDC" not "USD Coin"
233
+ version: "2"
234
+ },
235
+ x402: {
236
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
237
+ enabled: true
238
+ }
239
+ },
240
+ unichain: {
241
+ chainId: 130,
242
+ chainIdHex: "0x82",
243
+ name: "unichain",
244
+ displayName: "Unichain",
245
+ networkType: "evm",
246
+ rpcUrl: "https://unichain-rpc.publicnode.com",
247
+ explorerUrl: "https://uniscan.xyz",
248
+ nativeCurrency: {
249
+ name: "Ethereum",
250
+ symbol: "ETH",
251
+ decimals: 18
252
+ },
253
+ usdc: {
254
+ address: "0x078d782b760474a361dda0af3839290b0ef57ad6",
255
+ decimals: 6,
256
+ name: "USDC",
257
+ // Unichain uses "USDC" not "USD Coin"
258
+ version: "2"
259
+ },
260
+ x402: {
261
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
262
+ enabled: true
263
+ }
264
+ },
265
+ monad: {
266
+ chainId: 143,
267
+ chainIdHex: "0x8f",
268
+ name: "monad",
269
+ displayName: "Monad",
270
+ networkType: "evm",
271
+ rpcUrl: "https://rpc.monad.xyz",
272
+ explorerUrl: "https://monad.socialscan.io",
273
+ nativeCurrency: {
274
+ name: "Monad",
275
+ symbol: "MON",
276
+ decimals: 18
277
+ },
278
+ usdc: {
279
+ address: "0x754704bc059f8c67012fed69bc8a327a5aafb603",
280
+ decimals: 6,
281
+ name: "USDC",
282
+ // Monad uses "USDC" not "USD Coin"
283
+ version: "2"
284
+ },
285
+ x402: {
286
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
287
+ enabled: true
288
+ }
289
+ },
290
+ // BSC disabled: USDC doesn't support ERC-3009 transferWithAuthorization
291
+ bsc: {
292
+ chainId: 56,
293
+ chainIdHex: "0x38",
294
+ name: "bsc",
295
+ displayName: "BNB Smart Chain",
296
+ networkType: "evm",
297
+ rpcUrl: "https://binance.llamarpc.com",
298
+ explorerUrl: "https://bscscan.com",
299
+ nativeCurrency: {
300
+ name: "Binance Coin",
301
+ symbol: "BNB",
302
+ decimals: 18
303
+ },
304
+ usdc: {
305
+ address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
306
+ decimals: 18,
307
+ // BSC USDC uses 18 decimals
308
+ name: "USD Coin",
309
+ version: "2"
310
+ },
311
+ x402: {
312
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
313
+ enabled: false
314
+ // Disabled: BSC USDC doesn't support ERC-3009
315
+ }
316
+ },
317
+ // ============================================================================
318
+ // SVM CHAINS (2 networks) - Solana Virtual Machine
319
+ // ============================================================================
320
+ solana: {
321
+ chainId: 0,
322
+ // Non-EVM
323
+ chainIdHex: "0x0",
324
+ name: "solana",
325
+ displayName: "Solana",
326
+ networkType: "svm",
327
+ rpcUrl: "https://api.mainnet-beta.solana.com",
328
+ explorerUrl: "https://solscan.io",
329
+ nativeCurrency: {
330
+ name: "Solana",
331
+ symbol: "SOL",
332
+ decimals: 9
333
+ },
334
+ usdc: {
335
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
336
+ // USDC SPL token mint
337
+ decimals: 6,
338
+ name: "USD Coin",
339
+ version: "1"
340
+ },
341
+ x402: {
342
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
343
+ enabled: true
344
+ }
345
+ },
346
+ fogo: {
347
+ chainId: 0,
348
+ // Non-EVM (SVM)
349
+ chainIdHex: "0x0",
350
+ name: "fogo",
351
+ displayName: "Fogo",
352
+ networkType: "svm",
353
+ rpcUrl: "https://rpc.fogo.nightly.app/",
354
+ explorerUrl: "https://explorer.fogo.nightly.app",
355
+ nativeCurrency: {
356
+ name: "Fogo",
357
+ symbol: "FOGO",
358
+ decimals: 9
359
+ },
360
+ usdc: {
361
+ address: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
362
+ // Fogo USDC mint
363
+ decimals: 6,
364
+ name: "USDC",
365
+ version: "1"
366
+ },
367
+ x402: {
368
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
369
+ enabled: true
370
+ }
371
+ },
372
+ // ============================================================================
373
+ // STELLAR (1 network)
374
+ // ============================================================================
375
+ stellar: {
376
+ chainId: 0,
377
+ // Non-EVM
378
+ chainIdHex: "0x0",
379
+ name: "stellar",
380
+ displayName: "Stellar",
381
+ networkType: "stellar",
382
+ rpcUrl: "https://horizon.stellar.org",
383
+ explorerUrl: "https://stellar.expert/explorer/public",
384
+ nativeCurrency: {
385
+ name: "Lumens",
386
+ symbol: "XLM",
387
+ decimals: 7
388
+ // Stellar uses 7 decimals (stroops)
389
+ },
390
+ usdc: {
391
+ address: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
392
+ // Soroban Asset Contract
393
+ decimals: 7,
394
+ // Stellar USDC uses 7 decimals
395
+ name: "USDC",
396
+ version: "1"
397
+ },
398
+ x402: {
399
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
400
+ enabled: true
401
+ }
402
+ },
403
+ // ============================================================================
404
+ // NEAR (1 network) - Uses NEP-366 meta-transactions
405
+ // ============================================================================
406
+ near: {
407
+ chainId: 0,
408
+ // Non-EVM
409
+ chainIdHex: "0x0",
410
+ name: "near",
411
+ displayName: "NEAR Protocol",
412
+ networkType: "near",
413
+ rpcUrl: "https://rpc.mainnet.near.org",
414
+ explorerUrl: "https://nearblocks.io",
415
+ nativeCurrency: {
416
+ name: "NEAR",
417
+ symbol: "NEAR",
418
+ decimals: 24
419
+ // NEAR uses 24 decimals (yoctoNEAR)
420
+ },
421
+ usdc: {
422
+ address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
423
+ // Native Circle USDC
424
+ decimals: 6,
425
+ name: "USDC",
426
+ version: "1"
427
+ },
428
+ x402: {
429
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
430
+ enabled: true
431
+ // NEP-366 meta-transactions supported
432
+ }
433
+ }
434
+ };
435
+ function getChainByName(name) {
436
+ return SUPPORTED_CHAINS[name.toLowerCase()];
437
+ }
438
+
439
+ // src/providers/solana/index.ts
440
+ function uint8ArrayToBase64(bytes) {
441
+ let binary = "";
442
+ for (let i = 0; i < bytes.length; i++) {
443
+ binary += String.fromCharCode(bytes[i]);
444
+ }
445
+ return btoa(binary);
446
+ }
447
+ var Connection;
448
+ var PublicKey;
449
+ var TransactionMessage;
450
+ var VersionedTransaction;
451
+ var ComputeBudgetProgram;
452
+ var getAssociatedTokenAddress;
453
+ var createTransferCheckedInstruction;
454
+ var createAssociatedTokenAccountIdempotentInstruction;
455
+ var TOKEN_PROGRAM_ID;
456
+ async function loadSolanaDeps() {
457
+ if (!Connection) {
458
+ const web3 = await import('@solana/web3.js');
459
+ const splToken = await import('@solana/spl-token');
460
+ Connection = web3.Connection;
461
+ PublicKey = web3.PublicKey;
462
+ TransactionMessage = web3.TransactionMessage;
463
+ VersionedTransaction = web3.VersionedTransaction;
464
+ ComputeBudgetProgram = web3.ComputeBudgetProgram;
465
+ getAssociatedTokenAddress = splToken.getAssociatedTokenAddress;
466
+ createTransferCheckedInstruction = splToken.createTransferCheckedInstruction;
467
+ createAssociatedTokenAccountIdempotentInstruction = splToken.createAssociatedTokenAccountIdempotentInstruction;
468
+ TOKEN_PROGRAM_ID = splToken.TOKEN_PROGRAM_ID;
469
+ }
470
+ }
471
+ var SVMProvider = class {
472
+ id = "phantom";
473
+ name = "Phantom";
474
+ networkType = "svm";
475
+ provider = null;
476
+ publicKey = null;
477
+ connections = /* @__PURE__ */ new Map();
478
+ address = null;
479
+ /**
480
+ * Check if Phantom wallet is available
481
+ */
482
+ isAvailable() {
483
+ if (typeof window === "undefined") return false;
484
+ return !!(window.phantom?.solana?.isPhantom || window.solana?.isPhantom);
485
+ }
486
+ /**
487
+ * Connect to Phantom wallet
488
+ */
489
+ async connect() {
490
+ await loadSolanaDeps();
491
+ this.provider = await this.getPhantomProvider();
492
+ if (!this.provider) {
493
+ throw new X402Error(
494
+ "Phantom wallet not installed. Please install from phantom.app",
495
+ "WALLET_NOT_FOUND"
496
+ );
497
+ }
498
+ try {
499
+ if (this.provider.publicKey && this.provider.isConnected) {
500
+ const publicKeyString2 = this.provider.publicKey.toBase58();
501
+ this.publicKey = new PublicKey(publicKeyString2);
502
+ this.address = publicKeyString2;
503
+ await this.initConnection();
504
+ return publicKeyString2;
505
+ }
506
+ const resp = await this.provider.connect();
507
+ const publicKeyString = resp.publicKey.toBase58();
508
+ this.publicKey = new PublicKey(publicKeyString);
509
+ this.address = publicKeyString;
510
+ await this.initConnection();
511
+ return publicKeyString;
512
+ } catch (error) {
513
+ if (error instanceof Error) {
514
+ if (error.message.includes("User rejected") || error.code === 4001) {
515
+ throw new X402Error("Connection rejected by user", "WALLET_CONNECTION_REJECTED");
516
+ }
517
+ }
518
+ throw new X402Error(
519
+ `Failed to connect Phantom: ${error instanceof Error ? error.message : "Unknown error"}`,
520
+ "UNKNOWN_ERROR",
521
+ error
522
+ );
523
+ }
524
+ }
525
+ /**
526
+ * Disconnect from Phantom
527
+ */
528
+ async disconnect() {
529
+ if (this.provider) {
530
+ try {
531
+ await this.provider.disconnect();
532
+ } catch {
533
+ }
534
+ }
535
+ this.provider = null;
536
+ this.publicKey = null;
537
+ this.connections.clear();
538
+ this.address = null;
539
+ }
540
+ /**
541
+ * Get current address
542
+ */
543
+ getAddress() {
544
+ return this.address;
545
+ }
546
+ /**
547
+ * Get USDC balance
548
+ */
549
+ async getBalance(chainConfig) {
550
+ await loadSolanaDeps();
551
+ if (!this.address) {
552
+ throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
553
+ }
554
+ await this.initConnection(chainConfig);
555
+ const connection = this.connections.get(chainConfig.name);
556
+ if (!connection) {
557
+ throw new X402Error("Failed to connect to Solana RPC", "NETWORK_ERROR");
558
+ }
559
+ try {
560
+ const response = await fetch(chainConfig.rpcUrl, {
561
+ method: "POST",
562
+ headers: { "Content-Type": "application/json" },
563
+ body: JSON.stringify({
564
+ jsonrpc: "2.0",
565
+ id: 1,
566
+ method: "getTokenAccountsByOwner",
567
+ params: [
568
+ this.address,
569
+ { mint: chainConfig.usdc.address },
570
+ { encoding: "jsonParsed" }
571
+ ]
572
+ })
573
+ });
574
+ const data = await response.json();
575
+ if (!data.result?.value?.length) {
576
+ return "0.00";
577
+ }
578
+ const tokenAccountInfo = data.result.value[0].account.data.parsed.info;
579
+ const balance = Number(tokenAccountInfo.tokenAmount.amount) / Math.pow(10, tokenAccountInfo.tokenAmount.decimals);
580
+ return balance.toFixed(2);
581
+ } catch {
582
+ return "0.00";
583
+ }
584
+ }
585
+ /**
586
+ * Create SVM payment (partially-signed transaction)
587
+ *
588
+ * Works for both Solana and Fogo chains.
589
+ *
590
+ * Transaction structure required by facilitator:
591
+ * 1. SetComputeUnitLimit
592
+ * 2. SetComputeUnitPrice
593
+ * 3. (Optional) CreateAssociatedTokenAccount if recipient ATA doesn't exist
594
+ * 4. TransferChecked (USDC transfer)
595
+ *
596
+ * Fee payer: Facilitator (not user)
597
+ * User pays: ZERO SOL/FOGO
598
+ */
599
+ async signPayment(paymentInfo, chainConfig) {
600
+ await loadSolanaDeps();
601
+ if (!this.provider || !this.publicKey || !this.address) {
602
+ throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
603
+ }
604
+ const connection = await this.getConnection(chainConfig);
605
+ if (!connection) {
606
+ throw new X402Error(`Failed to connect to ${chainConfig.displayName} RPC`, "NETWORK_ERROR");
607
+ }
608
+ const recipient = paymentInfo.recipients?.solana || paymentInfo.recipient;
609
+ const facilitatorAddress = paymentInfo.facilitator;
610
+ if (!facilitatorAddress) {
611
+ throw new X402Error("Facilitator address not provided", "INVALID_CONFIG");
612
+ }
613
+ const recipientPubkey = new PublicKey(recipient);
614
+ const facilitatorPubkey = new PublicKey(facilitatorAddress);
615
+ const usdcMint = new PublicKey(chainConfig.usdc.address);
616
+ const amount = Math.floor(parseFloat(paymentInfo.amount) * 1e6);
617
+ const fromTokenAccount = await getAssociatedTokenAddress(
618
+ usdcMint,
619
+ this.publicKey,
620
+ true,
621
+ TOKEN_PROGRAM_ID
622
+ );
623
+ const toTokenAccount = await getAssociatedTokenAddress(
624
+ usdcMint,
625
+ recipientPubkey,
626
+ true,
627
+ TOKEN_PROGRAM_ID
628
+ );
629
+ const toTokenAccountInfo = await connection.getAccountInfo(toTokenAccount);
630
+ const needsATACreation = toTokenAccountInfo === null;
631
+ const { blockhash } = await connection.getLatestBlockhash("finalized");
632
+ const instructions = [];
633
+ instructions.push(
634
+ ComputeBudgetProgram.setComputeUnitLimit({
635
+ units: needsATACreation ? 5e4 : 2e4
636
+ })
637
+ );
638
+ instructions.push(
639
+ ComputeBudgetProgram.setComputeUnitPrice({
640
+ microLamports: 1
641
+ })
642
+ );
643
+ if (needsATACreation) {
644
+ instructions.push(
645
+ createAssociatedTokenAccountIdempotentInstruction(
646
+ this.publicKey,
647
+ // User pays for ATA creation
648
+ toTokenAccount,
649
+ recipientPubkey,
650
+ usdcMint,
651
+ TOKEN_PROGRAM_ID
652
+ )
653
+ );
654
+ }
655
+ instructions.push(
656
+ createTransferCheckedInstruction(
657
+ fromTokenAccount,
658
+ usdcMint,
659
+ toTokenAccount,
660
+ this.publicKey,
661
+ amount,
662
+ 6,
663
+ [],
664
+ TOKEN_PROGRAM_ID
665
+ )
666
+ );
667
+ const messageV0 = new TransactionMessage({
668
+ payerKey: facilitatorPubkey,
669
+ recentBlockhash: blockhash,
670
+ instructions
671
+ }).compileToV0Message();
672
+ const transaction = new VersionedTransaction(messageV0);
673
+ let signedTransaction;
674
+ try {
675
+ signedTransaction = await this.provider.signTransaction(transaction);
676
+ } catch (error) {
677
+ if (error instanceof Error && error.message.includes("User rejected")) {
678
+ throw new X402Error("Signature rejected by user", "SIGNATURE_REJECTED");
679
+ }
680
+ throw new X402Error(
681
+ `Failed to sign transaction: ${error instanceof Error ? error.message : "Unknown error"}`,
682
+ "PAYMENT_FAILED",
683
+ error
684
+ );
685
+ }
686
+ const serialized = signedTransaction.serialize();
687
+ const payload = {
688
+ transaction: uint8ArrayToBase64(serialized)
689
+ };
690
+ return JSON.stringify(payload);
691
+ }
692
+ /**
693
+ * Encode SVM payment as X-PAYMENT header
694
+ *
695
+ * @param paymentPayload - The payment payload JSON string
696
+ * @param chainConfig - Optional chain config (defaults to 'solana' if not provided)
697
+ */
698
+ encodePaymentHeader(paymentPayload, chainConfig) {
699
+ const payload = JSON.parse(paymentPayload);
700
+ const networkName = chainConfig?.name || "solana";
701
+ const x402Payload = {
702
+ x402Version: 1,
703
+ scheme: "exact",
704
+ network: networkName,
705
+ payload: {
706
+ transaction: payload.transaction
707
+ }
708
+ };
709
+ return btoa(JSON.stringify(x402Payload));
710
+ }
711
+ // Private helpers
712
+ async getPhantomProvider() {
713
+ if (typeof window === "undefined") return null;
714
+ const win = window;
715
+ if (win.phantom?.solana?.isPhantom) {
716
+ return win.phantom.solana;
717
+ }
718
+ if (win.solana?.isPhantom) {
719
+ return win.solana;
720
+ }
721
+ for (let i = 0; i < 5; i++) {
722
+ await new Promise((resolve) => setTimeout(resolve, 100));
723
+ if (win.phantom?.solana?.isPhantom) {
724
+ return win.phantom.solana;
725
+ }
726
+ if (win.solana?.isPhantom) {
727
+ return win.solana;
728
+ }
729
+ }
730
+ return null;
731
+ }
732
+ /**
733
+ * Get or create a connection for a specific chain
734
+ */
735
+ async getConnection(chainConfig) {
736
+ await loadSolanaDeps();
737
+ const config = chainConfig || getChainByName("solana");
738
+ if (!config) {
739
+ throw new X402Error("Chain config not found", "CHAIN_NOT_SUPPORTED");
740
+ }
741
+ if (this.connections.has(config.name)) {
742
+ return this.connections.get(config.name);
743
+ }
744
+ const connection = new Connection(config.rpcUrl, "confirmed");
745
+ this.connections.set(config.name, connection);
746
+ return connection;
747
+ }
748
+ /**
749
+ * @deprecated Use getConnection instead
750
+ */
751
+ async initConnection(chainConfig) {
752
+ await this.getConnection(chainConfig);
753
+ }
754
+ };
755
+ var SolanaProvider = class extends SVMProvider {
756
+ constructor() {
757
+ super();
758
+ console.warn("SolanaProvider is deprecated. Use SVMProvider instead.");
759
+ }
760
+ };
761
+ var solana_default = SVMProvider;
762
+
763
+ export { SVMProvider, SolanaProvider, solana_default as default };
764
+ //# sourceMappingURL=index.mjs.map
765
+ //# sourceMappingURL=index.mjs.map