uvd-x402-sdk 2.5.0 → 2.10.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 (75) hide show
  1. package/README.md +380 -3
  2. package/dist/adapters/index.d.mts +1 -1
  3. package/dist/adapters/index.d.ts +1 -1
  4. package/dist/adapters/index.js +82 -1
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/adapters/index.mjs +82 -1
  7. package/dist/adapters/index.mjs.map +1 -1
  8. package/dist/backend/index.d.mts +1036 -0
  9. package/dist/backend/index.d.ts +1036 -0
  10. package/dist/backend/index.js +1722 -0
  11. package/dist/backend/index.js.map +1 -0
  12. package/dist/backend/index.mjs +1704 -0
  13. package/dist/backend/index.mjs.map +1 -0
  14. package/dist/{index-BrFeSWKm.d.mts → index-C60c_e5z.d.mts} +13 -4
  15. package/dist/{index-DR2vXt-c.d.mts → index-D-dO_FoP.d.mts} +70 -4
  16. package/dist/{index-DR2vXt-c.d.ts → index-D-dO_FoP.d.ts} +70 -4
  17. package/dist/{index-BYX9BU79.d.ts → index-VIOUicmO.d.ts} +13 -4
  18. package/dist/index.d.mts +3 -3
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +115 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +110 -2
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/providers/algorand/index.d.mts +86 -0
  25. package/dist/providers/algorand/index.d.ts +86 -0
  26. package/dist/providers/algorand/index.js +903 -0
  27. package/dist/providers/algorand/index.js.map +1 -0
  28. package/dist/providers/algorand/index.mjs +898 -0
  29. package/dist/providers/algorand/index.mjs.map +1 -0
  30. package/dist/providers/evm/index.d.mts +1 -1
  31. package/dist/providers/evm/index.d.ts +1 -1
  32. package/dist/providers/evm/index.js +78 -1
  33. package/dist/providers/evm/index.js.map +1 -1
  34. package/dist/providers/evm/index.mjs +78 -1
  35. package/dist/providers/evm/index.mjs.map +1 -1
  36. package/dist/providers/near/index.d.mts +1 -1
  37. package/dist/providers/near/index.d.ts +1 -1
  38. package/dist/providers/near/index.js +78 -1
  39. package/dist/providers/near/index.js.map +1 -1
  40. package/dist/providers/near/index.mjs +78 -1
  41. package/dist/providers/near/index.mjs.map +1 -1
  42. package/dist/providers/solana/index.d.mts +1 -1
  43. package/dist/providers/solana/index.d.ts +1 -1
  44. package/dist/providers/solana/index.js +78 -1
  45. package/dist/providers/solana/index.js.map +1 -1
  46. package/dist/providers/solana/index.mjs +78 -1
  47. package/dist/providers/solana/index.mjs.map +1 -1
  48. package/dist/providers/stellar/index.d.mts +1 -1
  49. package/dist/providers/stellar/index.d.ts +1 -1
  50. package/dist/providers/stellar/index.js +78 -1
  51. package/dist/providers/stellar/index.js.map +1 -1
  52. package/dist/providers/stellar/index.mjs +78 -1
  53. package/dist/providers/stellar/index.mjs.map +1 -1
  54. package/dist/react/index.d.mts +3 -3
  55. package/dist/react/index.d.ts +3 -3
  56. package/dist/react/index.js +82 -1
  57. package/dist/react/index.js.map +1 -1
  58. package/dist/react/index.mjs +82 -1
  59. package/dist/react/index.mjs.map +1 -1
  60. package/dist/utils/index.d.mts +57 -5
  61. package/dist/utils/index.d.ts +57 -5
  62. package/dist/utils/index.js +96 -1
  63. package/dist/utils/index.js.map +1 -1
  64. package/dist/utils/index.mjs +93 -2
  65. package/dist/utils/index.mjs.map +1 -1
  66. package/package.json +24 -3
  67. package/src/adapters/wagmi.ts +4 -0
  68. package/src/backend/index.ts +2131 -0
  69. package/src/chains/index.ts +94 -2
  70. package/src/client/X402Client.ts +4 -0
  71. package/src/index.ts +26 -1
  72. package/src/providers/algorand/index.ts +356 -0
  73. package/src/types/index.ts +78 -3
  74. package/src/utils/index.ts +4 -0
  75. package/src/utils/validation.ts +76 -3
