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.
- package/LICENSE +21 -0
- package/README.md +782 -0
- package/dist/index-BrBqP1I8.d.ts +199 -0
- package/dist/index-D6Sr4ARD.d.mts +429 -0
- package/dist/index-D6Sr4ARD.d.ts +429 -0
- package/dist/index-DJ4Cvrev.d.mts +199 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1178 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1146 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers/evm/index.d.mts +84 -0
- package/dist/providers/evm/index.d.ts +84 -0
- package/dist/providers/evm/index.js +740 -0
- package/dist/providers/evm/index.js.map +1 -0
- package/dist/providers/evm/index.mjs +735 -0
- package/dist/providers/evm/index.mjs.map +1 -0
- package/dist/providers/near/index.d.mts +99 -0
- package/dist/providers/near/index.d.ts +99 -0
- package/dist/providers/near/index.js +483 -0
- package/dist/providers/near/index.js.map +1 -0
- package/dist/providers/near/index.mjs +478 -0
- package/dist/providers/near/index.mjs.map +1 -0
- package/dist/providers/solana/index.d.mts +115 -0
- package/dist/providers/solana/index.d.ts +115 -0
- package/dist/providers/solana/index.js +771 -0
- package/dist/providers/solana/index.js.map +1 -0
- package/dist/providers/solana/index.mjs +765 -0
- package/dist/providers/solana/index.mjs.map +1 -0
- package/dist/providers/stellar/index.d.mts +67 -0
- package/dist/providers/stellar/index.d.ts +67 -0
- package/dist/providers/stellar/index.js +306 -0
- package/dist/providers/stellar/index.js.map +1 -0
- package/dist/providers/stellar/index.mjs +301 -0
- package/dist/providers/stellar/index.mjs.map +1 -0
- package/dist/react/index.d.mts +73 -0
- package/dist/react/index.d.ts +73 -0
- package/dist/react/index.js +1218 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +1211 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/utils/index.d.mts +103 -0
- package/dist/utils/index.d.ts +103 -0
- package/dist/utils/index.js +575 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +562 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +149 -0
- package/src/chains/index.ts +539 -0
- package/src/client/X402Client.ts +663 -0
- package/src/client/index.ts +1 -0
- package/src/index.ts +166 -0
- package/src/providers/evm/index.ts +394 -0
- package/src/providers/near/index.ts +664 -0
- package/src/providers/solana/index.ts +489 -0
- package/src/providers/stellar/index.ts +376 -0
- package/src/react/index.tsx +417 -0
- package/src/types/index.ts +561 -0
- package/src/utils/index.ts +20 -0
- 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
|