uvd-x402-sdk 2.1.0 → 2.2.0

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 (54) hide show
  1. package/README.md +282 -15
  2. package/dist/adapters/index.d.mts +1 -1
  3. package/dist/adapters/index.d.ts +1 -1
  4. package/dist/adapters/index.js +168 -0
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/adapters/index.mjs +168 -0
  7. package/dist/adapters/index.mjs.map +1 -1
  8. package/dist/{index-MTBgC_SL.d.mts → index-BHwtdJrt.d.mts} +45 -4
  9. package/dist/{index-MTBgC_SL.d.ts → index-BHwtdJrt.d.ts} +45 -4
  10. package/dist/{index-Db8dWNam.d.ts → index-CkDdnSNx.d.mts} +33 -2
  11. package/dist/{index-D0N_SYpK.d.mts → index-UTj85ZDJ.d.ts} +33 -2
  12. package/dist/index.d.mts +2 -2
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.js +210 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +207 -1
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/providers/evm/index.d.mts +19 -3
  19. package/dist/providers/evm/index.d.ts +19 -3
  20. package/dist/providers/evm/index.js +228 -12
  21. package/dist/providers/evm/index.js.map +1 -1
  22. package/dist/providers/evm/index.mjs +228 -12
  23. package/dist/providers/evm/index.mjs.map +1 -1
  24. package/dist/providers/near/index.d.mts +1 -1
  25. package/dist/providers/near/index.d.ts +1 -1
  26. package/dist/providers/near/index.js.map +1 -1
  27. package/dist/providers/near/index.mjs.map +1 -1
  28. package/dist/providers/solana/index.d.mts +1 -1
  29. package/dist/providers/solana/index.d.ts +1 -1
  30. package/dist/providers/solana/index.js +168 -0
  31. package/dist/providers/solana/index.js.map +1 -1
  32. package/dist/providers/solana/index.mjs +168 -0
  33. package/dist/providers/solana/index.mjs.map +1 -1
  34. package/dist/providers/stellar/index.d.mts +1 -1
  35. package/dist/providers/stellar/index.d.ts +1 -1
  36. package/dist/providers/stellar/index.js.map +1 -1
  37. package/dist/providers/stellar/index.mjs.map +1 -1
  38. package/dist/react/index.d.mts +3 -3
  39. package/dist/react/index.d.ts +3 -3
  40. package/dist/react/index.js +168 -0
  41. package/dist/react/index.js.map +1 -1
  42. package/dist/react/index.mjs +168 -0
  43. package/dist/react/index.mjs.map +1 -1
  44. package/dist/utils/index.d.mts +1 -1
  45. package/dist/utils/index.d.ts +1 -1
  46. package/dist/utils/index.js +168 -0
  47. package/dist/utils/index.js.map +1 -1
  48. package/dist/utils/index.mjs +168 -0
  49. package/dist/utils/index.mjs.map +1 -1
  50. package/package.json +5 -2
  51. package/src/chains/index.ts +255 -1
  52. package/src/index.ts +9 -0
  53. package/src/providers/evm/index.ts +64 -16
  54. package/src/types/index.ts +46 -3
@@ -8,7 +8,7 @@
8
8
  * NEAR (1): Uses NEP-366 meta-transactions
9
9
  */
10
10
 
11
- import type { ChainConfig, NetworkType } from '../types';
11
+ import type { ChainConfig, NetworkType, TokenType, TokenConfig } from '../types';
12
12
 
