uvd-x402-sdk 2.0.3 → 2.1.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.
@@ -0,0 +1,556 @@
1
+ 'use strict';
2
+
3
+ // src/chains/index.ts
4
+ var DEFAULT_FACILITATOR_URL = "https://facilitator.ultravioletadao.xyz";
5
+ var SUPPORTED_CHAINS = {
6
+ // ============================================================================
7
+ // EVM CHAINS (10 networks)
8
+ // ============================================================================
9
+ base: {
10
+ chainId: 8453,
11
+ chainIdHex: "0x2105",
12
+ name: "base",
13
+ displayName: "Base",
14
+ networkType: "evm",
15
+ rpcUrl: "https://mainnet.base.org",
16
+ explorerUrl: "https://basescan.org",
17
+ nativeCurrency: {
18
+ name: "Ethereum",
19
+ symbol: "ETH",
20
+ decimals: 18
21
+ },
22
+ usdc: {
23
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
24
+ decimals: 6,
25
+ name: "USD Coin",
26
+ version: "2"
27
+ },
28
+ x402: {
29
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
30
+ enabled: true
31
+ }
32
+ },
33
+ avalanche: {
34
+ chainId: 43114,
35
+ chainIdHex: "0xa86a",
36
+ name: "avalanche",
37
+ displayName: "Avalanche C-Chain",
38
+ networkType: "evm",
39
+ rpcUrl: "https://avalanche-c-chain-rpc.publicnode.com",
40
+ explorerUrl: "https://snowtrace.io",
41
+ nativeCurrency: {
42
+ name: "Avalanche",
43
+ symbol: "AVAX",
44
+ decimals: 18
45
+ },
46
+ usdc: {
47
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
48
+ decimals: 6,
49
+ name: "USD Coin",
50
+ version: "2"
51
+ },
52
+ x402: {
53
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
54
+ enabled: true
55
+ }
56
+ },
57
+ ethereum: {
58
+ chainId: 1,
59
+ chainIdHex: "0x1",
60
+ name: "ethereum",
61
+ displayName: "Ethereum",
62
+ networkType: "evm",
63
+ rpcUrl: "https://eth.llamarpc.com",
64
+ explorerUrl: "https://etherscan.io",
65
+ nativeCurrency: {
66
+ name: "Ethereum",
67
+ symbol: "ETH",
68
+ decimals: 18
69
+ },
70
+ usdc: {
71
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
72
+ decimals: 6,
73
+ name: "USD Coin",
74
+ version: "2"
75
+ },
76
+ x402: {
77
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
78
+ enabled: true
79
+ }
80
+ },
81
+ polygon: {
82
+ chainId: 137,
83
+ chainIdHex: "0x89",
84
+ name: "polygon",
85
+ displayName: "Polygon",
86
+ networkType: "evm",
87
+ rpcUrl: "https://polygon-rpc.com",
88
+ explorerUrl: "https://polygonscan.com",
89
+ nativeCurrency: {
90
+ name: "Polygon",
91
+ symbol: "POL",
92
+ decimals: 18
93
+ },
94
+ usdc: {
95
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
96
+ decimals: 6,
97
+ name: "USD Coin",
98
+ version: "2"
99
+ },
100
+ x402: {
101
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
102
+ enabled: true
103
+ }
104
+ },
105
+ arbitrum: {
106
+ chainId: 42161,
107
+ chainIdHex: "0xa4b1",
108
+ name: "arbitrum",
109
+ displayName: "Arbitrum One",
110
+ networkType: "evm",
111
+ rpcUrl: "https://arb1.arbitrum.io/rpc",
112
+ explorerUrl: "https://arbiscan.io",
113
+ nativeCurrency: {
114
+ name: "Ethereum",
115
+ symbol: "ETH",
116
+ decimals: 18
117
+ },
118
+ usdc: {
119
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
120
+ decimals: 6,
121
+ name: "USD Coin",
122
+ version: "2"
123
+ },
124
+ x402: {
125
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
126
+ enabled: true
127
+ }
128
+ },
129
+ optimism: {
130
+ chainId: 10,
131
+ chainIdHex: "0xa",
132
+ name: "optimism",
133
+ displayName: "Optimism",
134
+ networkType: "evm",
135
+ rpcUrl: "https://mainnet.optimism.io",
136
+ explorerUrl: "https://optimistic.etherscan.io",
137
+ nativeCurrency: {
138
+ name: "Ethereum",
139
+ symbol: "ETH",
140
+ decimals: 18
141
+ },
142
+ usdc: {
143
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
144
+ decimals: 6,
145
+ name: "USD Coin",
146
+ version: "2"
147
+ },
148
+ x402: {
149
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
150
+ enabled: true
151
+ }
152
+ },
153
+ celo: {
154
+ chainId: 42220,
155
+ chainIdHex: "0xa4ec",
156
+ name: "celo",
157
+ displayName: "Celo",
158
+ networkType: "evm",
159
+ rpcUrl: "https://forno.celo.org",
160
+ explorerUrl: "https://celoscan.io",
161
+ nativeCurrency: {
162
+ name: "Celo",
163
+ symbol: "CELO",
164
+ decimals: 18
165
+ },
166
+ usdc: {
167
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
168
+ decimals: 6,
169
+ name: "USDC",
170
+ // Celo uses "USDC" not "USD Coin" for EIP-712
171
+ version: "2"
172
+ },
173
+ x402: {
174
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
175
+ enabled: true
176
+ }
177
+ },
178
+ hyperevm: {
179
+ chainId: 999,
180
+ chainIdHex: "0x3e7",
181
+ name: "hyperevm",
182
+ displayName: "HyperEVM",
183
+ networkType: "evm",
184
+ rpcUrl: "https://rpc.hyperliquid.xyz/evm",
185
+ explorerUrl: "https://hyperevmscan.io",
186
+ nativeCurrency: {
187
+ name: "Ethereum",
188
+ symbol: "ETH",
189
+ decimals: 18
190
+ },
191
+ usdc: {
192
+ address: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
193
+ decimals: 6,
194
+ name: "USDC",
195
+ // HyperEVM uses "USDC" not "USD Coin"
196
+ version: "2"
197
+ },
198
+ x402: {
199
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
200
+ enabled: true
201
+ }
202
+ },
203
+ unichain: {
204
+ chainId: 130,
205
+ chainIdHex: "0x82",
206
+ name: "unichain",
207
+ displayName: "Unichain",
208
+ networkType: "evm",
209
+ rpcUrl: "https://unichain-rpc.publicnode.com",
210
+ explorerUrl: "https://uniscan.xyz",
211
+ nativeCurrency: {
212
+ name: "Ethereum",
213
+ symbol: "ETH",
214
+ decimals: 18
215
+ },
216
+ usdc: {
217
+ address: "0x078d782b760474a361dda0af3839290b0ef57ad6",
218
+ decimals: 6,
219
+ name: "USDC",
220
+ // Unichain uses "USDC" not "USD Coin"
221
+ version: "2"
222
+ },
223
+ x402: {
224
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
225
+ enabled: true
226
+ }
227
+ },
228
+ monad: {
229
+ chainId: 143,
230
+ chainIdHex: "0x8f",
231
+ name: "monad",
232
+ displayName: "Monad",
233
+ networkType: "evm",
234
+ rpcUrl: "https://rpc.monad.xyz",
235
+ explorerUrl: "https://monad.socialscan.io",
236
+ nativeCurrency: {
237
+ name: "Monad",
238
+ symbol: "MON",
239
+ decimals: 18
240
+ },
241
+ usdc: {
242
+ address: "0x754704bc059f8c67012fed69bc8a327a5aafb603",
243
+ decimals: 6,
244
+ name: "USDC",
245
+ // Monad uses "USDC" not "USD Coin"
246
+ version: "2"
247
+ },
248
+ x402: {
249
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
250
+ enabled: true
251
+ }
252
+ },
253
+ // ============================================================================
254
+ // SVM CHAINS (2 networks) - Solana Virtual Machine
255
+ // ============================================================================
256
+ solana: {
257
+ chainId: 0,
258
+ // Non-EVM
259
+ chainIdHex: "0x0",
260
+ name: "solana",
261
+ displayName: "Solana",
262
+ networkType: "svm",
263
+ rpcUrl: "https://api.mainnet-beta.solana.com",
264
+ explorerUrl: "https://solscan.io",
265
+ nativeCurrency: {
266
+ name: "Solana",
267
+ symbol: "SOL",
268
+ decimals: 9
269
+ },
270
+ usdc: {
271
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
272
+ // USDC SPL token mint
273
+ decimals: 6,
274
+ name: "USD Coin",
275
+ version: "1"
276
+ },
277
+ x402: {
278
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
279
+ enabled: true
280
+ }
281
+ },
282
+ fogo: {
283
+ chainId: 0,
284
+ // Non-EVM (SVM)
285
+ chainIdHex: "0x0",
286
+ name: "fogo",
287
+ displayName: "Fogo",
288
+ networkType: "svm",
289
+ rpcUrl: "https://rpc.fogo.nightly.app/",
290
+ explorerUrl: "https://explorer.fogo.nightly.app",
291
+ nativeCurrency: {
292
+ name: "Fogo",
293
+ symbol: "FOGO",
294
+ decimals: 9
295
+ },
296
+ usdc: {
297
+ address: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
298
+ // Fogo USDC mint
299
+ decimals: 6,
300
+ name: "USDC",
301
+ version: "1"
302
+ },
303
+ x402: {
304
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
305
+ enabled: true
306
+ }
307
+ },
308
+ // ============================================================================
309
+ // STELLAR (1 network)
310
+ // ============================================================================
311
+ stellar: {
312
+ chainId: 0,
313
+ // Non-EVM
314
+ chainIdHex: "0x0",
315
+ name: "stellar",
316
+ displayName: "Stellar",
317
+ networkType: "stellar",
318
+ rpcUrl: "https://horizon.stellar.org",
319
+ explorerUrl: "https://stellar.expert/explorer/public",
320
+ nativeCurrency: {
321
+ name: "Lumens",
322
+ symbol: "XLM",
323
+ decimals: 7
324
+ // Stellar uses 7 decimals (stroops)
325
+ },
326
+ usdc: {
327
+ address: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
328
+ // Soroban Asset Contract
329
+ decimals: 7,
330
+ // Stellar USDC uses 7 decimals
331
+ name: "USDC",
332
+ version: "1"
333
+ },
334
+ x402: {
335
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
336
+ enabled: true
337
+ }
338
+ },
339
+ // ============================================================================
340
+ // NEAR (1 network) - Uses NEP-366 meta-transactions
341
+ // ============================================================================
342
+ near: {
343
+ chainId: 0,
344
+ // Non-EVM
345
+ chainIdHex: "0x0",
346
+ name: "near",
347
+ displayName: "NEAR Protocol",
348
+ networkType: "near",
349
+ rpcUrl: "https://rpc.mainnet.near.org",
350
+ explorerUrl: "https://nearblocks.io",
351
+ nativeCurrency: {
352
+ name: "NEAR",
353
+ symbol: "NEAR",
354
+ decimals: 24
355
+ // NEAR uses 24 decimals (yoctoNEAR)
356
+ },
357
+ usdc: {
358
+ address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
359
+ // Native Circle USDC
360
+ decimals: 6,
361
+ name: "USDC",
362
+ version: "1"
363
+ },
364
+ x402: {
365
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
366
+ enabled: true
367
+ // NEP-366 meta-transactions supported
368
+ }
369
+ }
370
+ };
371
+ function getChainByName(name) {
372
+ return SUPPORTED_CHAINS[name.toLowerCase()];
373
+ }
374
+
375
+ // src/types/index.ts
376
+ var CAIP2_IDENTIFIERS = {
377
+ // EVM chains
378
+ base: "eip155:8453",
379
+ ethereum: "eip155:1",
380
+ polygon: "eip155:137",
381
+ arbitrum: "eip155:42161",
382
+ optimism: "eip155:10",
383
+ avalanche: "eip155:43114",
384
+ celo: "eip155:42220",
385
+ hyperevm: "eip155:999",
386
+ unichain: "eip155:130",
387
+ monad: "eip155:143",
388
+ // SVM chains
389
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
390
+ fogo: "svm:fogo",
391
+ // Stellar
392
+ stellar: "stellar:pubnet",
393
+ // NEAR
394
+ near: "near:mainnet"
395
+ };
396
+ Object.fromEntries(
397
+ Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])
398
+ );
399
+ var X402Error = class _X402Error extends Error {
400
+ code;
401
+ details;
402
+ constructor(message, code, details) {
403
+ super(message);
404
+ this.name = "X402Error";
405
+ this.code = code;
406
+ this.details = details;
407
+ if (Error.captureStackTrace) {
408
+ Error.captureStackTrace(this, _X402Error);
409
+ }
410
+ }
411
+ };
412
+
413
+ // src/utils/x402.ts
414
+ function encodeX402Header(header) {
415
+ return btoa(JSON.stringify(header));
416
+ }
417
+ function createX402V1Header(network, payload) {
418
+ return {
419
+ x402Version: 1,
420
+ scheme: "exact",
421
+ network,
422
+ payload
423
+ };
424
+ }
425
+
426
+ // src/adapters/wagmi.ts
427
+ function generateNonce() {
428
+ const bytes = new Uint8Array(32);
429
+ if (typeof globalThis !== "undefined" && globalThis.crypto?.getRandomValues) {
430
+ globalThis.crypto.getRandomValues(bytes);
431
+ } else if (typeof window !== "undefined" && window.crypto?.getRandomValues) {
432
+ window.crypto.getRandomValues(bytes);
433
+ } else {
434
+ for (let i = 0; i < 32; i++) {
435
+ bytes[i] = Math.floor(Math.random() * 256);
436
+ }
437
+ }
438
+ return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
439
+ }
440
+ function parseUnits(amount, decimals) {
441
+ const [integer, fraction = ""] = amount.split(".");
442
+ const paddedFraction = fraction.padEnd(decimals, "0").slice(0, decimals);
443
+ return BigInt(integer + paddedFraction);
444
+ }
445
+ async function createPaymentFromWalletClient(walletClient, options) {
446
+ if (!walletClient) {
447
+ throw new X402Error("WalletClient is not available. Make sure wallet is connected.", "WALLET_NOT_CONNECTED");
448
+ }
449
+ const {
450
+ recipient,
451
+ amount,
452
+ chainName = "base",
453
+ validitySeconds = 300
454
+ } = options;
455
+ const chain = getChainByName(chainName);
456
+ if (!chain) {
457
+ throw new X402Error(`Unsupported chain: ${chainName}`, "CHAIN_NOT_SUPPORTED");
458
+ }
459
+ if (chain.networkType !== "evm") {
460
+ throw new X402Error(
461
+ `wagmi adapter only supports EVM chains. For ${chain.networkType}, use the appropriate provider.`,
462
+ "CHAIN_NOT_SUPPORTED"
463
+ );
464
+ }
465
+ const from = walletClient.account.address;
466
+ const to = recipient;
467
+ const nonce = generateNonce();
468
+ const validAfter = 0;
469
+ const validBefore = Math.floor(Date.now() / 1e3) + validitySeconds;
470
+ const value = parseUnits(amount, chain.usdc.decimals);
471
+ const domain = {
472
+ name: chain.usdc.name,
473
+ version: chain.usdc.version,
474
+ chainId: chain.chainId,
475
+ verifyingContract: chain.usdc.address
476
+ };
477
+ const types = {
478
+ TransferWithAuthorization: [
479
+ { name: "from", type: "address" },
480
+ { name: "to", type: "address" },
481
+ { name: "value", type: "uint256" },
482
+ { name: "validAfter", type: "uint256" },
483
+ { name: "validBefore", type: "uint256" },
484
+ { name: "nonce", type: "bytes32" }
485
+ ]
486
+ };
487
+ const message = {
488
+ from,
489
+ to,
490
+ value,
491
+ validAfter: BigInt(validAfter),
492
+ validBefore: BigInt(validBefore),
493
+ nonce
494
+ };
495
+ let signature;
496
+ try {
497
+ signature = await walletClient.signTypedData({
498
+ domain,
499
+ types,
500
+ primaryType: "TransferWithAuthorization",
501
+ message
502
+ });
503
+ } catch (error) {
504
+ if (error instanceof Error) {
505
+ if (error.message.includes("User rejected") || error.message.includes("denied")) {
506
+ throw new X402Error("Signature rejected by user", "SIGNATURE_REJECTED");
507
+ }
508
+ }
509
+ throw new X402Error(
510
+ `Failed to sign payment: ${error instanceof Error ? error.message : "Unknown error"}`,
511
+ "PAYMENT_FAILED",
512
+ error
513
+ );
514
+ }
515
+ const header = createX402V1Header(chainName, {
516
+ signature,
517
+ authorization: {
518
+ from,
519
+ to: recipient,
520
+ value: value.toString(),
521
+ validAfter: validAfter.toString(),
522
+ validBefore: validBefore.toString(),
523
+ nonce
524
+ }
525
+ });
526
+ return encodeX402Header(header);
527
+ }
528
+ async function createPaymentWithResult(walletClient, options) {
529
+ const paymentHeader = await createPaymentFromWalletClient(walletClient, options);
530
+ return {
531
+ success: true,
532
+ paymentHeader,
533
+ network: options.chainName || "base",
534
+ payer: walletClient?.account.address
535
+ };
536
+ }
537
+ function useX402Wagmi(walletClient) {
538
+ const isReady = !!walletClient;
539
+ const createPayment = async (options) => {
540
+ return createPaymentFromWalletClient(walletClient, options);
541
+ };
542
+ const createPaymentFull = async (options) => {
543
+ return createPaymentWithResult(walletClient, options);
544
+ };
545
+ return {
546
+ isReady,
547
+ createPayment,
548
+ createPaymentFull
549
+ };
550
+ }
551
+
552
+ exports.createPaymentFromWalletClient = createPaymentFromWalletClient;
553
+ exports.createPaymentWithResult = createPaymentWithResult;
554
+ exports.useX402Wagmi = useX402Wagmi;
555
+ //# sourceMappingURL=index.js.map
556
+ //# sourceMappingURL=index.js.map