uvd-x402-sdk 2.1.0 → 2.2.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.
- package/README.md +280 -15
- package/dist/adapters/index.d.mts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +138 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +138 -0
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/{index-MTBgC_SL.d.mts → index-BG738nMY.d.mts} +43 -4
- package/dist/{index-MTBgC_SL.d.ts → index-BG738nMY.d.ts} +43 -4
- package/dist/{index-Db8dWNam.d.ts → index-I60aHxwu.d.mts} +33 -2
- package/dist/{index-D0N_SYpK.d.mts → index-OZTSi1rJ.d.ts} +33 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +180 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -1
- package/dist/index.mjs.map +1 -1
- package/dist/providers/evm/index.d.mts +19 -3
- package/dist/providers/evm/index.d.ts +19 -3
- package/dist/providers/evm/index.js +198 -12
- package/dist/providers/evm/index.js.map +1 -1
- package/dist/providers/evm/index.mjs +198 -12
- package/dist/providers/evm/index.mjs.map +1 -1
- package/dist/providers/near/index.d.mts +1 -1
- package/dist/providers/near/index.d.ts +1 -1
- package/dist/providers/near/index.js.map +1 -1
- package/dist/providers/near/index.mjs.map +1 -1
- package/dist/providers/solana/index.d.mts +1 -1
- package/dist/providers/solana/index.d.ts +1 -1
- package/dist/providers/solana/index.js +138 -0
- package/dist/providers/solana/index.js.map +1 -1
- package/dist/providers/solana/index.mjs +138 -0
- package/dist/providers/solana/index.mjs.map +1 -1
- package/dist/providers/stellar/index.d.mts +1 -1
- package/dist/providers/stellar/index.d.ts +1 -1
- package/dist/providers/stellar/index.js.map +1 -1
- package/dist/providers/stellar/index.mjs.map +1 -1
- package/dist/react/index.d.mts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +138 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +138 -0
- package/dist/react/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +138 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +138 -0
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +5 -2
- package/src/chains/index.ts +225 -1
- package/src/index.ts +9 -0
- package/src/providers/evm/index.ts +64 -16
- package/src/types/index.ts +44 -3
package/src/chains/index.ts
CHANGED
|
@@ -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,20 @@ 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
|
+
},
|
|
50
64
|
x402: {
|
|
51
65
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
52
66
|
enabled: true,
|
|
@@ -72,6 +86,26 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
72
86
|
name: 'USD Coin',
|
|
73
87
|
version: '2',
|
|
74
88
|
},
|
|
89
|
+
tokens: {
|
|
90
|
+
usdc: {
|
|
91
|
+
address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
|
|
92
|
+
decimals: 6,
|
|
93
|
+
name: 'USD Coin',
|
|
94
|
+
version: '2',
|
|
95
|
+
},
|
|
96
|
+
eurc: {
|
|
97
|
+
address: '0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
|
|
98
|
+
decimals: 6,
|
|
99
|
+
name: 'EURC',
|
|
100
|
+
version: '2',
|
|
101
|
+
},
|
|
102
|
+
ausd: {
|
|
103
|
+
address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
|
|
104
|
+
decimals: 6,
|
|
105
|
+
name: 'Agora USD',
|
|
106
|
+
version: '1',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
75
109
|
x402: {
|
|
76
110
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
77
111
|
enabled: true,
|
|
@@ -97,6 +131,32 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
97
131
|
name: 'USD Coin',
|
|
98
132
|
version: '2',
|
|
99
133
|
},
|
|
134
|
+
tokens: {
|
|
135
|
+
usdc: {
|
|
136
|
+
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
137
|
+
decimals: 6,
|
|
138
|
+
name: 'USD Coin',
|
|
139
|
+
version: '2',
|
|
140
|
+
},
|
|
141
|
+
eurc: {
|
|
142
|
+
address: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
|
|
143
|
+
decimals: 6,
|
|
144
|
+
name: 'EURC',
|
|
145
|
+
version: '2',
|
|
146
|
+
},
|
|
147
|
+
ausd: {
|
|
148
|
+
address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
|
|
149
|
+
decimals: 6,
|
|
150
|
+
name: 'Agora USD',
|
|
151
|
+
version: '1',
|
|
152
|
+
},
|
|
153
|
+
pyusd: {
|
|
154
|
+
address: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8',
|
|
155
|
+
decimals: 6,
|
|
156
|
+
name: 'PayPal USD',
|
|
157
|
+
version: '1',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
100
160
|
x402: {
|
|
101
161
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
102
162
|
enabled: true,
|
|
@@ -122,6 +182,20 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
122
182
|
name: 'USD Coin',
|
|
123
183
|
version: '2',
|
|
124
184
|
},
|
|
185
|
+
tokens: {
|
|
186
|
+
usdc: {
|
|
187
|
+
address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
|
|
188
|
+
decimals: 6,
|
|
189
|
+
name: 'USD Coin',
|
|
190
|
+
version: '2',
|
|
191
|
+
},
|
|
192
|
+
ausd: {
|
|
193
|
+
address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
|
|
194
|
+
decimals: 6,
|
|
195
|
+
name: 'Agora USD',
|
|
196
|
+
version: '1',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
125
199
|
x402: {
|
|
126
200
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
127
201
|
enabled: true,
|
|
@@ -147,6 +221,20 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
147
221
|
name: 'USD Coin',
|
|
148
222
|
version: '2',
|
|
149
223
|
},
|
|
224
|
+
tokens: {
|
|
225
|
+
usdc: {
|
|
226
|
+
address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
|
227
|
+
decimals: 6,
|
|
228
|
+
name: 'USD Coin',
|
|
229
|
+
version: '2',
|
|
230
|
+
},
|
|
231
|
+
ausd: {
|
|
232
|
+
address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
|
|
233
|
+
decimals: 6,
|
|
234
|
+
name: 'Agora USD',
|
|
235
|
+
version: '1',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
150
238
|
x402: {
|
|
151
239
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
152
240
|
enabled: true,
|
|
@@ -172,6 +260,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
172
260
|
name: 'USD Coin',
|
|
173
261
|
version: '2',
|
|
174
262
|
},
|
|
263
|
+
tokens: {
|
|
264
|
+
usdc: {
|
|
265
|
+
address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
|
|
266
|
+
decimals: 6,
|
|
267
|
+
name: 'USD Coin',
|
|
268
|
+
version: '2',
|
|
269
|
+
},
|
|
270
|
+
},
|
|
175
271
|
x402: {
|
|
176
272
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
177
273
|
enabled: true,
|
|
@@ -197,6 +293,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
197
293
|
name: 'USDC', // Celo uses "USDC" not "USD Coin" for EIP-712
|
|
198
294
|
version: '2',
|
|
199
295
|
},
|
|
296
|
+
tokens: {
|
|
297
|
+
usdc: {
|
|
298
|
+
address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
|
|
299
|
+
decimals: 6,
|
|
300
|
+
name: 'USDC', // Celo uses "USDC" not "USD Coin" for EIP-712
|
|
301
|
+
version: '2',
|
|
302
|
+
},
|
|
303
|
+
},
|
|
200
304
|
x402: {
|
|
201
305
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
202
306
|
enabled: true,
|
|
@@ -222,6 +326,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
222
326
|
name: 'USDC', // HyperEVM uses "USDC" not "USD Coin"
|
|
223
327
|
version: '2',
|
|
224
328
|
},
|
|
329
|
+
tokens: {
|
|
330
|
+
usdc: {
|
|
331
|
+
address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',
|
|
332
|
+
decimals: 6,
|
|
333
|
+
name: 'USDC', // HyperEVM uses "USDC" not "USD Coin"
|
|
334
|
+
version: '2',
|
|
335
|
+
},
|
|
336
|
+
},
|
|
225
337
|
x402: {
|
|
226
338
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
227
339
|
enabled: true,
|
|
@@ -247,6 +359,14 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
247
359
|
name: 'USDC', // Unichain uses "USDC" not "USD Coin"
|
|
248
360
|
version: '2',
|
|
249
361
|
},
|
|
362
|
+
tokens: {
|
|
363
|
+
usdc: {
|
|
364
|
+
address: '0x078d782b760474a361dda0af3839290b0ef57ad6',
|
|
365
|
+
decimals: 6,
|
|
366
|
+
name: 'USDC', // Unichain uses "USDC" not "USD Coin"
|
|
367
|
+
version: '2',
|
|
368
|
+
},
|
|
369
|
+
},
|
|
250
370
|
x402: {
|
|
251
371
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
252
372
|
enabled: true,
|
|
@@ -272,6 +392,20 @@ export const SUPPORTED_CHAINS: Record<string, ChainConfig> = {
|
|
|
272
392
|
name: 'USDC', // Monad uses "USDC" not "USD Coin"
|
|
273
393
|
version: '2',
|
|
274
394
|
},
|
|
395
|
+
tokens: {
|
|
396
|
+
usdc: {
|
|
397
|
+
address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',
|
|
398
|
+
decimals: 6,
|
|
399
|
+
name: 'USDC', // Monad uses "USDC" not "USD Coin"
|
|
400
|
+
version: '2',
|
|
401
|
+
},
|
|
402
|
+
ausd: {
|
|
403
|
+
address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',
|
|
404
|
+
decimals: 6,
|
|
405
|
+
name: 'Agora USD',
|
|
406
|
+
version: '1',
|
|
407
|
+
},
|
|
408
|
+
},
|
|
275
409
|
x402: {
|
|
276
410
|
facilitatorUrl: DEFAULT_FACILITATOR_URL,
|
|
277
411
|
enabled: true,
|
|
@@ -511,3 +645,93 @@ export function getExplorerAddressUrl(chainName: string, address: string): strin
|
|
|
511
645
|
return null;
|
|
512
646
|
}
|
|
513
647
|
}
|
|
648
|
+
|
|
649
|
+
// ============================================================================
|
|
650
|
+
// MULTI-TOKEN SUPPORT FUNCTIONS
|
|
651
|
+
// ============================================================================
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Get token configuration for a specific chain and token type
|
|
655
|
+
* Falls back to USDC config if token not found (for backward compatibility)
|
|
656
|
+
*
|
|
657
|
+
* @param chainName - Chain name (e.g., 'ethereum', 'base')
|
|
658
|
+
* @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')
|
|
659
|
+
* @returns Token configuration or undefined if chain not found
|
|
660
|
+
*/
|
|
661
|
+
export function getTokenConfig(
|
|
662
|
+
chainName: string,
|
|
663
|
+
tokenType: TokenType = 'usdc'
|
|
664
|
+
): TokenConfig | undefined {
|
|
665
|
+
const chain = getChainByName(chainName);
|
|
666
|
+
if (!chain) return undefined;
|
|
667
|
+
|
|
668
|
+
// Try to get from tokens map first (new multi-token support)
|
|
669
|
+
if (chain.tokens && chain.tokens[tokenType]) {
|
|
670
|
+
return chain.tokens[tokenType];
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Fall back to usdc config for backward compatibility
|
|
674
|
+
if (tokenType === 'usdc') {
|
|
675
|
+
return chain.usdc;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return undefined;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Get list of supported tokens for a chain
|
|
683
|
+
*
|
|
684
|
+
* @param chainName - Chain name (e.g., 'ethereum', 'base')
|
|
685
|
+
* @returns Array of supported token types, or empty array if chain not found
|
|
686
|
+
*/
|
|
687
|
+
export function getSupportedTokens(chainName: string): TokenType[] {
|
|
688
|
+
const chain = getChainByName(chainName);
|
|
689
|
+
if (!chain) return [];
|
|
690
|
+
|
|
691
|
+
// If tokens map exists, return its keys
|
|
692
|
+
if (chain.tokens) {
|
|
693
|
+
return Object.keys(chain.tokens) as TokenType[];
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Default to just USDC for chains without explicit tokens map
|
|
697
|
+
return ['usdc'];
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Check if a token is supported on a specific chain
|
|
702
|
+
*
|
|
703
|
+
* @param chainName - Chain name (e.g., 'ethereum', 'base')
|
|
704
|
+
* @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')
|
|
705
|
+
* @returns true if token is supported on the chain
|
|
706
|
+
*/
|
|
707
|
+
export function isTokenSupported(chainName: string, tokenType: TokenType): boolean {
|
|
708
|
+
const chain = getChainByName(chainName);
|
|
709
|
+
if (!chain) return false;
|
|
710
|
+
|
|
711
|
+
// Check tokens map
|
|
712
|
+
if (chain.tokens && chain.tokens[tokenType]) {
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// USDC is always supported (backward compatibility)
|
|
717
|
+
if (tokenType === 'usdc') {
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
return false;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Get all chains that support a specific token
|
|
726
|
+
*
|
|
727
|
+
* @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')
|
|
728
|
+
* @returns Array of chain configs that support the token
|
|
729
|
+
*/
|
|
730
|
+
export function getChainsByToken(tokenType: TokenType): ChainConfig[] {
|
|
731
|
+
return Object.values(SUPPORTED_CHAINS).filter(chain => {
|
|
732
|
+
if (!chain.x402.enabled) return false;
|
|
733
|
+
if (chain.tokens && chain.tokens[tokenType]) return true;
|
|
734
|
+
if (tokenType === 'usdc') return true; // USDC is universal
|
|
735
|
+
return false;
|
|
736
|
+
});
|
|
737
|
+
}
|
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
|
|
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(
|
|
236
|
+
const publicProvider = new ethers.JsonRpcProvider(rpcUrl);
|
|
209
237
|
|
|
210
|
-
const
|
|
211
|
-
const
|
|
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
|
|
215
|
-
const formatted = ethers.formatUnits(balance,
|
|
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:
|
|
252
|
-
version:
|
|
299
|
+
name: tokenConfig.name,
|
|
300
|
+
version: tokenConfig.version,
|
|
253
301
|
chainId: chainConfig.chainId,
|
|
254
|
-
verifyingContract:
|
|
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,
|
|
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:
|
|
361
|
+
token: tokenConfig.address,
|
|
314
362
|
};
|
|
315
363
|
|
|
316
364
|
return JSON.stringify(payload);
|
package/src/types/index.ts
CHANGED
|
@@ -20,8 +20,32 @@
|
|
|
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
|
+
*/
|
|
30
|
+
export type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Token configuration for EIP-712 signing and transfers
|
|
34
|
+
*/
|
|
35
|
+
export interface TokenConfig {
|
|
36
|
+
/** Contract/mint address */
|
|
37
|
+
address: string;
|
|
38
|
+
/** Token decimals (6 for all supported stablecoins) */
|
|
39
|
+
decimals: number;
|
|
40
|
+
/** Token name for EIP-712 domain (e.g., "USD Coin" or "USDC") */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Token version for EIP-712 domain */
|
|
43
|
+
version: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
23
46
|
/**
|
|
24
47
|
* USDC token configuration for a specific chain
|
|
48
|
+
* @deprecated Use TokenConfig instead. This is kept for backward compatibility.
|
|
25
49
|
*/
|
|
26
50
|
export interface USDCConfig {
|
|
27
51
|
/** Contract/mint address */
|
|
@@ -65,6 +89,12 @@ export interface ChainConfig {
|
|
|
65
89
|
nativeCurrency: NativeCurrency;
|
|
66
90
|
/** USDC token configuration */
|
|
67
91
|
usdc: USDCConfig;
|
|
92
|
+
/**
|
|
93
|
+
* Multi-token configurations (EVM chains only)
|
|
94
|
+
* Maps token type to its configuration for this chain.
|
|
95
|
+
* Not all tokens are available on all chains.
|
|
96
|
+
*/
|
|
97
|
+
tokens?: Partial<Record<TokenType, TokenConfig>>;
|
|
68
98
|
/** x402 facilitator configuration */
|
|
69
99
|
x402: {
|
|
70
100
|
facilitatorUrl: string;
|
|
@@ -117,11 +147,17 @@ export interface WalletAdapter {
|
|
|
117
147
|
/** Switch to a different chain (EVM only) */
|
|
118
148
|
switchChain?(chainName: string): Promise<void>;
|
|
119
149
|
|
|
120
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Sign a payment payload
|
|
152
|
+
* For EVM chains, supports multi-token via paymentInfo.tokenType
|
|
153
|
+
*/
|
|
121
154
|
signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;
|
|
122
155
|
|
|
123
|
-
/**
|
|
124
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Check token balance (defaults to USDC for backward compatibility)
|
|
158
|
+
* EVM providers may accept optional tokenType parameter
|
|
159
|
+
*/
|
|
160
|
+
getBalance(chainConfig: ChainConfig, tokenType?: TokenType): Promise<string>;
|
|
125
161
|
|
|
126
162
|
/** Get current address */
|
|
127
163
|
getAddress(): string | null;
|
|
@@ -170,6 +206,11 @@ export interface PaymentInfo {
|
|
|
170
206
|
amount: string;
|
|
171
207
|
/** Token symbol (usually "USDC") */
|
|
172
208
|
token?: string;
|
|
209
|
+
/**
|
|
210
|
+
* Token type for multi-token support
|
|
211
|
+
* Defaults to 'usdc' if not specified for backward compatibility
|
|
212
|
+
*/
|
|
213
|
+
tokenType?: TokenType;
|
|
173
214
|
/** Network hint from backend */
|
|
174
215
|
network?: string;
|
|
175
216
|
/** Supported chain IDs */
|