13
13
  /**
14
14
  * Default facilitator URL for x402 payments
@@ -47,6 +47,26 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
47
47
  name: 'USD Coin',
48
48
  version: '2',
49
49
  },
50
+ tokens: {
51
+ usdc: {
52
+ address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
53
+ decimals: 6,
54
+ name: 'USD Coin',
55
+ version: '2',
56
+ },
57
+ eurc: {
58
+ address: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
59
+ decimals: 6,
60
+ name: 'EURC',
61
+ version: '2',
62
+ },
63
+ gho: {
64
+ address: '0x6Bb7a212910682DCFdbd5BCBb3e28FB4E8da10Ee',
65
+ decimals: 18,
66
+ name: 'Gho Token',
67
+ version: '1',
68
+ },
69
+ },
50
70
  x402: {
51
71
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
52
72
  enabled: true,
@@ -72,6 +92,26 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
72
92
  name: 'USD Coin',
73
93
  version: '2',
74
94
  },
95
+ tokens: {
96
+ usdc: {
97
+ address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
98
+ decimals: 6,
99
+ name: 'USD Coin',
100
+ version: '2',
101
+ },
102
+ eurc: {
103
+ address: '0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
104
+ decimals: 6,
105
+ name: 'EURC',
106
+ version: '2',
107
+ },
108
+ ausd: {
109
+ address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
110
+ decimals: 6,
111
+ name: 'Agora USD',
112
+ version: '1',
113
+ },
114
+ },
75
115
  x402: {
76
116
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
77
117
  enabled: true,
@@ -97,6 +137,44 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
97
137
  name: 'USD Coin',
98
138
  version: '2',
99
139
  },
140
+ tokens: {
141
+ usdc: {
142
+ address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
143
+ decimals: 6,
144
+ name: 'USD Coin',
145
+ version: '2',
146
+ },
147
+ eurc: {
148
+ address: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
149
+ decimals: 6,
150
+ name: 'EURC',
151
+ version: '2',
152
+ },
153
+ ausd: {
154
+ address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
155
+ decimals: 6,
156
+ name: 'Agora USD',
157
+ version: '1',
158
+ },
159
+ pyusd: {
160
+ address: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8',
161
+ decimals: 6,
162
+ name: 'PayPal USD',
163
+ version: '1',
164
+ },
165
+ gho: {
166
+ address: '0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f',
167
+ decimals: 18,
168
+ name: 'Gho Token',
169
+ version: '1',
170
+ },
171
+ crvusd: {
172
+ address: '0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E',
173
+ decimals: 18,
174
+ name: 'Curve.Fi USD Stablecoin',
175
+ version: '1',
176
+ },
177
+ },
100
178
  x402: {
101
179
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
102
180
  enabled: true,
@@ -122,6 +200,20 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
122
200
  name: 'USD Coin',
123
201
  version: '2',
124
202
  },
203
+ tokens: {
204
+ usdc: {
205
+ address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
206
+ decimals: 6,
207
+ name: 'USD Coin',
208
+ version: '2',
209
+ },
210
+ ausd: {
211
+ address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
212
+ decimals: 6,
213
+ name: 'Agora USD',
214
+ version: '1',
215
+ },
216
+ },
125
217
  x402: {
126
218
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
127
219
  enabled: true,
@@ -147,6 +239,32 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
147
239
  name: 'USD Coin',
148
240
  version: '2',
149
241
  },
242
+ tokens: {
243
+ usdc: {
244
+ address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
245
+ decimals: 6,
246
+ name: 'USD Coin',
247
+ version: '2',
248
+ },
249
+ ausd: {
250
+ address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
251
+ decimals: 6,
252
+ name: 'Agora USD',
253
+ version: '1',
254
+ },
255
+ gho: {
256
+ address: '0x7dfF72693f6A4149b17e7C6314655f6A9F7c8B33',
257
+ decimals: 18,
258
+ name: 'Gho Token',
259
+ version: '1',
260
+ },
261
+ crvusd: {
262
+ address: '0x498Bf2B1e120FeD3ad3D42EA2165E9b73f99C1e5',
263
+ decimals: 18,
264
+ name: 'Curve.Fi USD Stablecoin',
265
+ version: '1',
266
+ },
267
+ },
150
268
  x402: {
151
269
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
152
270
  enabled: true,
@@ -172,6 +290,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
172
290
  name: 'USD Coin',
173
291
  version: '2',
174
292
  },
293
+ tokens: {
294
+ usdc: {
295
+ address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
296
+ decimals: 6,
297
+ name: 'USD Coin',
298
+ version: '2',
299
+ },
300
+ },
175
301
  x402: {
176
302
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
177
303
  enabled: true,
@@ -197,6 +323,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
197
323
  name: 'USDC', // Celo uses "USDC" not "USD Coin" for EIP-712
198
324
  version: '2',
199
325
  },
326
+ tokens: {
327
+ usdc: {
328
+ address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
329
+ decimals: 6,
330
+ name: 'USDC', // Celo uses "USDC" not "USD Coin" for EIP-712
331
+ version: '2',
332
+ },
333
+ },
200
334
  x402: {
201
335
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
202
336
  enabled: true,
@@ -222,6 +356,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
222
356
  name: 'USDC', // HyperEVM uses "USDC" not "USD Coin"
223
357
  version: '2',
224
358
  },
359
+ tokens: {
360
+ usdc: {
361
+ address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',
362
+ decimals: 6,
363
+ name: 'USDC', // HyperEVM uses "USDC" not "USD Coin"
364
+ version: '2',
365
+ },
366
+ },
225
367
  x402: {
226
368
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
227
369
  enabled: true,
@@ -247,6 +389,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
247
389
  name: 'USDC', // Unichain uses "USDC" not "USD Coin"
248
390
  version: '2',
249
391
  },
392
+ tokens: {
393
+ usdc: {
394
+ address: '0x078d782b760474a361dda0af3839290b0ef57ad6',
395
+ decimals: 6,
396
+ name: 'USDC', // Unichain uses "USDC" not "USD Coin"
397
+ version: '2',
398
+ },
399
+ },
250
400
  x402: {
251
401
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
252
402
  enabled: true,
@@ -272,6 +422,20 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
272
422
  name: 'USDC', // Monad uses "USDC" not "USD Coin"
273
423
  version: '2',
274
424
  },
425
+ tokens: {
426
+ usdc: {
427
+ address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',
428
+ decimals: 6,
429
+ name: 'USDC', // Monad uses "USDC" not "USD Coin"
430
+ version: '2',
431
+ },
432
+ ausd: {
433
+ address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
434
+ decimals: 6,
435
+ name: 'Agora USD',
436
+ version: '1',
437
+ },
438
+ },
275
439
  x402: {
276
440
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
277
441
  enabled: true,
@@ -511,3 +675,93 @@ export function getExplorerAddressUrl(chainName: string, address: string): strin
511
675
  return null;
512
676
  }
513
677
  }
678
+
679
+ // ============================================================================
680
+ // MULTI-TOKEN SUPPORT FUNCTIONS
681
+ // ============================================================================
682
+
683
+ /**
684
+ * Get token configuration for a specific chain and token type
685
+ * Falls back to USDC config if token not found (for backward compatibility)
686
+ *
687
+ * @param chainName - Chain name (e.g., 'ethereum', 'base')
688
+ * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'gho')
689
+ * @returns Token configuration or undefined if chain not found
690
+ */
691
+ export function getTokenConfig(
692
+ chainName: string,
693
+ tokenType: TokenType = 'usdc'
694
+ ): TokenConfig | undefined {
695
+ const chain = getChainByName(chainName);
696
+ if (!chain) return undefined;
697
+
698
+ // Try to get from tokens map first (new multi-token support)
699
+ if (chain.tokens && chain.tokens[tokenType]) {
700
+ return chain.tokens[tokenType];
701
+ }
702
+
703
+ // Fall back to usdc config for backward compatibility
704
+ if (tokenType === 'usdc') {
705
+ return chain.usdc;
706
+ }
707
+
708
+ return undefined;
709
+ }
710
+
711
+ /**
712
+ * Get list of supported tokens for a chain
713
+ *
714
+ * @param chainName - Chain name (e.g., 'ethereum', 'base')
715
+ * @returns Array of supported token types, or empty array if chain not found
716
+ */
717
+ export function getSupportedTokens(chainName: string): TokenType[] {
718
+ const chain = getChainByName(chainName);
719
+ if (!chain) return [];
720
+
721
+ // If tokens map exists, return its keys
722
+ if (chain.tokens) {
723
+ return Object.keys(chain.tokens) as TokenType[];
724
+ }
725
+
726
+ // Default to just USDC for chains without explicit tokens map
727
+ return ['usdc'];
728
+ }
729
+
730
+ /**
731
+ * Check if a token is supported on a specific chain
732
+ *
733
+ * @param chainName - Chain name (e.g., 'ethereum', 'base')
734
+ * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'gho')
735
+ * @returns true if token is supported on the chain
736
+ */
737
+ export function isTokenSupported(chainName: string, tokenType: TokenType): boolean {
738
+ const chain = getChainByName(chainName);
739
+ if (!chain) return false;
740
+
741
+ // Check tokens map
742
+ if (chain.tokens && chain.tokens[tokenType]) {
743
+ return true;
744
+ }
745
+
746
+ // USDC is always supported (backward compatibility)
747
+ if (tokenType === 'usdc') {
748
+ return true;
749
+ }
750
+
751
+ return false;
752
+ }
753
+
754
+ /**
755
+ * Get all chains that support a specific token
756
+ *
757
+ * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'gho')
758
+ * @returns Array of chain configs that support the token
759
+ */
760
+ export function getChainsByToken(tokenType: TokenType): ChainConfig[] {
761
+ return Object.values(SUPPORTED_CHAINS).filter(chain => {
762
+ if (!chain.x402.enabled) return false;
763
+ if (chain.tokens && chain.tokens[tokenType]) return true;
764
+ if (tokenType === 'usdc') return true; // USDC is universal
765
+ return false;
766
+ });
767
+ }
package/src/index.ts CHANGED
@@ -95,6 +95,11 @@ export {
95
95
  getNetworkType,
96
96
  getExplorerTxUrl,
97
97
  getExplorerAddressUrl,
98
+ // Multi-token support functions
99
+ getTokenConfig,
100
+ getSupportedTokens,
101
+ isTokenSupported,
102
+ getChainsByToken,
98
103
  } from './chains';
