uvd-x402-sdk 2.6.0 → 2.10.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.
Files changed (71) 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 +94 -1
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/adapters/index.mjs +94 -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 +1738 -0
  11. package/dist/backend/index.js.map +1 -0
  12. package/dist/backend/index.mjs +1720 -0
  13. package/dist/backend/index.mjs.map +1 -0
  14. package/dist/{index-fwbSkart.d.ts → index-C60c_e5z.d.mts} +13 -4
  15. package/dist/{index-BR1o8JZQ.d.mts → index-D-dO_FoP.d.mts} +38 -4
  16. package/dist/{index-BR1o8JZQ.d.ts → index-D-dO_FoP.d.ts} +38 -4
  17. package/dist/{index-DKbWiaJ9.d.mts → index-VIOUicmO.d.ts} +13 -4
  18. package/dist/index.d.mts +2 -2
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +109 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +108 -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 +919 -0
  27. package/dist/providers/algorand/index.js.map +1 -0
  28. package/dist/providers/algorand/index.mjs +914 -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 +94 -1
  33. package/dist/providers/evm/index.js.map +1 -1
  34. package/dist/providers/evm/index.mjs +94 -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 +94 -1
  39. package/dist/providers/near/index.js.map +1 -1
  40. package/dist/providers/near/index.mjs +94 -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 +94 -1
  45. package/dist/providers/solana/index.js.map +1 -1
  46. package/dist/providers/solana/index.mjs +94 -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 +94 -1
  51. package/dist/providers/stellar/index.js.map +1 -1
  52. package/dist/providers/stellar/index.mjs +94 -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 +94 -1
  57. package/dist/react/index.js.map +1 -1
  58. package/dist/react/index.mjs +94 -1
  59. package/dist/react/index.mjs.map +1 -1
  60. package/dist/utils/index.d.mts +1 -1
  61. package/dist/utils/index.d.ts +1 -1
  62. package/dist/utils/index.js +94 -1
  63. package/dist/utils/index.js.map +1 -1
  64. package/dist/utils/index.mjs +94 -1
  65. package/dist/utils/index.mjs.map +1 -1
  66. package/package.json +24 -3
  67. package/src/backend/index.ts +2131 -0
  68. package/src/chains/index.ts +108 -2
  69. package/src/index.ts +19 -1
  70. package/src/providers/algorand/index.ts +356 -0
  71. package/src/types/index.ts +44 -3
