uvd-x402-sdk 2.5.0 → 2.10.0

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