99
104
 
100
105
  // x402 utilities
@@ -121,6 +126,10 @@ export type {
121
126
  NativeCurrency,
122
127
  NetworkType,
123
128
 
129
+ // Token types (multi-token support)
130
+ TokenType,
131
+ TokenConfig,
132
+
124
133
  // Wallet types
125
134
  WalletState,
126
135
  WalletAdapter,
@@ -27,9 +27,11 @@ import type {
27
27
  PaymentInfo,
28
28
  EVMPaymentPayload,
29
29
  WalletAdapter,
30
+ TokenType,
31
+ TokenConfig,
30
32
  } from '../../types';
31
33
  import { X402Error } from '../../types';
32
- import { getChainByName, getChainById } from '../../chains';
34
+ import { getChainByName, getChainById, getTokenConfig } from '../../chains';
33
35
 
34
36
  /**
35
37
  * Ethereum provider interface
@@ -197,22 +199,48 @@ export class EVMProvider implements WalletAdapter {
197
199
  }
198
200
 
199
201
  /**
200
- * Get USDC balance
202
+ * Get token balance (defaults to USDC for backward compatibility)
203
+ *
204
+ * @param chainConfig - Chain configuration
205
+ * @param tokenType - Token type to check balance for (defaults to 'usdc')
206
+ * @returns Formatted balance string
201
207
  */
202
- async getBalance(chainConfig: ChainConfig): Promise<string> {
208
+ async getBalance(chainConfig: ChainConfig, tokenType: TokenType = 'usdc'): Promise<string> {
203
209
  if (!this.address) {
204
210
  throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');
205
211
  }
206
212
 
213
+ // Get token config for the specified token type
214
+ const tokenConfig = getTokenConfig(chainConfig.name, tokenType);
215
+ if (!tokenConfig) {
216
+ // Fall back to USDC config for backward compatibility
217
+ const fallbackConfig = chainConfig.usdc;
218
+ if (!fallbackConfig) {
219
+ throw new X402Error(`Token ${tokenType} not supported on ${chainConfig.name}`, 'INVALID_CONFIG');
220
+ }
221
+ return this.getBalanceWithConfig(chainConfig.rpcUrl, fallbackConfig);
222
+ }
223
+
224
+ return this.getBalanceWithConfig(chainConfig.rpcUrl, tokenConfig);
225
+ }
226
+
227
+ /**
228
+ * Internal helper to get balance using a token config
229
+ */
230
+ private async getBalanceWithConfig(rpcUrl: string, tokenConfig: TokenConfig): Promise<string> {
231
+ if (!this.address) {
232
+ return '0.00';
233
+ }
234
+
207
235
  // Use public RPC for balance check
208
- const publicProvider = new ethers.JsonRpcProvider(chainConfig.rpcUrl);
236
+ const publicProvider = new ethers.JsonRpcProvider(rpcUrl);
209
237
 
210
- const usdcAbi = ['function balanceOf(address owner) view returns (uint256)'];
211
- const usdcContract = new ethers.Contract(chainConfig.usdc.address, usdcAbi, publicProvider);
238
+ const tokenAbi = ['function balanceOf(address owner) view returns (uint256)'];
239
+ const tokenContract = new ethers.Contract(tokenConfig.address, tokenAbi, publicProvider);
212
240
 
213
241
  try {
214
- const balance = await usdcContract.balanceOf(this.address);
215
- const formatted = ethers.formatUnits(balance, chainConfig.usdc.decimals);
242
+ const balance = await tokenContract.balanceOf(this.address);
243
+ const formatted = ethers.formatUnits(balance, tokenConfig.decimals);
216
244
  return parseFloat(formatted).toFixed(2);
217
245
  } catch {
218
246
  return '0.00';
@@ -221,12 +249,32 @@ export class EVMProvider implements WalletAdapter {
221
249
 
222
250
  /**
223
251
  * Create EVM payment (EIP-712 TransferWithAuthorization)
252
+ *
253
+ * Supports multi-token payments. If paymentInfo.tokenType is specified,
254
+ * it will use the appropriate token configuration. Defaults to USDC
255
+ * for backward compatibility.
256
+ *
257
+ * @param paymentInfo - Payment details including amount and recipient
258
+ * @param chainConfig - Chain configuration
259
+ * @returns JSON-encoded payment payload
224
260
  */
225
261
  async signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string> {
226
262
  if (!this.signer || !this.address) {
227
263
  throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');
228
264
  }
229
265
 
266
+ // Determine token type (default to 'usdc' for backward compatibility)
267
+ const tokenType: TokenType = paymentInfo.tokenType || 'usdc';
268
+
269
+ // Get token configuration for the specified token type
270
+ const tokenConfig = getTokenConfig(chainConfig.name, tokenType);
271
+ if (!tokenConfig) {
272
+ throw new X402Error(
273
+ `Token ${tokenType} not supported on ${chainConfig.name}`,
274
+ 'CHAIN_NOT_SUPPORTED'
275
+ );
276
+ }
277
+
230
278
  // Get recipient
231
279
  const recipient = paymentInfo.recipients?.evm || paymentInfo.recipient;
232
280
 
@@ -246,12 +294,12 @@ export class EVMProvider implements WalletAdapter {
246
294
  const validityWindowSeconds = chainConfig.name === 'base' ? 300 : 60;
247
295
  const validBefore = Math.floor(Date.now() / 1000) + validityWindowSeconds;
248
296
 
249
- // EIP-712 domain
297
+ // EIP-712 domain using the selected token's configuration
250
298
  const domain = {
251
- name: chainConfig.usdc.name,
252
- version: chainConfig.usdc.version,
299
+ name: tokenConfig.name,
300
+ version: tokenConfig.version,
253
301
  chainId: chainConfig.chainId,
254
- verifyingContract: chainConfig.usdc.address,
302
+ verifyingContract: tokenConfig.address,
255
303
  };
256
304
 
257
305
  // EIP-712 types for TransferWithAuthorization (ERC-3009)
@@ -266,8 +314,8 @@ export class EVMProvider implements WalletAdapter {
266
314
  ],
267
315
  };
268
316
 
269
- // Parse amount
270
- const value = ethers.parseUnits(paymentInfo.amount, chainConfig.usdc.decimals);
317
+ // Parse amount using the token's decimals
318
+ const value = ethers.parseUnits(paymentInfo.amount, tokenConfig.decimals);
271
319
  const from = this.address;
272
320
  const to = ethers.getAddress(recipient);
273
321
 
@@ -298,7 +346,7 @@ export class EVMProvider implements WalletAdapter {
298
346
 
299
347
  const sig = ethers.Signature.from(signature);
300
348
 
301
- // Construct payload
349
+ // Construct payload with the selected token address
302
350
  const payload: EVMPaymentPayload = {
303
351
  from,
304
352
  to,
@@ -310,7 +358,7 @@ export class EVMProvider implements WalletAdapter {
310
358
  r: sig.r,
311
359
  s: sig.s,
312
360
  chainId: chainConfig.chainId,
313
- token: chainConfig.usdc.address,
361
+ token: tokenConfig.address,
314
362
  };
315
363
 
316
364
  return JSON.stringify(payload);
@@ -20,8 +20,34 @@
20
20
  */
21
21
  export type NetworkType = 'evm' | 'svm' | 'solana' | 'stellar' | 'near';
22
22
 
23
+ /**
24
+ * Supported stablecoin token types
25
+ * - usdc: USD Coin (Circle) - 6 decimals
26
+ * - eurc: Euro Coin (Circle) - 6 decimals
27
+ * - ausd: Agora USD (Agora Finance) - 6 decimals
28
+ * - pyusd: PayPal USD (PayPal/Paxos) - 6 decimals
29
+ * - gho: GHO Stablecoin (Aave) - 18 decimals
30
+ * - crvusd: Curve USD (Curve Finance) - 18 decimals
31
+ */
32
+ export type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd' | 'gho' | 'crvusd';
33
+
34
+ /**
35
+ * Token configuration for EIP-712 signing and transfers
36
+ */
37
+ export interface TokenConfig {
38
+ /** Contract/mint address */
39
+ address: string;
40
+ /** Token decimals (6 for most stablecoins, 18 for GHO/crvUSD) */
41
+ decimals: number;
42
+ /** Token name for EIP-712 domain (e.g., "USD Coin" or "USDC") */
43
+ name: string;
44
+ /** Token version for EIP-712 domain */
45
+ version: string;
46
+ }
47
+
23
48
  /**
24
49
  * USDC token configuration for a specific chain
50
+ * @deprecated Use TokenConfig instead. This is kept for backward compatibility.
25
51
  */
26
52
  export interface USDCConfig {
27
53
  /** Contract/mint address */
@@ -65,6 +91,12 @@ export interface ChainConfig {
65
91
  nativeCurrency: NativeCurrency;
66
92
  /** USDC token configuration */
67
93
  usdc: USDCConfig;
94
+ /**
95
+ * Multi-token configurations (EVM chains only)
96
+ * Maps token type to its configuration for this chain.
97
+ * Not all tokens are available on all chains.
98
+ */
99
+ tokens?: Partial<Record<TokenType, TokenConfig>>;
68
100
  /** x402 facilitator configuration */
69
101
  x402: {
70
102
  facilitatorUrl: string;
@@ -117,11 +149,17 @@ export interface WalletAdapter {
117
149
  /** Switch to a different chain (EVM only) */
118
150
  switchChain?(chainName: string): Promise<void>;
119
151
 
120
- /** Sign a payment payload */
152
+ /**
153
+ * Sign a payment payload
154
+ * For EVM chains, supports multi-token via paymentInfo.tokenType
155
+ */
121
156
  signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;
122
157
 
123
- /** Check USDC balance */
124
- getBalance(chainConfig: ChainConfig): Promise<string>;
158
+ /**
159
+ * Check token balance (defaults to USDC for backward compatibility)
160
+ * EVM providers may accept optional tokenType parameter
161
+ */
162
+ getBalance(chainConfig: ChainConfig, tokenType?: TokenType): Promise<string>;
125
163
 
126
164
  /** Get current address */
127
165
  getAddress(): string | null;
@@ -170,6 +208,11 @@ export interface PaymentInfo {
170
208
  amount: string;
171
209
  /** Token symbol (usually "USDC") */
172
210
  token?: string;
211
+ /**
212
+ * Token type for multi-token support
213
+ * Defaults to 'usdc' if not specified for backward compatibility
214
+ */
215
+ tokenType?: TokenType;
173
216
  /** Network hint from backend */
174
217
  network?: string;
175
218
  /** Supported chain IDs */