@@ -0,0 +1,1720 @@
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
+ tokens: {
461
+ usdc: {
462
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
463
+ // USDC SPL token mint
464
+ decimals: 6,
465
+ name: "USD Coin",
466
+ version: "1"
467
+ },
468
+ ausd: {
469
+ address: "AUSD1jCcCyPLybk1YnvPWsHQSrZ46dxwoMniN4N2UEB9",
470
+ // AUSD Token2022 mint
471
+ decimals: 6,
472
+ name: "Agora Dollar",
473
+ version: "1"
474
+ }
475
+ },
476
+ x402: {
477
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
478
+ enabled: true
479
+ }
480
+ },
481
+ fogo: {
482
+ chainId: 0,
483
+ // Non-EVM (SVM)
484
+ chainIdHex: "0x0",
485
+ name: "fogo",
486
+ displayName: "Fogo",
487
+ networkType: "svm",
488
+ rpcUrl: "https://rpc.fogo.nightly.app/",
489
+ explorerUrl: "https://explorer.fogo.nightly.app",
490
+ nativeCurrency: {
491
+ name: "Fogo",
492
+ symbol: "FOGO",
493
+ decimals: 9
494
+ },
495
+ usdc: {
496
+ address: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
497
+ // Fogo USDC mint
498
+ decimals: 6,
499
+ name: "USDC",
500
+ version: "1"
501
+ },
502
+ x402: {
503
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
504
+ enabled: true
505
+ }
506
+ },
507
+ // ============================================================================
508
+ // STELLAR (1 network)
509
+ // ============================================================================
510
+ stellar: {
511
+ chainId: 0,
512
+ // Non-EVM
513
+ chainIdHex: "0x0",
514
+ name: "stellar",
515
+ displayName: "Stellar",
516
+ networkType: "stellar",
517
+ rpcUrl: "https://horizon.stellar.org",
518
+ explorerUrl: "https://stellar.expert/explorer/public",
519
+ nativeCurrency: {
520
+ name: "Lumens",
521
+ symbol: "XLM",
522
+ decimals: 7
523
+ // Stellar uses 7 decimals (stroops)
524
+ },
525
+ usdc: {
526
+ address: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
527
+ // Soroban Asset Contract
528
+ decimals: 7,
529
+ // Stellar USDC uses 7 decimals
530
+ name: "USDC",
531
+ version: "1"
532
+ },
533
+ x402: {
534
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
535
+ enabled: true
536
+ }
537
+ },
538
+ // ============================================================================
539
+ // NEAR (1 network) - Uses NEP-366 meta-transactions
540
+ // ============================================================================
541
+ near: {
542
+ chainId: 0,
543
+ // Non-EVM
544
+ chainIdHex: "0x0",
545
+ name: "near",
546
+ displayName: "NEAR Protocol",
547
+ networkType: "near",
548
+ rpcUrl: "https://rpc.mainnet.near.org",
549
+ explorerUrl: "https://nearblocks.io",
550
+ nativeCurrency: {
551
+ name: "NEAR",
552
+ symbol: "NEAR",
553
+ decimals: 24
554
+ // NEAR uses 24 decimals (yoctoNEAR)
555
+ },
556
+ usdc: {
557
+ address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
558
+ // Native Circle USDC
559
+ decimals: 6,
560
+ name: "USDC",
561
+ version: "1"
562
+ },
563
+ x402: {
564
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
565
+ enabled: true
566
+ // NEP-366 meta-transactions supported
567
+ }
568
+ },
569
+ // ============================================================================
570
+ // ALGORAND (2 networks) - Uses ASA transfers with atomic transaction groups
571
+ // ============================================================================
572
+ algorand: {
573
+ chainId: 0,
574
+ // Non-EVM (Algorand uses genesis hash for network identification)
575
+ chainIdHex: "0x0",
576
+ name: "algorand",
577
+ displayName: "Algorand",
578
+ networkType: "algorand",
579
+ rpcUrl: "https://mainnet-api.algonode.cloud",
580
+ explorerUrl: "https://allo.info",
581
+ nativeCurrency: {
582
+ name: "Algo",
583
+ symbol: "ALGO",
584
+ decimals: 6
585
+ // Algorand uses 6 decimals (microAlgos)
586
+ },
587
+ usdc: {
588
+ address: "31566704",
589
+ // USDC ASA ID on Algorand mainnet
590
+ decimals: 6,
591
+ name: "USDC",
592
+ version: "1"
593
+ },
594
+ tokens: {
595
+ usdc: {
596
+ address: "31566704",
597
+ // USDC ASA ID on Algorand mainnet
598
+ decimals: 6,
599
+ name: "USDC",
600
+ version: "1"
601
+ }
602
+ },
603
+ x402: {
604
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
605
+ enabled: true
606
+ }
607
+ },
608
+ "algorand-testnet": {
609
+ chainId: 0,
610
+ // Non-EVM
611
+ chainIdHex: "0x0",
612
+ name: "algorand-testnet",
613
+ displayName: "Algorand Testnet",
614
+ networkType: "algorand",
615
+ rpcUrl: "https://testnet-api.algonode.cloud",
616
+ explorerUrl: "https://testnet.allo.info",
617
+ nativeCurrency: {
618
+ name: "Algo",
619
+ symbol: "ALGO",
620
+ decimals: 6
621
+ },
622
+ usdc: {
623
+ address: "10458941",
624
+ // USDC ASA ID on Algorand testnet
625
+ decimals: 6,
626
+ name: "USDC",
627
+ version: "1"
628
+ },
629
+ tokens: {
630
+ usdc: {
631
+ address: "10458941",
632
+ // USDC ASA ID on Algorand testnet
633
+ decimals: 6,
634
+ name: "USDC",
635
+ version: "1"
636
+ }
637
+ },
638
+ x402: {
639
+ facilitatorUrl: DEFAULT_FACILITATOR_URL,
640
+ enabled: true
641
+ }
642
+ }
643
+ };
644
+ function getChainByName(name) {
645
+ return SUPPORTED_CHAINS[name.toLowerCase()];
646
+ }
647
+
648
+ // src/utils/x402.ts
649
+ function chainToCAIP2(chainName) {
650
+ const caip2 = CAIP2_IDENTIFIERS[chainName.toLowerCase()];
651
+ if (caip2) {
652
+ return caip2;
653
+ }
654
+ const chain = getChainByName(chainName);
655
+ if (chain) {
656
+ if (chain.networkType === "evm") {
657
+ return `eip155:${chain.chainId}`;
658
+ }
659
+ return `${chain.networkType}:${chainName}`;
660
+ }
661
+ return chainName;
662
+ }
663
+ function decodeX402Header(encoded) {
664
+ const json = atob(encoded);
665
+ return JSON.parse(json);
666
+ }
667
+
668
+ // src/backend/index.ts
669
+ function parsePaymentHeader(headerValue) {
670
+ if (!headerValue) {
671
+ return null;
672
+ }
673
+ try {
674
+ return decodeX402Header(headerValue);
675
+ } catch {
676
+ return null;
677
+ }
678
+ }
679
+ function extractPaymentFromHeaders(headers) {
680
+ const normalizedHeaders = {};
681
+ for (const [key, value] of Object.entries(headers)) {
682
+ if (typeof value === "string") {
683
+ normalizedHeaders[key.toLowerCase()] = value;
684
+ } else if (Array.isArray(value) && value.length > 0) {
685
+ normalizedHeaders[key.toLowerCase()] = value[0];
686
+ }
687
+ }
688
+ const headerValue = normalizedHeaders["x-payment"] || normalizedHeaders["payment-signature"];
689
+ return parsePaymentHeader(headerValue);
690
+ }
691
+ function buildPaymentRequirements(options) {
692
+ const {
693
+ amount,
694
+ recipient,
695
+ resource,
696
+ chainName = "base",
697
+ description = "Payment for resource access",
698
+ mimeType = "application/json",
699
+ timeoutSeconds = 300,
700
+ x402Version = 1
701
+ } = options;
702
+ const chain = getChainByName(chainName);
703
+ if (!chain) {
704
+ throw new Error(`Unsupported chain: ${chainName}`);
705
+ }
706
+ const atomicAmount = Math.floor(
707
+ parseFloat(amount) * Math.pow(10, chain.usdc.decimals)
708
+ ).toString();
709
+ const network = x402Version === 2 ? chainToCAIP2(chainName) : chainName;
710
+ return {
711
+ scheme: "exact",
712
+ network,
713
+ maxAmountRequired: atomicAmount,
714
+ resource,
715
+ description,
716
+ mimeType,
717
+ payTo: recipient,
718
+ maxTimeoutSeconds: timeoutSeconds,
719
+ asset: chain.usdc.address
720
+ };
721
+ }
722
+ function buildVerifyRequest(paymentHeader, requirements) {
723
+ return {
724
+ x402Version: paymentHeader.x402Version,
725
+ paymentPayload: paymentHeader,
726
+ paymentRequirements: requirements
727
+ };
728
+ }
729
+ function buildSettleRequest(paymentHeader, requirements) {
730
+ return {
731
+ x402Version: paymentHeader.x402Version,
732
+ paymentPayload: paymentHeader,
733
+ paymentRequirements: requirements
734
+ };
735
+ }
736
+ var X402_CORS_HEADERS = {
737
+ "Access-Control-Allow-Headers": "Content-Type, X-PAYMENT, PAYMENT-SIGNATURE, Authorization",
738
+ "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE, PAYMENT-RESPONSE, PAYMENT-REQUIRED",
739
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS"
740
+ };
741
+ var X402_HEADER_NAMES = [
742
+ "X-PAYMENT",
743
+ "PAYMENT-SIGNATURE",
744
+ "X-PAYMENT-RESPONSE",
745
+ "PAYMENT-RESPONSE",
746
+ "PAYMENT-REQUIRED"
747
+ ];
748
+ function getCorsHeaders(origin = "*") {
749
+ return {
750
+ "Access-Control-Allow-Origin": origin,
751
+ ...X402_CORS_HEADERS
752
+ };
753
+ }
754
+ var FacilitatorClient = class {
755
+ baseUrl;
756
+ timeout;
757
+ constructor(options = {}) {
758
+ this.baseUrl = options.baseUrl || "https://facilitator.ultravioletadao.xyz";
759
+ this.timeout = options.timeout || 3e4;
760
+ }
761
+ /**
762
+ * Verify a payment with the facilitator
763
+ *
764
+ * Call this before providing the paid resource to validate the payment.
765
+ *
766
+ * @param paymentHeader - Parsed x402 payment header
767
+ * @param requirements - Payment requirements
768
+ * @returns Verification result
769
+ */
770
+ async verify(paymentHeader, requirements) {
771
+ const body = buildVerifyRequest(paymentHeader, requirements);
772
+ const controller = new AbortController();
773
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
774
+ try {
775
+ const response = await fetch(`${this.baseUrl}/verify`, {
776
+ method: "POST",
777
+ headers: { "Content-Type": "application/json" },
778
+ body: JSON.stringify(body),
779
+ signal: controller.signal
780
+ });
781
+ clearTimeout(timeoutId);
782
+ if (!response.ok) {
783
+ const errorText = await response.text();
784
+ return {
785
+ isValid: false,
786
+ invalidReason: `Facilitator error: ${response.status} - ${errorText}`
787
+ };
788
+ }
789
+ return await response.json();
790
+ } catch (error) {
791
+ clearTimeout(timeoutId);
792
+ return {
793
+ isValid: false,
794
+ invalidReason: error instanceof Error ? error.message : "Unknown error"
795
+ };
796
+ }
797
+ }
798
+ /**
799
+ * Settle a payment with the facilitator
800
+ *
801
+ * Call this after providing the paid resource to execute the on-chain transfer.
802
+ *
803
+ * @param paymentHeader - Parsed x402 payment header
804
+ * @param requirements - Payment requirements
805
+ * @returns Settlement result with transaction hash
806
+ */
807
+ async settle(paymentHeader, requirements) {
808
+ const body = buildSettleRequest(paymentHeader, requirements);
809
+ const controller = new AbortController();
810
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
811
+ try {
812
+ const response = await fetch(`${this.baseUrl}/settle`, {
813
+ method: "POST",
814
+ headers: { "Content-Type": "application/json" },
815
+ body: JSON.stringify(body),
816
+ signal: controller.signal
817
+ });
818
+ clearTimeout(timeoutId);
819
+ if (!response.ok) {
820
+ const errorText = await response.text();
821
+ return {
822
+ success: false,
823
+ error: `Facilitator error: ${response.status} - ${errorText}`
824
+ };
825
+ }
826
+ const result = await response.json();
827
+ return {
828
+ success: true,
829
+ transactionHash: result.transactionHash || result.transaction_hash,
830
+ network: result.network
831
+ };
832
+ } catch (error) {
833
+ clearTimeout(timeoutId);
834
+ return {
835
+ success: false,
836
+ error: error instanceof Error ? error.message : "Unknown error"
837
+ };
838
+ }
839
+ }
840
+ /**
841
+ * Verify and settle atomically
842
+ *
843
+ * Convenience method that verifies first, then settles if valid.
844
+ * Use this for simple payment flows where you don't need custom logic between verify and settle.
845
+ *
846
+ * @param paymentHeader - Parsed x402 payment header
847
+ * @param requirements - Payment requirements
848
+ * @returns Combined result with verify and settle status
849
+ */
850
+ async verifyAndSettle(paymentHeader, requirements) {
851
+ const verifyResult = await this.verify(paymentHeader, requirements);
852
+ if (!verifyResult.isValid) {
853
+ return {
854
+ verified: false,
855
+ settled: false,
856
+ error: verifyResult.invalidReason
857
+ };
858
+ }
859
+ const settleResult = await this.settle(paymentHeader, requirements);
860
+ return {
861
+ verified: true,
862
+ settled: settleResult.success,
863
+ transactionHash: settleResult.transactionHash,
864
+ error: settleResult.error
865
+ };
866
+ }
867
+ /**
868
+ * Check if the facilitator is healthy
869
+ *
870
+ * @returns True if the facilitator is responding
871
+ */
872
+ async healthCheck() {
873
+ try {
874
+ const response = await fetch(`${this.baseUrl}/health`, {
875
+ method: "GET"
876
+ });
877
+ return response.ok;
878
+ } catch {
879
+ return false;
880
+ }
881
+ }
882
+ };
883
+ function create402Response(requirements, options = {}) {
884
+ const reqs = buildPaymentRequirements(requirements);
885
+ const body = {
886
+ x402Version: requirements.x402Version || 1,
887
+ ...reqs
888
+ };
889
+ if (options.accepts) {
890
+ body.accepts = options.accepts;
891
+ }
892
+ return {
893
+ status: 402,
894
+ headers: {
895
+ "Content-Type": "application/json",
896
+ ...X402_CORS_HEADERS
897
+ },
898
+ body
899
+ };
900
+ }
901
+ function createPaymentMiddleware(getRequirements, options = {}) {
902
+ const client = new FacilitatorClient(options);
903
+ return async (req, res, next) => {
904
+ const payment = extractPaymentFromHeaders(req.headers);
905
+ if (!payment) {
906
+ const reqOptions2 = getRequirements(req);
907
+ const { status, headers, body } = create402Response(reqOptions2);
908
+ res.status(status).set(headers).json(body);
909
+ return;
910
+ }
911
+ const reqOptions = getRequirements(req);
912
+ const requirements = buildPaymentRequirements(reqOptions);
913
+ const verifyResult = await client.verify(payment, requirements);
914
+ if (!verifyResult.isValid) {
915
+ res.status(402).json({
916
+ error: "Payment verification failed",
917
+ reason: verifyResult.invalidReason
918
+ });
919
+ return;
920
+ }
921
+ next();
922
+ };
923
+ }
924
+ var BazaarClient = class {
925
+ baseUrl;
926
+ apiKey;
927
+ timeout;
928
+ constructor(options = {}) {
929
+ this.baseUrl = options.baseUrl || "https://bazaar.ultravioletadao.xyz";
930
+ this.apiKey = options.apiKey;
931
+ this.timeout = options.timeout || 3e4;
932
+ }
933
+ /**
934
+ * Discover x402-enabled resources
935
+ *
936
+ * @param options - Discovery filters
937
+ * @returns Paginated list of matching resources
938
+ *
939
+ * @example
940
+ * ```ts
941
+ * // Find AI APIs on Base with USDC under $0.10
942
+ * const results = await bazaar.discover({
943
+ * category: 'ai',
944
+ * network: 'base',
945
+ * token: 'USDC',
946
+ * maxPrice: '0.10',
947
+ * });
948
+ *
949
+ * for (const resource of results.resources) {
950
+ * console.log(`${resource.name}: ${resource.url}`);
951
+ * }
952
+ * ```
953
+ */
954
+ async discover(options = {}) {
955
+ const params = new URLSearchParams();
956
+ if (options.category) params.set("category", options.category);
957
+ if (options.network) params.set("network", options.network);
958
+ if (options.token) params.set("token", options.token);
959
+ if (options.provider) params.set("provider", options.provider);
960
+ if (options.tags?.length) params.set("tags", options.tags.join(","));
961
+ if (options.query) params.set("query", options.query);
962
+ if (options.maxPrice) params.set("maxPrice", options.maxPrice);
963
+ if (options.page) params.set("page", options.page.toString());
964
+ if (options.limit) params.set("limit", options.limit.toString());
965
+ if (options.sortBy) params.set("sortBy", options.sortBy);
966
+ if (options.sortOrder) params.set("sortOrder", options.sortOrder);
967
+ const url = `${this.baseUrl}/resources${params.toString() ? `?${params}` : ""}`;
968
+ const controller = new AbortController();
969
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
970
+ try {
971
+ const response = await fetch(url, {
972
+ method: "GET",
973
+ headers: { "Accept": "application/json" },
974
+ signal: controller.signal
975
+ });
976
+ clearTimeout(timeoutId);
977
+ if (!response.ok) {
978
+ const errorText = await response.text();
979
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
980
+ }
981
+ return await response.json();
982
+ } catch (error) {
983
+ clearTimeout(timeoutId);
984
+ throw error;
985
+ }
986
+ }
987
+ /**
988
+ * Get a specific resource by ID
989
+ *
990
+ * @param resourceId - Resource ID
991
+ * @returns Resource details
992
+ */
993
+ async getResource(resourceId) {
994
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
995
+ const controller = new AbortController();
996
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
997
+ try {
998
+ const response = await fetch(url, {
999
+ method: "GET",
1000
+ headers: { "Accept": "application/json" },
1001
+ signal: controller.signal
1002
+ });
1003
+ clearTimeout(timeoutId);
1004
+ if (!response.ok) {
1005
+ const errorText = await response.text();
1006
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1007
+ }
1008
+ return await response.json();
1009
+ } catch (error) {
1010
+ clearTimeout(timeoutId);
1011
+ throw error;
1012
+ }
1013
+ }
1014
+ /**
1015
+ * Get a resource by its URL
1016
+ *
1017
+ * @param resourceUrl - Resource URL
1018
+ * @returns Resource details
1019
+ */
1020
+ async getResourceByUrl(resourceUrl) {
1021
+ const url = `${this.baseUrl}/resources/by-url?url=${encodeURIComponent(resourceUrl)}`;
1022
+ const controller = new AbortController();
1023
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1024
+ try {
1025
+ const response = await fetch(url, {
1026
+ method: "GET",
1027
+ headers: { "Accept": "application/json" },
1028
+ signal: controller.signal
1029
+ });
1030
+ clearTimeout(timeoutId);
1031
+ if (!response.ok) {
1032
+ const errorText = await response.text();
1033
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1034
+ }
1035
+ return await response.json();
1036
+ } catch (error) {
1037
+ clearTimeout(timeoutId);
1038
+ throw error;
1039
+ }
1040
+ }
1041
+ /**
1042
+ * Register a new resource in the Bazaar
1043
+ *
1044
+ * Requires API key authentication.
1045
+ *
1046
+ * @param options - Resource registration options
1047
+ * @returns Registered resource
1048
+ *
1049
+ * @example
1050
+ * ```ts
1051
+ * const resource = await bazaar.register({
1052
+ * url: 'https://api.example.com/v1/generate',
1053
+ * name: 'Image Generator API',
1054
+ * description: 'Generate images with AI',
1055
+ * category: 'ai',
1056
+ * networks: ['base', 'ethereum', 'polygon'],
1057
+ * price: '0.05',
1058
+ * payTo: '0x1234...',
1059
+ * tags: ['ai', 'image', 'generator'],
1060
+ * });
1061
+ * ```
1062
+ */
1063
+ async register(options) {
1064
+ if (!this.apiKey) {
1065
+ throw new Error("API key required for resource registration");
1066
+ }
1067
+ const url = `${this.baseUrl}/resources`;
1068
+ const controller = new AbortController();
1069
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1070
+ try {
1071
+ const response = await fetch(url, {
1072
+ method: "POST",
1073
+ headers: {
1074
+ "Content-Type": "application/json",
1075
+ "Accept": "application/json",
1076
+ "Authorization": `Bearer ${this.apiKey}`
1077
+ },
1078
+ body: JSON.stringify({
1079
+ url: options.url,
1080
+ name: options.name,
1081
+ description: options.description,
1082
+ category: options.category,
1083
+ networks: options.networks,
1084
+ tokens: options.tokens || ["USDC"],
1085
+ price: options.price,
1086
+ priceCurrency: options.priceCurrency || "USDC",
1087
+ payTo: options.payTo,
1088
+ mimeType: options.mimeType || "application/json",
1089
+ outputSchema: options.outputSchema,
1090
+ tags: options.tags
1091
+ }),
1092
+ signal: controller.signal
1093
+ });
1094
+ clearTimeout(timeoutId);
1095
+ if (!response.ok) {
1096
+ const errorText = await response.text();
1097
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1098
+ }
1099
+ return await response.json();
1100
+ } catch (error) {
1101
+ clearTimeout(timeoutId);
1102
+ throw error;
1103
+ }
1104
+ }
1105
+ /**
1106
+ * Update an existing resource
1107
+ *
1108
+ * Requires API key authentication. Only the owner can update.
1109
+ *
1110
+ * @param resourceId - Resource ID to update
1111
+ * @param updates - Partial update options
1112
+ * @returns Updated resource
1113
+ */
1114
+ async update(resourceId, updates) {
1115
+ if (!this.apiKey) {
1116
+ throw new Error("API key required for resource update");
1117
+ }
1118
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
1119
+ const controller = new AbortController();
1120
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1121
+ try {
1122
+ const response = await fetch(url, {
1123
+ method: "PATCH",
1124
+ headers: {
1125
+ "Content-Type": "application/json",
1126
+ "Accept": "application/json",
1127
+ "Authorization": `Bearer ${this.apiKey}`
1128
+ },
1129
+ body: JSON.stringify(updates),
1130
+ signal: controller.signal
1131
+ });
1132
+ clearTimeout(timeoutId);
1133
+ if (!response.ok) {
1134
+ const errorText = await response.text();
1135
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1136
+ }
1137
+ return await response.json();
1138
+ } catch (error) {
1139
+ clearTimeout(timeoutId);
1140
+ throw error;
1141
+ }
1142
+ }
1143
+ /**
1144
+ * Delete a resource from the Bazaar
1145
+ *
1146
+ * Requires API key authentication. Only the owner can delete.
1147
+ *
1148
+ * @param resourceId - Resource ID to delete
1149
+ */
1150
+ async delete(resourceId) {
1151
+ if (!this.apiKey) {
1152
+ throw new Error("API key required for resource deletion");
1153
+ }
1154
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}`;
1155
+ const controller = new AbortController();
1156
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1157
+ try {
1158
+ const response = await fetch(url, {
1159
+ method: "DELETE",
1160
+ headers: {
1161
+ "Authorization": `Bearer ${this.apiKey}`
1162
+ },
1163
+ signal: controller.signal
1164
+ });
1165
+ clearTimeout(timeoutId);
1166
+ if (!response.ok) {
1167
+ const errorText = await response.text();
1168
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1169
+ }
1170
+ } catch (error) {
1171
+ clearTimeout(timeoutId);
1172
+ throw error;
1173
+ }
1174
+ }
1175
+ /**
1176
+ * Deactivate a resource (soft delete)
1177
+ *
1178
+ * Requires API key authentication. Only the owner can deactivate.
1179
+ *
1180
+ * @param resourceId - Resource ID to deactivate
1181
+ * @returns Updated resource with isActive: false
1182
+ */
1183
+ async deactivate(resourceId) {
1184
+ if (!this.apiKey) {
1185
+ throw new Error("API key required for resource deactivation");
1186
+ }
1187
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}/deactivate`;
1188
+ const controller = new AbortController();
1189
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1190
+ try {
1191
+ const response = await fetch(url, {
1192
+ method: "POST",
1193
+ headers: {
1194
+ "Authorization": `Bearer ${this.apiKey}`
1195
+ },
1196
+ signal: controller.signal
1197
+ });
1198
+ clearTimeout(timeoutId);
1199
+ if (!response.ok) {
1200
+ const errorText = await response.text();
1201
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1202
+ }
1203
+ return await response.json();
1204
+ } catch (error) {
1205
+ clearTimeout(timeoutId);
1206
+ throw error;
1207
+ }
1208
+ }
1209
+ /**
1210
+ * Reactivate a deactivated resource
1211
+ *
1212
+ * Requires API key authentication. Only the owner can reactivate.
1213
+ *
1214
+ * @param resourceId - Resource ID to reactivate
1215
+ * @returns Updated resource with isActive: true
1216
+ */
1217
+ async reactivate(resourceId) {
1218
+ if (!this.apiKey) {
1219
+ throw new Error("API key required for resource reactivation");
1220
+ }
1221
+ const url = `${this.baseUrl}/resources/${encodeURIComponent(resourceId)}/reactivate`;
1222
+ const controller = new AbortController();
1223
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1224
+ try {
1225
+ const response = await fetch(url, {
1226
+ method: "POST",
1227
+ headers: {
1228
+ "Authorization": `Bearer ${this.apiKey}`
1229
+ },
1230
+ signal: controller.signal
1231
+ });
1232
+ clearTimeout(timeoutId);
1233
+ if (!response.ok) {
1234
+ const errorText = await response.text();
1235
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1236
+ }
1237
+ return await response.json();
1238
+ } catch (error) {
1239
+ clearTimeout(timeoutId);
1240
+ throw error;
1241
+ }
1242
+ }
1243
+ /**
1244
+ * List all resources owned by the authenticated user
1245
+ *
1246
+ * Requires API key authentication.
1247
+ *
1248
+ * @param options - Pagination options
1249
+ * @returns Paginated list of owned resources
1250
+ */
1251
+ async listMyResources(options = {}) {
1252
+ if (!this.apiKey) {
1253
+ throw new Error("API key required to list owned resources");
1254
+ }
1255
+ const params = new URLSearchParams();
1256
+ if (options.page) params.set("page", options.page.toString());
1257
+ if (options.limit) params.set("limit", options.limit.toString());
1258
+ if (options.includeInactive) params.set("includeInactive", "true");
1259
+ const url = `${this.baseUrl}/resources/mine${params.toString() ? `?${params}` : ""}`;
1260
+ const controller = new AbortController();
1261
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1262
+ try {
1263
+ const response = await fetch(url, {
1264
+ method: "GET",
1265
+ headers: {
1266
+ "Accept": "application/json",
1267
+ "Authorization": `Bearer ${this.apiKey}`
1268
+ },
1269
+ signal: controller.signal
1270
+ });
1271
+ clearTimeout(timeoutId);
1272
+ if (!response.ok) {
1273
+ const errorText = await response.text();
1274
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1275
+ }
1276
+ return await response.json();
1277
+ } catch (error) {
1278
+ clearTimeout(timeoutId);
1279
+ throw error;
1280
+ }
1281
+ }
1282
+ /**
1283
+ * Get Bazaar API health status
1284
+ *
1285
+ * @returns True if the Bazaar API is healthy
1286
+ */
1287
+ async healthCheck() {
1288
+ try {
1289
+ const response = await fetch(`${this.baseUrl}/health`, {
1290
+ method: "GET"
1291
+ });
1292
+ return response.ok;
1293
+ } catch {
1294
+ return false;
1295
+ }
1296
+ }
1297
+ /**
1298
+ * Get Bazaar statistics
1299
+ *
1300
+ * @returns Global statistics about the Bazaar
1301
+ */
1302
+ async getStats() {
1303
+ const url = `${this.baseUrl}/stats`;
1304
+ const controller = new AbortController();
1305
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1306
+ try {
1307
+ const response = await fetch(url, {
1308
+ method: "GET",
1309
+ headers: { "Accept": "application/json" },
1310
+ signal: controller.signal
1311
+ });
1312
+ clearTimeout(timeoutId);
1313
+ if (!response.ok) {
1314
+ const errorText = await response.text();
1315
+ throw new Error(`Bazaar API error: ${response.status} - ${errorText}`);
1316
+ }
1317
+ return await response.json();
1318
+ } catch (error) {
1319
+ clearTimeout(timeoutId);
1320
+ throw error;
1321
+ }
1322
+ }
1323
+ };
1324
+ var EscrowClient = class {
1325
+ baseUrl;
1326
+ apiKey;
1327
+ timeout;
1328
+ constructor(options = {}) {
1329
+ this.baseUrl = options.baseUrl || "https://escrow.ultravioletadao.xyz";
1330
+ this.apiKey = options.apiKey;
1331
+ this.timeout = options.timeout || 3e4;
1332
+ }
1333
+ getHeaders(authenticated = false) {
1334
+ const headers = {
1335
+ "Content-Type": "application/json",
1336
+ "Accept": "application/json"
1337
+ };
1338
+ if (authenticated && this.apiKey) {
1339
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
1340
+ }
1341
+ return headers;
1342
+ }
1343
+ /**
1344
+ * Create an escrow payment
1345
+ *
1346
+ * Holds the payment in escrow until released or refunded.
1347
+ *
1348
+ * @param options - Escrow creation options
1349
+ * @returns Created escrow payment
1350
+ */
1351
+ async createEscrow(options) {
1352
+ const url = `${this.baseUrl}/escrow`;
1353
+ const controller = new AbortController();
1354
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1355
+ try {
1356
+ const response = await fetch(url, {
1357
+ method: "POST",
1358
+ headers: this.getHeaders(true),
1359
+ body: JSON.stringify({
1360
+ paymentHeader: options.paymentHeader,
1361
+ paymentRequirements: options.requirements,
1362
+ escrowDuration: options.escrowDuration || 86400,
1363
+ releaseConditions: options.releaseConditions
1364
+ }),
1365
+ signal: controller.signal
1366
+ });
1367
+ clearTimeout(timeoutId);
1368
+ if (!response.ok) {
1369
+ const errorText = await response.text();
1370
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1371
+ }
1372
+ return await response.json();
1373
+ } catch (error) {
1374
+ clearTimeout(timeoutId);
1375
+ throw error;
1376
+ }
1377
+ }
1378
+ /**
1379
+ * Get escrow payment by ID
1380
+ *
1381
+ * @param escrowId - Escrow payment ID
1382
+ * @returns Escrow payment details
1383
+ */
1384
+ async getEscrow(escrowId) {
1385
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}`;
1386
+ const controller = new AbortController();
1387
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1388
+ try {
1389
+ const response = await fetch(url, {
1390
+ method: "GET",
1391
+ headers: this.getHeaders(),
1392
+ signal: controller.signal
1393
+ });
1394
+ clearTimeout(timeoutId);
1395
+ if (!response.ok) {
1396
+ const errorText = await response.text();
1397
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1398
+ }
1399
+ return await response.json();
1400
+ } catch (error) {
1401
+ clearTimeout(timeoutId);
1402
+ throw error;
1403
+ }
1404
+ }
1405
+ /**
1406
+ * Release escrow funds to recipient
1407
+ *
1408
+ * Call this after service has been successfully provided.
1409
+ *
1410
+ * @param escrowId - Escrow payment ID
1411
+ * @returns Updated escrow payment with transaction hash
1412
+ */
1413
+ async release(escrowId) {
1414
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/release`;
1415
+ const controller = new AbortController();
1416
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1417
+ try {
1418
+ const response = await fetch(url, {
1419
+ method: "POST",
1420
+ headers: this.getHeaders(true),
1421
+ signal: controller.signal
1422
+ });
1423
+ clearTimeout(timeoutId);
1424
+ if (!response.ok) {
1425
+ const errorText = await response.text();
1426
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1427
+ }
1428
+ return await response.json();
1429
+ } catch (error) {
1430
+ clearTimeout(timeoutId);
1431
+ throw error;
1432
+ }
1433
+ }
1434
+ /**
1435
+ * Request a refund for an escrow payment
1436
+ *
1437
+ * Initiates a refund request that must be approved.
1438
+ *
1439
+ * @param options - Refund request options
1440
+ * @returns Created refund request
1441
+ */
1442
+ async requestRefund(options) {
1443
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(options.escrowId)}/refund`;
1444
+ const controller = new AbortController();
1445
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1446
+ try {
1447
+ const response = await fetch(url, {
1448
+ method: "POST",
1449
+ headers: this.getHeaders(true),
1450
+ body: JSON.stringify({
1451
+ reason: options.reason,
1452
+ amount: options.amount,
1453
+ evidence: options.evidence
1454
+ }),
1455
+ signal: controller.signal
1456
+ });
1457
+ clearTimeout(timeoutId);
1458
+ if (!response.ok) {
1459
+ const errorText = await response.text();
1460
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1461
+ }
1462
+ return await response.json();
1463
+ } catch (error) {
1464
+ clearTimeout(timeoutId);
1465
+ throw error;
1466
+ }
1467
+ }
1468
+ /**
1469
+ * Approve a refund request (for recipients)
1470
+ *
1471
+ * @param refundId - Refund request ID
1472
+ * @param amount - Amount to approve (may be less than requested)
1473
+ * @returns Updated refund request
1474
+ */
1475
+ async approveRefund(refundId, amount) {
1476
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/approve`;
1477
+ const controller = new AbortController();
1478
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1479
+ try {
1480
+ const response = await fetch(url, {
1481
+ method: "POST",
1482
+ headers: this.getHeaders(true),
1483
+ body: JSON.stringify({ amount }),
1484
+ signal: controller.signal
1485
+ });
1486
+ clearTimeout(timeoutId);
1487
+ if (!response.ok) {
1488
+ const errorText = await response.text();
1489
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1490
+ }
1491
+ return await response.json();
1492
+ } catch (error) {
1493
+ clearTimeout(timeoutId);
1494
+ throw error;
1495
+ }
1496
+ }
1497
+ /**
1498
+ * Reject a refund request (for recipients)
1499
+ *
1500
+ * @param refundId - Refund request ID
1501
+ * @param reason - Reason for rejection
1502
+ * @returns Updated refund request
1503
+ */
1504
+ async rejectRefund(refundId, reason) {
1505
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/reject`;
1506
+ const controller = new AbortController();
1507
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1508
+ try {
1509
+ const response = await fetch(url, {
1510
+ method: "POST",
1511
+ headers: this.getHeaders(true),
1512
+ body: JSON.stringify({ reason }),
1513
+ signal: controller.signal
1514
+ });
1515
+ clearTimeout(timeoutId);
1516
+ if (!response.ok) {
1517
+ const errorText = await response.text();
1518
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1519
+ }
1520
+ return await response.json();
1521
+ } catch (error) {
1522
+ clearTimeout(timeoutId);
1523
+ throw error;
1524
+ }
1525
+ }
1526
+ /**
1527
+ * Get refund request by ID
1528
+ *
1529
+ * @param refundId - Refund request ID
1530
+ * @returns Refund request details
1531
+ */
1532
+ async getRefund(refundId) {
1533
+ const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}`;
1534
+ const controller = new AbortController();
1535
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1536
+ try {
1537
+ const response = await fetch(url, {
1538
+ method: "GET",
1539
+ headers: this.getHeaders(),
1540
+ signal: controller.signal
1541
+ });
1542
+ clearTimeout(timeoutId);
1543
+ if (!response.ok) {
1544
+ const errorText = await response.text();
1545
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1546
+ }
1547
+ return await response.json();
1548
+ } catch (error) {
1549
+ clearTimeout(timeoutId);
1550
+ throw error;
1551
+ }
1552
+ }
1553
+ /**
1554
+ * Open a dispute for an escrow payment
1555
+ *
1556
+ * Initiates arbitration when payer and recipient disagree.
1557
+ *
1558
+ * @param escrowId - Escrow payment ID
1559
+ * @param reason - Reason for dispute
1560
+ * @param evidence - Supporting evidence
1561
+ * @returns Created dispute
1562
+ */
1563
+ async openDispute(escrowId, reason, evidence) {
1564
+ const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/dispute`;
1565
+ const controller = new AbortController();
1566
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1567
+ try {
1568
+ const response = await fetch(url, {
1569
+ method: "POST",
1570
+ headers: this.getHeaders(true),
1571
+ body: JSON.stringify({ reason, evidence }),
1572
+ signal: controller.signal
1573
+ });
1574
+ clearTimeout(timeoutId);
1575
+ if (!response.ok) {
1576
+ const errorText = await response.text();
1577
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1578
+ }
1579
+ return await response.json();
1580
+ } catch (error) {
1581
+ clearTimeout(timeoutId);
1582
+ throw error;
1583
+ }
1584
+ }
1585
+ /**
1586
+ * Submit evidence to a dispute
1587
+ *
1588
+ * @param disputeId - Dispute ID
1589
+ * @param evidence - Evidence to submit
1590
+ * @returns Updated dispute
1591
+ */
1592
+ async submitEvidence(disputeId, evidence) {
1593
+ const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}/evidence`;
1594
+ const controller = new AbortController();
1595
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1596
+ try {
1597
+ const response = await fetch(url, {
1598
+ method: "POST",
1599
+ headers: this.getHeaders(true),
1600
+ body: JSON.stringify({ evidence }),
1601
+ signal: controller.signal
1602
+ });
1603
+ clearTimeout(timeoutId);
1604
+ if (!response.ok) {
1605
+ const errorText = await response.text();
1606
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1607
+ }
1608
+ return await response.json();
1609
+ } catch (error) {
1610
+ clearTimeout(timeoutId);
1611
+ throw error;
1612
+ }
1613
+ }
1614
+ /**
1615
+ * Get dispute by ID
1616
+ *
1617
+ * @param disputeId - Dispute ID
1618
+ * @returns Dispute details
1619
+ */
1620
+ async getDispute(disputeId) {
1621
+ const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}`;
1622
+ const controller = new AbortController();
1623
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1624
+ try {
1625
+ const response = await fetch(url, {
1626
+ method: "GET",
1627
+ headers: this.getHeaders(),
1628
+ signal: controller.signal
1629
+ });
1630
+ clearTimeout(timeoutId);
1631
+ if (!response.ok) {
1632
+ const errorText = await response.text();
1633
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1634
+ }
1635
+ return await response.json();
1636
+ } catch (error) {
1637
+ clearTimeout(timeoutId);
1638
+ throw error;
1639
+ }
1640
+ }
1641
+ /**
1642
+ * List escrow payments (with filters)
1643
+ *
1644
+ * @param options - Filter and pagination options
1645
+ * @returns Paginated list of escrow payments
1646
+ */
1647
+ async listEscrows(options = {}) {
1648
+ const params = new URLSearchParams();
1649
+ if (options.status) params.set("status", options.status);
1650
+ if (options.payer) params.set("payer", options.payer);
1651
+ if (options.recipient) params.set("recipient", options.recipient);
1652
+ if (options.page) params.set("page", options.page.toString());
1653
+ if (options.limit) params.set("limit", options.limit.toString());
1654
+ const url = `${this.baseUrl}/escrow${params.toString() ? `?${params}` : ""}`;
1655
+ const controller = new AbortController();
1656
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1657
+ try {
1658
+ const response = await fetch(url, {
1659
+ method: "GET",
1660
+ headers: this.getHeaders(true),
1661
+ signal: controller.signal
1662
+ });
1663
+ clearTimeout(timeoutId);
1664
+ if (!response.ok) {
1665
+ const errorText = await response.text();
1666
+ throw new Error(`Escrow API error: ${response.status} - ${errorText}`);
1667
+ }
1668
+ return await response.json();
1669
+ } catch (error) {
1670
+ clearTimeout(timeoutId);
1671
+ throw error;
1672
+ }
1673
+ }
1674
+ /**
1675
+ * Check Escrow API health
1676
+ *
1677
+ * @returns True if healthy
1678
+ */
1679
+ async healthCheck() {
1680
+ try {
1681
+ const response = await fetch(`${this.baseUrl}/health`, {
1682
+ method: "GET"
1683
+ });
1684
+ return response.ok;
1685
+ } catch {
1686
+ return false;
1687
+ }
1688
+ }
1689
+ };
1690
+ function canReleaseEscrow(escrow) {
1691
+ if (escrow.status !== "held") {
1692
+ return false;
1693
+ }
1694
+ if (new Date(escrow.expiresAt) < /* @__PURE__ */ new Date()) {
1695
+ return false;
1696
+ }
1697
+ if (escrow.releaseConditions?.minHoldTime) {
1698
+ const createdAt = new Date(escrow.createdAt);
1699
+ const minReleaseTime = new Date(
1700
+ createdAt.getTime() + escrow.releaseConditions.minHoldTime * 1e3
1701
+ );
1702
+ if (/* @__PURE__ */ new Date() < minReleaseTime) {
1703
+ return false;
1704
+ }
1705
+ }
1706
+ return true;
1707
+ }
1708
+ function canRefundEscrow(escrow) {
1709
+ return escrow.status === "held" || escrow.status === "pending";
1710
+ }
1711
+ function isEscrowExpired(escrow) {
1712
+ return new Date(escrow.expiresAt) < /* @__PURE__ */ new Date();
1713
+ }
1714
+ function escrowTimeRemaining(escrow) {
1715
+ return new Date(escrow.expiresAt).getTime() - Date.now();
1716
+ }
1717
+
1718
+ export { BazaarClient, EscrowClient, FacilitatorClient, X402_CORS_HEADERS, X402_HEADER_NAMES, buildPaymentRequirements, buildSettleRequest, buildVerifyRequest, canRefundEscrow, canReleaseEscrow, create402Response, createPaymentMiddleware, escrowTimeRemaining, extractPaymentFromHeaders, getCorsHeaders, isEscrowExpired, parsePaymentHeader };
1719
+ //# sourceMappingURL=index.mjs.map
1720
+ //# sourceMappingURL=index.mjs.map