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