@@ -0,0 +1,1704 @@
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
+ // SVM chains
15
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
16
+ fogo: "svm:fogo",
17
+ // Stellar
18
+ stellar: "stellar:pubnet",
19
+ // NEAR
20
+ near: "near:mainnet",
21
+ // Algorand
22
+ algorand: "algorand:mainnet",
23
+ "algorand-testnet": "algorand:testnet"
24
+ };
25
+ Object.fromEntries(
26
+ Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])
27
+ );
28
+
29
+ // src/chains/index.ts
30
+ var DEFAULT_FACILITATOR_URL = "https://facilitator.ultravioletadao.xyz";
31
+ var SUPPORTED_CHAINS = {
32
+ // ============================================================================
33
+ // EVM CHAINS (10 networks)
34
+ // ============================================================================
35
+ base: {
36
+ chainId: 8453,
37
+ chainIdHex: "0x2105",
38
+ name: "base",
39
+ displayName: "Base",
40
+ networkType: "evm",
41
+ rpcUrl: "https://mainnet.base.org",
42
+ explorerUrl: "https://basescan.org",
43
+ nativeCurrency: {
44
+ name: "Ethereum",
45
+ symbol: "ETH",
46
+ decimals: 18
47
+ },
48
+ usdc: {
49
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
50
+ decimals: 6,
51
+ name: "USD Coin",
52
+ version: "2"
53
+ },
54
+ tokens: {
55
+ usdc: {
56
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
57
+ decimals: 6,
58
+ name: "USD Coin",
59
+ version: "2"
60
+ },
61
+ eurc: {
62
+ address: "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42",
63
+ decimals: 6,
64
+ name: "EURC",
65
+ version: "2"
66
+ }
67
+ },
68
+ x402: {
69
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
70
+ enabled: true
71
+ }
72
+ },
73
+ avalanche: {
74
+ chainId: 43114,
75
+ chainIdHex: "0xa86a",
76
+ name: "avalanche",
77
+ displayName: "Avalanche C-Chain",
78
+ networkType: "evm",
79
+ rpcUrl: "https://avalanche-c-chain-rpc.publicnode.com",
80
+ explorerUrl: "https://snowtrace.io",
81
+ nativeCurrency: {
82
+ name: "Avalanche",
83
+ symbol: "AVAX",
84
+ decimals: 18
85
+ },
86
+ usdc: {
87
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
88
+ decimals: 6,
89
+ name: "USD Coin",
90
+ version: "2"
91
+ },
92
+ tokens: {
93
+ usdc: {
94
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
95
+ decimals: 6,
96
+ name: "USD Coin",
97
+ version: "2"
98
+ },
99
+ eurc: {
100
+ address: "0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD",
101
+ decimals: 6,
102
+ name: "EURC",
103
+ version: "2"
104
+ },
105
+ ausd: {
106
+ address: "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a",
107
+ decimals: 6,
108
+ name: "Agora Dollar",
109
+ version: "1"
110
+ }
111
+ },
112
+ x402: {
113
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
114
+ enabled: true
115
+ }
116
+ },
117
+ ethereum: {
118
+ chainId: 1,
119
+ chainIdHex: "0x1",
120
+ name: "ethereum",
121
+ displayName: "Ethereum",
122
+ networkType: "evm",
123
+ rpcUrl: "https://eth.llamarpc.com",
124
+ explorerUrl: "https://etherscan.io",
125
+ nativeCurrency: {
126
+ name: "Ethereum",
127
+ symbol: "ETH",
128
+ decimals: 18
129
+ },
130
+ usdc: {
131
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
132
+ decimals: 6,
133
+ name: "USD Coin",
134
+ version: "2"
135
+ },
136
+ tokens: {
137
+ usdc: {
138
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
139
+ decimals: 6,
140
+ name: "USD Coin",
141
+ version: "2"
142
+ },
143
+ eurc: {
144
+ address: "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
145
+ decimals: 6,
146
+ name: "Euro Coin",
147
+ version: "2"
148
+ },
149
+ ausd: {
150
+ address: "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a",
151
+ decimals: 6,
152
+ name: "Agora Dollar",
153
+ version: "1"
154
+ },
155
+ pyusd: {
156
+ address: "0x6c3ea9036406852006290770BEdFcAbA0e23A0e8",
157
+ decimals: 6,
158
+ name: "PayPal USD",
159
+ version: "1"
160
+ }
161
+ },
162
+ x402: {
163
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
164
+ enabled: true
165
+ }
166
+ },
167
+ polygon: {
168
+ chainId: 137,
169
+ chainIdHex: "0x89",
170
+ name: "polygon",
171
+ displayName: "Polygon",
172
+ networkType: "evm",
173
+ rpcUrl: "https://polygon-rpc.com",
174
+ explorerUrl: "https://polygonscan.com",
175
+ nativeCurrency: {
176
+ name: "Polygon",
177
+ symbol: "POL",
178
+ decimals: 18
179
+ },
180
+ usdc: {
181
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
182
+ decimals: 6,
183
+ name: "USD Coin",
184
+ version: "2"
185
+ },
186
+ tokens: {
187
+ usdc: {
188
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
189
+ decimals: 6,
190
+ name: "USD Coin",
191
+ version: "2"
192
+ },
193
+ ausd: {
194
+ address: "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a",
195
+ decimals: 6,
196
+ name: "Agora Dollar",
197
+ version: "1"
198
+ }
199
+ },
200
+ x402: {
201
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
202
+ enabled: true
203
+ }
204
+ },
205
+ arbitrum: {
206
+ chainId: 42161,
207
+ chainIdHex: "0xa4b1",
208
+ name: "arbitrum",
209
+ displayName: "Arbitrum One",
210
+ networkType: "evm",
211
+ rpcUrl: "https://arb1.arbitrum.io/rpc",
212
+ explorerUrl: "https://arbiscan.io",
213
+ nativeCurrency: {
214
+ name: "Ethereum",
215
+ symbol: "ETH",
216
+ decimals: 18
217
+ },
218
+ usdc: {
219
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
220
+ decimals: 6,
221
+ name: "USD Coin",
222
+ version: "2"
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 Dollar",
235
+ version: "1"
236
+ },
237
+ usdt: {
238
+ address: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
239
+ decimals: 6,
240
+ name: "USD\u20AE0",
241
+ version: "1"
242
+ }
243
+ },
244
+ x402: {
245
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
246
+ enabled: true
247
+ }
248
+ },
249
+ optimism: {
250
+ chainId: 10,
251
+ chainIdHex: "0xa",
252
+ name: "optimism",
253
+ displayName: "Optimism",
254
+ networkType: "evm",
255
+ rpcUrl: "https://mainnet.optimism.io",
256
+ explorerUrl: "https://optimistic.etherscan.io",
257
+ nativeCurrency: {
258
+ name: "Ethereum",
259
+ symbol: "ETH",
260
+ decimals: 18
261
+ },
262
+ usdc: {
263
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
264
+ decimals: 6,
265
+ name: "USD Coin",
266
+ version: "2"
267
+ },
268
+ tokens: {
269
+ usdc: {
270
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
271
+ decimals: 6,
272
+ name: "USD Coin",
273
+ version: "2"
274
+ },
275
+ usdt: {
276
+ address: "0x01bff41798a0bcf287b996046ca68b395dbc1071",
277
+ decimals: 6,
278
+ name: "USD\u20AE0",
279
+ version: "1"
280
+ }
281
+ },
282
+ x402: {
283
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
284
+ enabled: true
285
+ }
286
+ },
287
+ celo: {
288
+ chainId: 42220,
289
+ chainIdHex: "0xa4ec",
290
+ name: "celo",
291
+ displayName: "Celo",
292
+ networkType: "evm",
293
+ rpcUrl: "https://forno.celo.org",
294
+ explorerUrl: "https://celoscan.io",
295
+ nativeCurrency: {
296
+ name: "Celo",
297
+ symbol: "CELO",
298
+ decimals: 18
299
+ },
300
+ usdc: {
301
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
302
+ decimals: 6,
303
+ name: "USDC",
304
+ // Celo uses "USDC" not "USD Coin" for EIP-712
305
+ version: "2"
306
+ },
307
+ tokens: {
308
+ usdc: {
309
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
310
+ decimals: 6,
311
+ name: "USDC",
312
+ // Celo uses "USDC" not "USD Coin" for EIP-712
313
+ version: "2"
314
+ },
315
+ usdt: {
316
+ address: "0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e",
317
+ decimals: 6,
318
+ name: "Tether USD",
319
+ // Celo USDT uses "Tether USD" for EIP-712
320
+ version: "1"
321
+ }
322
+ },
323
+ x402: {
324
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
325
+ enabled: true
326
+ }
327
+ },
328
+ hyperevm: {
329
+ chainId: 999,
330
+ chainIdHex: "0x3e7",
331
+ name: "hyperevm",
332
+ displayName: "HyperEVM",
333
+ networkType: "evm",
334
+ rpcUrl: "https://rpc.hyperliquid.xyz/evm",
335
+ explorerUrl: "https://hyperevmscan.io",
336
+ nativeCurrency: {
337
+ name: "Ethereum",
338
+ symbol: "ETH",
339
+ decimals: 18
340
+ },
341
+ usdc: {
342
+ address: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
343
+ decimals: 6,
344
+ name: "USDC",
345
+ // HyperEVM uses "USDC" not "USD Coin"
346
+ version: "2"
347
+ },
348
+ tokens: {
349
+ usdc: {
350
+ address: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
351
+ decimals: 6,
352
+ name: "USDC",
353
+ // HyperEVM uses "USDC" not "USD Coin"
354
+ version: "2"
355
+ }
356
+ },
357
+ x402: {
358
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
359
+ enabled: true
360
+ }
361
+ },
362
+ unichain: {
363
+ chainId: 130,
364
+ chainIdHex: "0x82",
365
+ name: "unichain",
366
+ displayName: "Unichain",
367
+ networkType: "evm",
368
+ rpcUrl: "https://unichain-rpc.publicnode.com",
369
+ explorerUrl: "https://uniscan.xyz",
370
+ nativeCurrency: {
371
+ name: "Ethereum",
372
+ symbol: "ETH",
373
+ decimals: 18
374
+ },
375
+ usdc: {
376
+ address: "0x078d782b760474a361dda0af3839290b0ef57ad6",
377
+ decimals: 6,
378
+ name: "USDC",
379
+ // Unichain uses "USDC" not "USD Coin"
380
+ version: "2"
381
+ },
382
+ tokens: {
383
+ usdc: {
384
+ address: "0x078d782b760474a361dda0af3839290b0ef57ad6",
385
+ decimals: 6,
386
+ name: "USDC",
387
+ // Unichain uses "USDC" not "USD Coin"
388
+ version: "2"
389
+ }
390
+ },
391
+ x402: {
392
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
393
+ enabled: true
394
+ }
395
+ },
396
+ monad: {
397
+ chainId: 143,
398
+ chainIdHex: "0x8f",
399
+ name: "monad",
400
+ displayName: "Monad",
401
+ networkType: "evm",
402
+ rpcUrl: "https://rpc.monad.xyz",
403
+ explorerUrl: "https://monad.socialscan.io",
404
+ nativeCurrency: {
405
+ name: "Monad",
406
+ symbol: "MON",
407
+ decimals: 18
408
+ },
409
+ usdc: {
410
+ address: "0x754704bc059f8c67012fed69bc8a327a5aafb603",
411
+ decimals: 6,
412
+ name: "USDC",
413
+ // Monad uses "USDC" not "USD Coin"
414
+ version: "2"
415
+ },
416
+ tokens: {
417
+ usdc: {
418
+ address: "0x754704bc059f8c67012fed69bc8a327a5aafb603",
419
+ decimals: 6,
420
+ name: "USDC",
421
+ // Monad uses "USDC" not "USD Coin"
422
+ version: "2"
423
+ },
424
+ ausd: {
425
+ address: "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a",
426
+ decimals: 6,
427
+ name: "Agora Dollar",
428
+ version: "1"
429
+ }
430
+ },
431
+ x402: {
432
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
433
+ enabled: true
434
+ }
435
+ },
436
+ // ============================================================================
437
+ // SVM CHAINS (2 networks) - Solana Virtual Machine
438
+ // ============================================================================
439
+ solana: {
440
+ chainId: 0,
441
+ // Non-EVM
442
+ chainIdHex: "0x0",
443
+ name: "solana",
444
+ displayName: "Solana",
445
+ networkType: "svm",
446
+ rpcUrl: "https://api.mainnet-beta.solana.com",
447
+ explorerUrl: "https://solscan.io",
448
+ nativeCurrency: {
449
+ name: "Solana",
450
+ symbol: "SOL",
451
+ decimals: 9
452
+ },
453
+ usdc: {
454
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
455
+ // USDC SPL token mint
456
+ decimals: 6,
457
+ name: "USD Coin",
458
+ version: "1"
459
+ },
460
+ x402: {
461
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
462
+ enabled: true
463
+ }
464
+ },
465
+ fogo: {
466
+ chainId: 0,
467
+ // Non-EVM (SVM)
468
+ chainIdHex: "0x0",
469
+ name: "fogo",
470
+ displayName: "Fogo",
471
+ networkType: "svm",
472
+ rpcUrl: "https://rpc.fogo.nightly.app/",
473
+ explorerUrl: "https://explorer.fogo.nightly.app",
474
+ nativeCurrency: {
475
+ name: "Fogo",
476
+ symbol: "FOGO",
477
+ decimals: 9
478
+ },
479
+ usdc: {
480
+ address: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
481
+ // Fogo USDC mint
482
+ decimals: 6,
483
+ name: "USDC",
484
+ version: "1"
485
+ },
486
+ x402: {
487
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
488
+ enabled: true
489
+ }
490
+ },
491
+ // ============================================================================
492
+ // STELLAR (1 network)
493
+ // ============================================================================
494
+ stellar: {
495
+ chainId: 0,
496
+ // Non-EVM
497
+ chainIdHex: "0x0",
498
+ name: "stellar",
499
+ displayName: "Stellar",
500
+ networkType: "stellar",
501
+ rpcUrl: "https://horizon.stellar.org",
502
+ explorerUrl: "https://stellar.expert/explorer/public",
503
+ nativeCurrency: {
504
+ name: "Lumens",
505
+ symbol: "XLM",
506
+ decimals: 7
507
+ // Stellar uses 7 decimals (stroops)
508
+ },
509
+ usdc: {
510
+ address: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
511
+ // Soroban Asset Contract
512
+ decimals: 7,
513
+ // Stellar USDC uses 7 decimals
514
+ name: "USDC",
515
+ version: "1"
516
+ },
517
+ x402: {
518
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
519
+ enabled: true
520
+ }
521
+ },
522
+ // ============================================================================
523
+ // NEAR (1 network) - Uses NEP-366 meta-transactions
524
+ // ============================================================================
525
+ near: {
526
+ chainId: 0,
527
+ // Non-EVM
528
+ chainIdHex: "0x0",
529
+ name: "near",
530
+ displayName: "NEAR Protocol",
531
+ networkType: "near",
532
+ rpcUrl: "https://rpc.mainnet.near.org",
533
+ explorerUrl: "https://nearblocks.io",
534
+ nativeCurrency: {
535
+ name: "NEAR",
536
+ symbol: "NEAR",
537
+ decimals: 24
538
+ // NEAR uses 24 decimals (yoctoNEAR)
539
+ },
540
+ usdc: {
541
+ address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
542
+ // Native Circle USDC
543
+ decimals: 6,
544
+ name: "USDC",
545
+ version: "1"
546
+ },
547
+ x402: {
548
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
549
+ enabled: true
550
+ // NEP-366 meta-transactions supported
551
+ }
552
+ },
553
+ // ============================================================================
554
+ // ALGORAND (2 networks) - Uses ASA transfers with atomic transaction groups
555
+ // ============================================================================
556
+ algorand: {
557
+ chainId: 0,
558
+ // Non-EVM (Algorand uses genesis hash for network identification)
559
+ chainIdHex: "0x0",
560
+ name: "algorand",
561
+ displayName: "Algorand",
562
+ networkType: "algorand",
563
+ rpcUrl: "https://mainnet-api.algonode.cloud",
564
+ explorerUrl: "https://allo.info",
565
+ nativeCurrency: {
566
+ name: "Algo",
567
+ symbol: "ALGO",
568
+ decimals: 6
569
+ // Algorand uses 6 decimals (microAlgos)
570
+ },
571
+ usdc: {
572
+ address: "31566704",
573
+ // USDC ASA ID on Algorand mainnet
574
+ decimals: 6,
575
+ name: "USDC",
576
+ version: "1"
577
+ },
578
+ tokens: {
579
+ usdc: {
580
+ address: "31566704",
581
+ // USDC ASA ID on Algorand mainnet
582
+ decimals: 6,
583
+ name: "USDC",
584
+ version: "1"
585
+ }
586
+ },
587
+ x402: {
588
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
589
+ enabled: true
590
+ }
591
+ },
592
+ "algorand-testnet": {
593
+ chainId: 0,
594
+ // Non-EVM
595
+ chainIdHex: "0x0",
596
+ name: "algorand-testnet",
597
+ displayName: "Algorand Testnet",
598
+ networkType: "algorand",
599
+ rpcUrl: "https://testnet-api.algonode.cloud",
600
+ explorerUrl: "https://testnet.allo.info",
601
+ nativeCurrency: {
602
+ name: "Algo",
603
+ symbol: "ALGO",
604
+ decimals: 6
605
+ },
606
+ usdc: {
607
+ address: "10458941",
608
+ // USDC ASA ID on Algorand testnet
609
+ decimals: 6,
610
+ name: "USDC",
611
+ version: "1"
612
+ },
613
+ tokens: {
614
+ usdc: {
615
+ address: "10458941",
616
+ // USDC ASA ID on Algorand testnet
617
+ decimals: 6,
618
+ name: "USDC",
619
+ version: "1"
620
+ }
621
+ },
622
+ x402: {
623
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
624
+ enabled: true
625
+ }
626
+ }
627
+ };
628
+ function getChainByName(name) {
629
+ return SUPPORTED_CHAINS[name.toLowerCase()];
630
+ }
631
+
632
+ // src/utils/x402.ts
633
+ function chainToCAIP2(chainName) {
634
+ const caip2 = CAIP2_IDENTIFIERS[chainName.toLowerCase()];
635
+ if (caip2) {
636
+ return caip2;
637
+ }
638
+ const chain = getChainByName(chainName);
639
+ if (chain) {
640
+ if (chain.networkType === "evm") {
641
+ return `eip155:${chain.chainId}`;
642
+ }
643
+ return `${chain.networkType}:${chainName}`;
644
+ }
645
+ return chainName;
646
+ }
647
+ function decodeX402Header(encoded) {
648
+ const json = atob(encoded);
649
+ return JSON.parse(json);
650
+ }
651
+
652
+ // src/backend/index.ts
653
+ function parsePaymentHeader(headerValue) {
654
+ if (!headerValue) {
655
+ return null;
656
+ }
657
+ try {
658
+ return decodeX402Header(headerValue);
659
+ } catch {
660
+ return null;
661
+ }
662
+ }
663
+ function extractPaymentFromHeaders(headers) {
664
+ const normalizedHeaders = {};
665
+ for (const [key, value] of Object.entries(headers)) {
666
+ if (typeof value === "string") {
667
+ normalizedHeaders[key.toLowerCase()] = value;
668
+ } else if (Array.isArray(value) && value.length > 0) {
669
+ normalizedHeaders[key.toLowerCase()] = value[0];
670
+ }
671
+ }
672
+ const headerValue = normalizedHeaders["x-payment"] || normalizedHeaders["payment-signature"];
673
+ return parsePaymentHeader(headerValue);
674
+ }
675
+ function buildPaymentRequirements(options) {
676
+ const {
677
+ amount,
678
+ recipient,
679
+ resource,
680
+ chainName = "base",
681
+ description = "Payment for resource access",
682
+ mimeType = "application/json",
683
+ timeoutSeconds = 300,
684
+ x402Version = 1
685
+ } = options;
686
+ const chain = getChainByName(chainName);
687
+ if (!chain) {
688
+ throw new Error(`Unsupported chain: ${chainName}`);
689
+ }
690
+ const atomicAmount = Math.floor(
691
+ parseFloat(amount) * Math.pow(10, chain.usdc.decimals)
692
+ ).toString();
693
+ const network = x402Version === 2 ? chainToCAIP2(chainName) : chainName;
694
+ return {
695
+ scheme: "exact",
696
+ network,
697
+ maxAmountRequired: atomicAmount,
698
+ resource,
699
+ description,
700
+ mimeType,
701
+ payTo: recipient,
702
+ maxTimeoutSeconds: timeoutSeconds,
703
+ asset: chain.usdc.address
704
+ };
705
+ }
706
+ function buildVerifyRequest(paymentHeader, requirements) {
707
+ return {
708
+ x402Version: paymentHeader.x402Version,
709
+ paymentPayload: paymentHeader,
710
+ paymentRequirements: requirements
711
+ };
712
+ }
713
+ function buildSettleRequest(paymentHeader, requirements) {
714
+ return {
715
+ x402Version: paymentHeader.x402Version,
716
+ paymentPayload: paymentHeader,
717
+ paymentRequirements: requirements
718
+ };
719
+ }
720
+ var X402_CORS_HEADERS = {
721
+ "Access-Control-Allow-Headers": "Content-Type, X-PAYMENT, PAYMENT-SIGNATURE, Authorization",
722
+ "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE, PAYMENT-RESPONSE, PAYMENT-REQUIRED",
723
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS"
724
+ };
725
+ var X402_HEADER_NAMES = [
726
+ "X-PAYMENT",
727
+ "PAYMENT-SIGNATURE",
728
+ "X-PAYMENT-RESPONSE",
729
+ "PAYMENT-RESPONSE",
730
+ "PAYMENT-REQUIRED"
731
+ ];
732
+ function getCorsHeaders(origin = "*") {
733
+ return {
734
+ "Access-Control-Allow-Origin": origin,
735
+ ...X402_CORS_HEADERS
736
+ };
737
+ }
738
+ var FacilitatorClient = class {
739
+ baseUrl;
740
+ timeout;
741
+ constructor(options = {}) {
742
+ this.baseUrl = options.baseUrl || "https://facilitator.ultravioletadao.xyz";
743
+ this.timeout = options.timeout || 3e4;
744
+ }
745
+ /**
746
+ * Verify a payment with the facilitator
747
+ *
748
+ * Call this before providing the paid resource to validate the payment.
749
+ *
750
+ * @param paymentHeader - Parsed x402 payment header
751
+ * @param requirements - Payment requirements
752
+ * @returns Verification result
753
+ */
754
+ async verify(paymentHeader, requirements) {
755
+ const body = buildVerifyRequest(paymentHeader, requirements);
756
+ const controller = new AbortController();
757
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
758
+ try {
759
+ const response = await fetch(`${this.baseUrl}/verify`, {
760
+ method: "POST",
761
+ headers: { "Content-Type": "application/json" },
762
+ body: JSON.stringify(body),
763
+ signal: controller.signal
764
+ });
765
+ clearTimeout(timeoutId);
766
+ if (!response.ok) {
767
+ const errorText = await response.text();
768
+ return {
769
+ isValid: false,
770
+ invalidReason: `Facilitator error: ${response.status} - ${errorText}`
771
+ };
772
+ }
773
+ return await response.json();
774
+ } catch (error) {
775
+ clearTimeout(timeoutId);
776
+ return {
777
+ isValid: false,
778
+ invalidReason: error instanceof Error ? error.message : "Unknown error"
779
+ };
780
+ }
781
+ }
782
+ /**
783
+ * Settle a payment with the facilitator
784
+ *
785
+ * Call this after providing the paid resource to execute the on-chain transfer.
786
+ *
787
+ * @param paymentHeader - Parsed x402 payment header
788
+ * @param requirements - Payment requirements
789
+ * @returns Settlement result with transaction hash
790
+ */
791
+ async settle(paymentHeader, requirements) {
792
+ const body = buildSettleRequest(paymentHeader, requirements);
793
+ const controller = new AbortController();
794
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
795
+ try {
796
+ const response = await fetch(`${this.baseUrl}/settle`, {
797
+ method: "POST",
798
+ headers: { "Content-Type": "application/json" },
799
+ body: JSON.stringify(body),
800
+ signal: controller.signal
801
+ });
802
+ clearTimeout(timeoutId);
803
+ if (!response.ok) {
804
+ const errorText = await response.text();
805
+ return {
806
+ success: false,
807
+ error: `Facilitator error: ${response.status} - ${errorText}`
808
+ };
809
+ }
810
+ const result = await response.json();
811
+ return {
812
+ success: true,
813
+ transactionHash: result.transactionHash || result.transaction_hash,
814
+ network: result.network
815
+ };
816
+ } catch (error) {
817
+ clearTimeout(timeoutId);
818
+ return {
819
+ success: false,
820
+ error: error instanceof Error ? error.message : "Unknown error"
821
+ };
822
+ }
823
+ }
824
+ /**
825
+ * Verify and settle atomically
826
+ *
827
+ * Convenience method that verifies first, then settles if valid.
828
+ * Use this for simple payment flows where you don't need custom logic between verify and settle.
829
+ *
830
+ * @param paymentHeader - Parsed x402 payment header
831
+ * @param requirements - Payment requirements
832
+ * @returns Combined result with verify and settle status
833
+ */
834
+ async verifyAndSettle(paymentHeader, requirements) {
835
+ const verifyResult = await this.verify(paymentHeader, requirements);
836
+ if (!verifyResult.isValid) {
837
+ return {
838
+ verified: false,
839
+ settled: false,
840
+ error: verifyResult.invalidReason
841
+ };
842
+ }
843
+ const settleResult = await this.settle(paymentHeader, requirements);
844
+ return {
845
+ verified: true,
846
+ settled: settleResult.success,
847
+ transactionHash: settleResult.transactionHash,
848
+ error: settleResult.error
849
+ };
850
+ }
851
+ /**
852
+ * Check if the facilitator is healthy
853
+ *
854
+ * @returns True if the facilitator is responding
855
+ */
856
+ async healthCheck() {
857
+ try {
858
+ const response = await fetch(`${this.baseUrl}/health`, {
859
+ method: "GET"
860
+ });
861
+ return response.ok;
862
+ } catch {
863
+ return false;
864
+ }
865
+ }
866
+ };
867
+ function create402Response(requirements, options = {}) {
868
+ const reqs = buildPaymentRequirements(requirements);
869
+ const body = {
870
+ x402Version: requirements.x402Version || 1,
871
+ ...reqs
872
+ };
873
+ if (options.accepts) {
874
+ body.accepts = options.accepts;
875
+ }
876
+ return {
877
+ status: 402,
878
+ headers: {
879
+ "Content-Type": "application/json",
880
+ ...X402_CORS_HEADERS
881
+ },
882
+ body
883
+ };
884
+ }
885
+ function createPaymentMiddleware(getRequirements, options = {}) {
886
+ const client = new FacilitatorClient(options);
887
+ return async (req, res, next) => {
888
+ const payment = extractPaymentFromHeaders(req.headers);
889
+ if (!payment) {
890
+ const reqOptions2 = getRequirements(req);
891
+ const { status, headers, body } = create402Response(reqOptions2);
892
+ res.status(status).set(headers).json(body);
893
+ return;
894
+ }
895
+ const reqOptions = getRequirements(req);
896
+ const requirements = buildPaymentRequirements(reqOptions);
897
+ const verifyResult = await client.verify(payment, requirements);
898
+ if (!verifyResult.isValid) {
899
+ res.status(402).json({
900
+ error: "Payment verification failed",
901
+ reason: verifyResult.invalidReason
902
+ });
903
+ return;
904
+ }
905
+ next();
906
+ };
907
+ }
908
+ var BazaarClient = class {
909
+ baseUrl;
910
+ apiKey;
911
+ timeout;
912
+ constructor(options = {}) {
913
+ this.baseUrl = options.baseUrl || "https://bazaar.ultravioletadao.xyz";
914
+ this.apiKey = options.apiKey;
915
+ this.timeout = options.timeout || 3e4;
916
+ }
917
+ /**
918
+ * Discover x402-enabled resources
919
+ *
920
+ * @param options - Discovery filters
921
+ * @returns Paginated list of matching resources
922
+ *
923
+ * @example
924
+ * ```ts
925
+ * // Find AI APIs on Base with USDC under $0.10
926
+ * const results = await bazaar.discover({
927
+ * category: 'ai',
928
+ * network: 'base',
929
+ * token: 'USDC',
930
+ * maxPrice: '0.10',
931
+ * });
932
+ *
933
+ * for (const resource of results.resources) {
934
+ * console.log(`${resource.name}: ${resource.url}`);
935
+ * }
936
+ * ```
937
+ */
938
+ async discover(options = {}) {
939
+ const params = new URLSearchParams();
940
+ if (options.category) params.set("category", options.category);
941
+ if (options.network) params.set("network", options.network);
942
+ if (options.token) params.set("token", options.token);
943
+ if (options.provider) params.set("provider", options.provider);
944
+ if (options.tags?.length) params.set("tags", options.tags.join(","));
945
+ if (options.query) params.set("query", options.query);
946
+ if (options.maxPrice) params.set("maxPrice", options.maxPrice);
947
+ if (options.page) params.set("page", options.page.toString());
948
+ if (options.limit) params.set("limit", options.limit.toString());
949
+ if (options.sortBy) params.set("sortBy", options.sortBy);
950
+ if (options.sortOrder) params.set("sortOrder", options.sortOrder);
951
+ const url = `${this.baseUrl}/resources${params.toString() ? `?${params}` : ""}`;
952
+ const controller = new AbortController();
953
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
954
+ try {
955
+ const response = await fetch(url, {
956
+ method: "GET",
957
+ headers: { "Accept": "application/json" },
958
+ signal: controller.signal
959
+ });
960
+ clearTimeout(timeoutId);
961
+ if (!response.ok) {
962
+ const errorText = await response.text();
963
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
964
+ }
965
+ return await response.json();
966
+ } catch (error) {
967
+ clearTimeout(timeoutId);
968
+ throw error;
969
+ }
970
+ }
971
+ /**
972
+ * Get a specific resource by ID
973
+ *
974
+ * @param resourceId - Resource ID
975
+ * @returns Resource details
976
+ */
977
+ async getResource(resourceId) {
978
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
979
+ const controller = new AbortController();
980
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
981
+ try {
982
+ const response = await fetch(url, {
983
+ method: "GET",
984
+ headers: { "Accept": "application/json" },
985
+ signal: controller.signal
986
+ });
987
+ clearTimeout(timeoutId);
988
+ if (!response.ok) {
989
+ const errorText = await response.text();
990
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
991
+ }
992
+ return await response.json();
993
+ } catch (error) {
994
+ clearTimeout(timeoutId);
995
+ throw error;
996
+ }
997
+ }
998
+ /**
999
+ * Get a resource by its URL
1000
+ *
1001
+ * @param resourceUrl - Resource URL
1002
+ * @returns Resource details
1003
+ */
1004
+ async getResourceByUrl(resourceUrl) {
1005
+ const url = `${this.baseUrl}/resources/by-url?url=${encodeURIComponent(resourceUrl)}`;
1006
+ const controller = new AbortController();
1007
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1008
+ try {
1009
+ const response = await fetch(url, {
1010
+ method: "GET",
1011
+ headers: { "Accept": "application/json" },
1012
+ signal: controller.signal
1013
+ });
1014
+ clearTimeout(timeoutId);
1015
+ if (!response.ok) {
1016
+ const errorText = await response.text();
1017
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1018
+ }
1019
+ return await response.json();
1020
+ } catch (error) {
1021
+ clearTimeout(timeoutId);
1022
+ throw error;
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Register a new resource in the Bazaar
1027
+ *
1028
+ * Requires API key authentication.
1029
+ *
1030
+ * @param options - Resource registration options
1031
+ * @returns Registered resource
1032
+ *
1033
+ * @example
1034
+ * ```ts
1035
+ * const resource = await bazaar.register({
1036
+ * url: 'https://api.example.com/v1/generate',
1037
+ * name: 'Image Generator API',
1038
+ * description: 'Generate images with AI',
1039
+ * category: 'ai',
1040
+ * networks: ['base', 'ethereum', 'polygon'],
1041
+ * price: '0.05',
1042
+ * payTo: '0x1234...',
1043
+ * tags: ['ai', 'image', 'generator'],
1044
+ * });
1045
+ * ```
1046
+ */
1047
+ async register(options) {
1048
+ if (!this.apiKey) {
1049
+ throw new Error("API key required for resource registration");
1050
+ }
1051
+ const url = `${this.baseUrl}/resources`;
1052
+ const controller = new AbortController();
1053
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1054
+ try {
1055
+ const response = await fetch(url, {
1056
+ method: "POST",
1057
+ headers: {
1058
+ "Content-Type": "application/json",
1059
+ "Accept": "application/json",
1060
+ "Authorization": `Bearer ${this.apiKey}`
1061
+ },
1062
+ body: JSON.stringify({
1063
+ url: options.url,
1064
+ name: options.name,
1065
+ description: options.description,
1066
+ category: options.category,
1067
+ networks: options.networks,
1068
+ tokens: options.tokens || ["USDC"],
1069
+ price: options.price,
1070
+ priceCurrency: options.priceCurrency || "USDC",
1071
+ payTo: options.payTo,
1072
+ mimeType: options.mimeType || "application/json",
1073
+ outputSchema: options.outputSchema,
1074
+ tags: options.tags
1075
+ }),
1076
+ signal: controller.signal
1077
+ });
1078
+ clearTimeout(timeoutId);
1079
+ if (!response.ok) {
1080
+ const errorText = await response.text();
1081
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1082
+ }
1083
+ return await response.json();
1084
+ } catch (error) {
1085
+ clearTimeout(timeoutId);
1086
+ throw error;
1087
+ }
1088
+ }
1089
+ /**
1090
+ * Update an existing resource
1091
+ *
1092
+ * Requires API key authentication. Only the owner can update.
1093
+ *
1094
+ * @param resourceId - Resource ID to update
1095
+ * @param updates - Partial update options
1096
+ * @returns Updated resource
1097
+ */
1098
+ async update(resourceId, updates) {
1099
+ if (!this.apiKey) {
1100
+ throw new Error("API key required for resource update");
1101
+ }
1102
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
1103
+ const controller = new AbortController();
1104
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1105
+ try {
1106
+ const response = await fetch(url, {
1107
+ method: "PATCH",
1108
+ headers: {
1109
+ "Content-Type": "application/json",
1110
+ "Accept": "application/json",
1111
+ "Authorization": `Bearer ${this.apiKey}`
1112
+ },
1113
+ body: JSON.stringify(updates),
1114
+ signal: controller.signal
1115
+ });
1116
+ clearTimeout(timeoutId);
1117
+ if (!response.ok) {
1118
+ const errorText = await response.text();
1119
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1120
+ }
1121
+ return await response.json();
1122
+ } catch (error) {
1123
+ clearTimeout(timeoutId);
1124
+ throw error;
1125
+ }
1126
+ }
1127
+ /**
1128
+ * Delete a resource from the Bazaar
1129
+ *
1130
+ * Requires API key authentication. Only the owner can delete.
1131
+ *
1132
+ * @param resourceId - Resource ID to delete
1133
+ */
1134
+ async delete(resourceId) {
1135
+ if (!this.apiKey) {
1136
+ throw new Error("API key required for resource deletion");
1137
+ }
1138
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
1139
+ const controller = new AbortController();
1140
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1141
+ try {
1142
+ const response = await fetch(url, {
1143
+ method: "DELETE",
1144
+ headers: {
1145
+ "Authorization": `Bearer ${this.apiKey}`
1146
+ },
1147
+ signal: controller.signal
1148
+ });
1149
+ clearTimeout(timeoutId);
1150
+ if (!response.ok) {
1151
+ const errorText = await response.text();
1152
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1153
+ }
1154
+ } catch (error) {
1155
+ clearTimeout(timeoutId);
1156
+ throw error;
1157
+ }
1158
+ }
1159
+ /**
1160
+ * Deactivate a resource (soft delete)
1161
+ *
1162
+ * Requires API key authentication. Only the owner can deactivate.
1163
+ *
1164
+ * @param resourceId - Resource ID to deactivate
1165
+ * @returns Updated resource with isActive: false
1166
+ */
1167
+ async deactivate(resourceId) {
1168
+ if (!this.apiKey) {
1169
+ throw new Error("API key required for resource deactivation");
1170
+ }
1171
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}/deactivate`;
1172
+ const controller = new AbortController();
1173
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1174
+ try {
1175
+ const response = await fetch(url, {
1176
+ method: "POST",
1177
+ headers: {
1178
+ "Authorization": `Bearer ${this.apiKey}`
1179
+ },
1180
+ signal: controller.signal
1181
+ });
1182
+ clearTimeout(timeoutId);
1183
+ if (!response.ok) {
1184
+ const errorText = await response.text();
1185
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1186
+ }
1187
+ return await response.json();
1188
+ } catch (error) {
1189
+ clearTimeout(timeoutId);
1190
+ throw error;
1191
+ }
1192
+ }
1193
+ /**
1194
+ * Reactivate a deactivated resource
1195
+ *
1196
+ * Requires API key authentication. Only the owner can reactivate.
1197
+ *
1198
+ * @param resourceId - Resource ID to reactivate
1199
+ * @returns Updated resource with isActive: true
1200
+ */
1201
+ async reactivate(resourceId) {
1202
+ if (!this.apiKey) {
1203
+ throw new Error("API key required for resource reactivation");
1204
+ }
1205
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}/reactivate`;
1206
+ const controller = new AbortController();
1207
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1208
+ try {
1209
+ const response = await fetch(url, {
1210
+ method: "POST",
1211
+ headers: {
1212
+ "Authorization": `Bearer ${this.apiKey}`
1213
+ },
1214
+ signal: controller.signal
1215
+ });
1216
+ clearTimeout(timeoutId);
1217
+ if (!response.ok) {
1218
+ const errorText = await response.text();
1219
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1220
+ }
1221
+ return await response.json();
1222
+ } catch (error) {
1223
+ clearTimeout(timeoutId);
1224
+ throw error;
1225
+ }
1226
+ }
1227
+ /**
1228
+ * List all resources owned by the authenticated user
1229
+ *
1230
+ * Requires API key authentication.
1231
+ *
1232
+ * @param options - Pagination options
1233
+ * @returns Paginated list of owned resources
1234
+ */
1235
+ async listMyResources(options = {}) {
1236
+ if (!this.apiKey) {
1237
+ throw new Error("API key required to list owned resources");
1238
+ }
1239
+ const params = new URLSearchParams();
1240
+ if (options.page) params.set("page", options.page.toString());
1241
+ if (options.limit) params.set("limit", options.limit.toString());
1242
+ if (options.includeInactive) params.set("includeInactive", "true");
1243
+ const url = `${this.baseUrl}/resources/mine${params.toString() ? `?${params}` : ""}`;
1244
+ const controller = new AbortController();
1245
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1246
+ try {
1247
+ const response = await fetch(url, {
1248
+ method: "GET",
1249
+ headers: {
1250
+ "Accept": "application/json",
1251
+ "Authorization": `Bearer ${this.apiKey}`
1252
+ },
1253
+ signal: controller.signal
1254
+ });
1255
+ clearTimeout(timeoutId);
1256
+ if (!response.ok) {
1257
+ const errorText = await response.text();
1258
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1259
+ }
1260
+ return await response.json();
1261
+ } catch (error) {
1262
+ clearTimeout(timeoutId);
1263
+ throw error;
1264
+ }
1265
+ }
1266
+ /**
1267
+ * Get Bazaar API health status
1268
+ *
1269
+ * @returns True if the Bazaar API is healthy
1270
+ */
1271
+ async healthCheck() {
1272
+ try {
1273
+ const response = await fetch(`${this.baseUrl}/health`, {
1274
+ method: "GET"
1275
+ });
1276
+ return response.ok;
1277
+ } catch {
1278
+ return false;
1279
+ }
1280
+ }
1281
+ /**
1282
+ * Get Bazaar statistics
1283
+ *
1284
+ * @returns Global statistics about the Bazaar
1285
+ */
1286
+ async getStats() {
1287
+ const url = `${this.baseUrl}/stats`;
1288
+ const controller = new AbortController();
1289
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1290
+ try {
1291
+ const response = await fetch(url, {
1292
+ method: "GET",
1293
+ headers: { "Accept": "application/json" },
1294
+ signal: controller.signal
1295
+ });
1296
+ clearTimeout(timeoutId);
1297
+ if (!response.ok) {
1298
+ const errorText = await response.text();
1299
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1300
+ }
1301
+ return await response.json();
1302
+ } catch (error) {
1303
+ clearTimeout(timeoutId);
1304
+ throw error;
1305
+ }
1306
+ }
1307
+ };
1308
+ var EscrowClient = class {
1309
+ baseUrl;
1310
+ apiKey;
1311
+ timeout;
1312
+ constructor(options = {}) {
1313
+ this.baseUrl = options.baseUrl || "https://escrow.ultravioletadao.xyz";
1314
+ this.apiKey = options.apiKey;
1315
+ this.timeout = options.timeout || 3e4;
1316
+ }
1317
+ getHeaders(authenticated = false) {
1318
+ const headers = {
1319
+ "Content-Type": "application/json",
1320
+ "Accept": "application/json"
1321
+ };
1322
+ if (authenticated && this.apiKey) {
1323
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
1324
+ }
1325
+ return headers;
1326
+ }
1327
+ /**
1328
+ * Create an escrow payment
1329
+ *
1330
+ * Holds the payment in escrow until released or refunded.
1331
+ *
1332
+ * @param options - Escrow creation options
1333
+ * @returns Created escrow payment
1334
+ */
1335
+ async createEscrow(options) {
1336
+ const url = `${this.baseUrl}/escrow`;
1337
+ const controller = new AbortController();
1338
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1339
+ try {
1340
+ const response = await fetch(url, {
1341
+ method: "POST",
1342
+ headers: this.getHeaders(true),
1343
+ body: JSON.stringify({
1344
+ paymentHeader: options.paymentHeader,
1345
+ paymentRequirements: options.requirements,
1346
+ escrowDuration: options.escrowDuration || 86400,
1347
+ releaseConditions: options.releaseConditions
1348
+ }),
1349
+ signal: controller.signal
1350
+ });
1351
+ clearTimeout(timeoutId);
1352
+ if (!response.ok) {
1353
+ const errorText = await response.text();
1354
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1355
+ }
1356
+ return await response.json();
1357
+ } catch (error) {
1358
+ clearTimeout(timeoutId);
1359
+ throw error;
1360
+ }
1361
+ }
1362
+ /**
1363
+ * Get escrow payment by ID
1364
+ *
1365
+ * @param escrowId - Escrow payment ID
1366
+ * @returns Escrow payment details
1367
+ */
1368
+ async getEscrow(escrowId) {
1369
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}`;
1370
+ const controller = new AbortController();
1371
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1372
+ try {
1373
+ const response = await fetch(url, {
1374
+ method: "GET",
1375
+ headers: this.getHeaders(),
1376
+ signal: controller.signal
1377
+ });
1378
+ clearTimeout(timeoutId);
1379
+ if (!response.ok) {
1380
+ const errorText = await response.text();
1381
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1382
+ }
1383
+ return await response.json();
1384
+ } catch (error) {
1385
+ clearTimeout(timeoutId);
1386
+ throw error;
1387
+ }
1388
+ }
1389
+ /**
1390
+ * Release escrow funds to recipient
1391
+ *
1392
+ * Call this after service has been successfully provided.
1393
+ *
1394
+ * @param escrowId - Escrow payment ID
1395
+ * @returns Updated escrow payment with transaction hash
1396
+ */
1397
+ async release(escrowId) {
1398
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/release`;
1399
+ const controller = new AbortController();
1400
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1401
+ try {
1402
+ const response = await fetch(url, {
1403
+ method: "POST",
1404
+ headers: this.getHeaders(true),
1405
+ signal: controller.signal
1406
+ });
1407
+ clearTimeout(timeoutId);
1408
+ if (!response.ok) {
1409
+ const errorText = await response.text();
1410
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1411
+ }
1412
+ return await response.json();
1413
+ } catch (error) {
1414
+ clearTimeout(timeoutId);
1415
+ throw error;
1416
+ }
1417
+ }
1418
+ /**
1419
+ * Request a refund for an escrow payment
1420
+ *
1421
+ * Initiates a refund request that must be approved.
1422
+ *
1423
+ * @param options - Refund request options
1424
+ * @returns Created refund request
1425
+ */
1426
+ async requestRefund(options) {
1427
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(options.escrowId)}/refund`;
1428
+ const controller = new AbortController();
1429
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1430
+ try {
1431
+ const response = await fetch(url, {
1432
+ method: "POST",
1433
+ headers: this.getHeaders(true),
1434
+ body: JSON.stringify({
1435
+ reason: options.reason,
1436
+ amount: options.amount,
1437
+ evidence: options.evidence
1438
+ }),
1439
+ signal: controller.signal
1440
+ });
1441
+ clearTimeout(timeoutId);
1442
+ if (!response.ok) {
1443
+ const errorText = await response.text();
1444
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1445
+ }
1446
+ return await response.json();
1447
+ } catch (error) {
1448
+ clearTimeout(timeoutId);
1449
+ throw error;
1450
+ }
1451
+ }
1452
+ /**
1453
+ * Approve a refund request (for recipients)
1454
+ *
1455
+ * @param refundId - Refund request ID
1456
+ * @param amount - Amount to approve (may be less than requested)
1457
+ * @returns Updated refund request
1458
+ */
1459
+ async approveRefund(refundId, amount) {
1460
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/approve`;
1461
+ const controller = new AbortController();
1462
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1463
+ try {
1464
+ const response = await fetch(url, {
1465
+ method: "POST",
1466
+ headers: this.getHeaders(true),
1467
+ body: JSON.stringify({ amount }),
1468
+ signal: controller.signal
1469
+ });
1470
+ clearTimeout(timeoutId);
1471
+ if (!response.ok) {
1472
+ const errorText = await response.text();
1473
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1474
+ }
1475
+ return await response.json();
1476
+ } catch (error) {
1477
+ clearTimeout(timeoutId);
1478
+ throw error;
1479
+ }
1480
+ }
1481
+ /**
1482
+ * Reject a refund request (for recipients)
1483
+ *
1484
+ * @param refundId - Refund request ID
1485
+ * @param reason - Reason for rejection
1486
+ * @returns Updated refund request
1487
+ */
1488
+ async rejectRefund(refundId, reason) {
1489
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/reject`;
1490
+ const controller = new AbortController();
1491
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1492
+ try {
1493
+ const response = await fetch(url, {
1494
+ method: "POST",
1495
+ headers: this.getHeaders(true),
1496
+ body: JSON.stringify({ reason }),
1497
+ signal: controller.signal
1498
+ });
1499
+ clearTimeout(timeoutId);
1500
+ if (!response.ok) {
1501
+ const errorText = await response.text();
1502
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1503
+ }
1504
+ return await response.json();
1505
+ } catch (error) {
1506
+ clearTimeout(timeoutId);
1507
+ throw error;
1508
+ }
1509
+ }
1510
+ /**
1511
+ * Get refund request by ID
1512
+ *
1513
+ * @param refundId - Refund request ID
1514
+ * @returns Refund request details
1515
+ */
1516
+ async getRefund(refundId) {
1517
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}`;
1518
+ const controller = new AbortController();
1519
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1520
+ try {
1521
+ const response = await fetch(url, {
1522
+ method: "GET",
1523
+ headers: this.getHeaders(),
1524
+ signal: controller.signal
1525
+ });
1526
+ clearTimeout(timeoutId);
1527
+ if (!response.ok) {
1528
+ const errorText = await response.text();
1529
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1530
+ }
1531
+ return await response.json();
1532
+ } catch (error) {
1533
+ clearTimeout(timeoutId);
1534
+ throw error;
1535
+ }
1536
+ }
1537
+ /**
1538
+ * Open a dispute for an escrow payment
1539
+ *
1540
+ * Initiates arbitration when payer and recipient disagree.
1541
+ *
1542
+ * @param escrowId - Escrow payment ID
1543
+ * @param reason - Reason for dispute
1544
+ * @param evidence - Supporting evidence
1545
+ * @returns Created dispute
1546
+ */
1547
+ async openDispute(escrowId, reason, evidence) {
1548
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/dispute`;
1549
+ const controller = new AbortController();
1550
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1551
+ try {
1552
+ const response = await fetch(url, {
1553
+ method: "POST",
1554
+ headers: this.getHeaders(true),
1555
+ body: JSON.stringify({ reason, evidence }),
1556
+ signal: controller.signal
1557
+ });
1558
+ clearTimeout(timeoutId);
1559
+ if (!response.ok) {
1560
+ const errorText = await response.text();
1561
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1562
+ }
1563
+ return await response.json();
1564
+ } catch (error) {
1565
+ clearTimeout(timeoutId);
1566
+ throw error;
1567
+ }
1568
+ }
1569
+ /**
1570
+ * Submit evidence to a dispute
1571
+ *
1572
+ * @param disputeId - Dispute ID
1573
+ * @param evidence - Evidence to submit
1574
+ * @returns Updated dispute
1575
+ */
1576
+ async submitEvidence(disputeId, evidence) {
1577
+ const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}/evidence`;
1578
+ const controller = new AbortController();
1579
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1580
+ try {
1581
+ const response = await fetch(url, {
1582
+ method: "POST",
1583
+ headers: this.getHeaders(true),
1584
+ body: JSON.stringify({ evidence }),
1585
+ signal: controller.signal
1586
+ });
1587
+ clearTimeout(timeoutId);
1588
+ if (!response.ok) {
1589
+ const errorText = await response.text();
1590
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1591
+ }
1592
+ return await response.json();
1593
+ } catch (error) {
1594
+ clearTimeout(timeoutId);
1595
+ throw error;
1596
+ }
1597
+ }
1598
+ /**
1599
+ * Get dispute by ID
1600
+ *
1601
+ * @param disputeId - Dispute ID
1602
+ * @returns Dispute details
1603
+ */
1604
+ async getDispute(disputeId) {
1605
+ const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}`;
1606
+ const controller = new AbortController();
1607
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1608
+ try {
1609
+ const response = await fetch(url, {
1610
+ method: "GET",
1611
+ headers: this.getHeaders(),
1612
+ signal: controller.signal
1613
+ });
1614
+ clearTimeout(timeoutId);
1615
+ if (!response.ok) {
1616
+ const errorText = await response.text();
1617
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1618
+ }
1619
+ return await response.json();
1620
+ } catch (error) {
1621
+ clearTimeout(timeoutId);
1622
+ throw error;
1623
+ }
1624
+ }
1625
+ /**
1626
+ * List escrow payments (with filters)
1627
+ *
1628
+ * @param options - Filter and pagination options
1629
+ * @returns Paginated list of escrow payments
1630
+ */
1631
+ async listEscrows(options = {}) {
1632
+ const params = new URLSearchParams();
1633
+ if (options.status) params.set("status", options.status);
1634
+ if (options.payer) params.set("payer", options.payer);
1635
+ if (options.recipient) params.set("recipient", options.recipient);
1636
+ if (options.page) params.set("page", options.page.toString());
1637
+ if (options.limit) params.set("limit", options.limit.toString());
1638
+ const url = `${this.baseUrl}/escrow${params.toString() ? `?${params}` : ""}`;
1639
+ const controller = new AbortController();
1640
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1641
+ try {
1642
+ const response = await fetch(url, {
1643
+ method: "GET",
1644
+ headers: this.getHeaders(true),
1645
+ signal: controller.signal
1646
+ });
1647
+ clearTimeout(timeoutId);
1648
+ if (!response.ok) {
1649
+ const errorText = await response.text();
1650
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1651
+ }
1652
+ return await response.json();
1653
+ } catch (error) {
1654
+ clearTimeout(timeoutId);
1655
+ throw error;
1656
+ }
1657
+ }
1658
+ /**
1659
+ * Check Escrow API health
1660
+ *
1661
+ * @returns True if healthy
1662
+ */
1663
+ async healthCheck() {
1664
+ try {
1665
+ const response = await fetch(`${this.baseUrl}/health`, {
1666
+ method: "GET"
1667
+ });
1668
+ return response.ok;
1669
+ } catch {
1670
+ return false;
1671
+ }
1672
+ }
1673
+ };
1674
+ function canReleaseEscrow(escrow) {
1675
+ if (escrow.status !== "held") {
1676
+ return false;
1677
+ }
1678
+ if (new Date(escrow.expiresAt) < /* @__PURE__ */ new Date()) {
1679
+ return false;
1680
+ }
1681
+ if (escrow.releaseConditions?.minHoldTime) {
1682
+ const createdAt = new Date(escrow.createdAt);
1683
+ const minReleaseTime = new Date(
1684
+ createdAt.getTime() + escrow.releaseConditions.minHoldTime * 1e3
1685
+ );
1686
+ if (/* @__PURE__ */ new Date() < minReleaseTime) {
1687
+ return false;
1688
+ }
1689
+ }
1690
+ return true;
1691
+ }
1692
+ function canRefundEscrow(escrow) {
1693
+ return escrow.status === "held" || escrow.status === "pending";
1694
+ }
1695
+ function isEscrowExpired(escrow) {
1696
+ return new Date(escrow.expiresAt) < /* @__PURE__ */ new Date();
1697
+ }
1698
+ function escrowTimeRemaining(escrow) {
1699
+ return new Date(escrow.expiresAt).getTime() - Date.now();
1700
+ }
1701
+
1702
+ export { BazaarClient, EscrowClient, FacilitatorClient, X402_CORS_HEADERS, X402_HEADER_NAMES, buildPaymentRequirements, buildSettleRequest, buildVerifyRequest, canRefundEscrow, canReleaseEscrow, create402Response, createPaymentMiddleware, escrowTimeRemaining, extractPaymentFromHeaders, getCorsHeaders, isEscrowExpired, parsePaymentHeader };
1703
+ //# sourceMappingURL=index.mjs.map
1704
+ //# sourceMappingURL=index.mjs.map