Skip to main content

datamaxi/
generated.rs

1// Code generated by datamaxi-codegen. DO NOT EDIT.
2
3use crate::api::{Client, Config, Datamaxi, Result};
4use std::collections::HashMap;
5use serde::Deserialize;
6
7// --- Announcements ---
8
9#[derive(Clone)]
10pub struct Announcements {
11    pub client: Client,
12}
13
14impl Datamaxi for Announcements {
15    fn new(api_key: String) -> Announcements {
16        let config = Config { base_url: None, api_key };
17        Announcements { client: Client::new(config) }
18    }
19    fn new_with_base_url(api_key: String, base_url: String) -> Announcements {
20        let config = Config { base_url: Some(base_url), api_key };
21        Announcements { client: Client::new(config) }
22    }
23}
24
25impl Announcements {
26    /// Get latest announcements from centralized exchanges
27    pub fn announcements(&self, options: CexAnnouncementsOptions) -> Result<serde_json::Value> {
28        let mut parameters = HashMap::new();
29        if let Some(v) = options.page {
30            parameters.insert("page".to_string(), v.to_string());
31        }
32        if let Some(v) = options.limit {
33            parameters.insert("limit".to_string(), v.to_string());
34        }
35        if let Some(v) = options.sort {
36            parameters.insert("sort".to_string(), v.to_string());
37        }
38        if let Some(v) = options.key {
39            parameters.insert("key".to_string(), v.to_string());
40        }
41        if let Some(v) = options.exchange {
42            parameters.insert("exchange".to_string(), v.to_string());
43        }
44        if let Some(v) = options.category {
45            parameters.insert("category".to_string(), v.to_string());
46        }
47        self.client.get("/cex/announcements", Some(parameters))
48    }
49
50}
51
52pub struct CexAnnouncementsOptions {
53    pub page: Option<i64>,
54    pub limit: Option<i64>,
55    pub sort: Option<String>,
56    pub key: Option<String>,
57    pub exchange: Option<String>,
58    pub category: Option<String>,
59}
60
61impl CexAnnouncementsOptions {
62    pub fn new() -> Self {
63        CexAnnouncementsOptions {
64            page: None,
65            limit: None,
66            sort: None,
67            key: None,
68            exchange: None,
69            category: None,
70        }
71    }
72
73    pub fn page(mut self, page: i64) -> Self {
74        self.page = Some(page);
75        self
76    }
77
78    pub fn limit(mut self, limit: i64) -> Self {
79        self.limit = Some(limit);
80        self
81    }
82
83    pub fn sort(mut self, sort: impl Into<String>) -> Self {
84        self.sort = Some(sort.into());
85        self
86    }
87
88    pub fn key(mut self, key: impl Into<String>) -> Self {
89        self.key = Some(key.into());
90        self
91    }
92
93    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
94        self.exchange = Some(exchange.into());
95        self
96    }
97
98    pub fn category(mut self, category: impl Into<String>) -> Self {
99        self.category = Some(category.into());
100        self
101    }
102
103}
104
105// --- CexCandle ---
106
107#[derive(Clone)]
108pub struct CexCandle {
109    pub client: Client,
110}
111
112impl Datamaxi for CexCandle {
113    fn new(api_key: String) -> CexCandle {
114        let config = Config { base_url: None, api_key };
115        CexCandle { client: Client::new(config) }
116    }
117    fn new_with_base_url(api_key: String, base_url: String) -> CexCandle {
118        let config = Config { base_url: Some(base_url), api_key };
119        CexCandle { client: Client::new(config) }
120    }
121}
122
123impl CexCandle {
124    /// Get historical candle data for a given `exchange`, `symbol`, `interval` and `market`.
125    pub fn get(&self, exchange: impl Into<String>, market: impl Into<String>, symbol: impl Into<String>, options: CexCandleOptions) -> Result<serde_json::Value> {
126        let mut parameters = HashMap::new();
127        parameters.insert("exchange".to_string(), exchange.into());
128        parameters.insert("market".to_string(), market.into());
129        parameters.insert("symbol".to_string(), symbol.into());
130        if let Some(v) = options.currency {
131            parameters.insert("currency".to_string(), v.to_string());
132        }
133        if let Some(v) = options.interval {
134            parameters.insert("interval".to_string(), v.to_string());
135        }
136        if let Some(v) = options.from {
137            parameters.insert("from".to_string(), v.to_string());
138        }
139        if let Some(v) = options.to {
140            parameters.insert("to".to_string(), v.to_string());
141        }
142        self.client.get("/cex/candle", Some(parameters))
143    }
144
145    /// Get supported exchanges accepted by `/api/v1/cex/candle` endpoint.
146    pub fn exchanges(&self, market: impl Into<String>) -> Result<serde_json::Value> {
147        let mut parameters = HashMap::new();
148        parameters.insert("market".to_string(), market.into());
149        self.client.get("/cex/candle/exchanges", Some(parameters))
150    }
151
152    /// Fetch supported intervals accepted by `/api/v1/cex/candle` endpoint.
153    pub fn intervals(&self) -> Result<serde_json::Value> {
154        self.client.get("/cex/candle/intervals", None)
155    }
156
157    /// Fetch supported symbols accepted by `/api/v1/cex/candle` endpoint.
158    pub fn symbols(&self, options: CexCandleSymbolsOptions) -> Result<serde_json::Value> {
159        let mut parameters = HashMap::new();
160        if let Some(v) = options.exchange {
161            parameters.insert("exchange".to_string(), v.to_string());
162        }
163        if let Some(v) = options.market {
164            parameters.insert("market".to_string(), v.to_string());
165        }
166        self.client.get("/cex/candle/symbols", Some(parameters))
167    }
168
169}
170
171pub struct CexCandleOptions {
172    pub currency: Option<String>,
173    pub interval: Option<String>,
174    pub from: Option<String>,
175    pub to: Option<String>,
176}
177
178impl CexCandleOptions {
179    pub fn new() -> Self {
180        CexCandleOptions {
181            currency: None,
182            interval: None,
183            from: None,
184            to: None,
185        }
186    }
187
188    pub fn currency(mut self, currency: impl Into<String>) -> Self {
189        self.currency = Some(currency.into());
190        self
191    }
192
193    pub fn interval(mut self, interval: impl Into<String>) -> Self {
194        self.interval = Some(interval.into());
195        self
196    }
197
198    pub fn from(mut self, from: impl Into<String>) -> Self {
199        self.from = Some(from.into());
200        self
201    }
202
203    pub fn to(mut self, to: impl Into<String>) -> Self {
204        self.to = Some(to.into());
205        self
206    }
207
208}
209
210pub struct CexCandleSymbolsOptions {
211    pub exchange: Option<String>,
212    pub market: Option<String>,
213}
214
215impl CexCandleSymbolsOptions {
216    pub fn new() -> Self {
217        CexCandleSymbolsOptions {
218            exchange: None,
219            market: None,
220        }
221    }
222
223    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
224        self.exchange = Some(exchange.into());
225        self
226    }
227
228    pub fn market(mut self, market: impl Into<String>) -> Self {
229        self.market = Some(market.into());
230        self
231    }
232
233}
234
235// --- CexSymbol ---
236
237#[derive(Clone)]
238pub struct CexSymbol {
239    pub client: Client,
240}
241
242impl Datamaxi for CexSymbol {
243    fn new(api_key: String) -> CexSymbol {
244        let config = Config { base_url: None, api_key };
245        CexSymbol { client: Client::new(config) }
246    }
247    fn new_with_base_url(api_key: String, base_url: String) -> CexSymbol {
248        let config = Config { base_url: Some(base_url), api_key };
249        CexSymbol { client: Client::new(config) }
250    }
251}
252
253impl CexSymbol {
254    /// Return currently-active caution/warning/danger flagged symbols. Bithumb provides an expiry (end_at); other exchanges are open-ended until the next collector poll clears them.
255    pub fn cautions(&self, options: CexSymbolCautionsOptions) -> Result<serde_json::Value> {
256        let mut parameters = HashMap::new();
257        if let Some(v) = options.exchange {
258            parameters.insert("exchange".to_string(), v.to_string());
259        }
260        if let Some(v) = options.market {
261            parameters.insert("market".to_string(), v.to_string());
262        }
263        if let Some(v) = options.min_level {
264            parameters.insert("min_level".to_string(), v.to_string());
265        }
266        if let Some(v) = options.active_only {
267            parameters.insert("active_only".to_string(), v.to_string());
268        }
269        if let Some(v) = options.limit {
270            parameters.insert("limit".to_string(), v.to_string());
271        }
272        if let Some(v) = options.page {
273            parameters.insert("page".to_string(), v.to_string());
274        }
275        self.client.get("/cex/symbol/cautions", Some(parameters))
276    }
277
278    /// Return symbols with a known delisting_at timestamp or trading_status in {delisting, delisted}. Filter by time window to get upcoming delistings.
279    pub fn delistings(&self, options: CexSymbolDelistingsOptions) -> Result<serde_json::Value> {
280        let mut parameters = HashMap::new();
281        if let Some(v) = options.exchange {
282            parameters.insert("exchange".to_string(), v.to_string());
283        }
284        if let Some(v) = options.market {
285            parameters.insert("market".to_string(), v.to_string());
286        }
287        if let Some(v) = options.from_ms {
288            parameters.insert("from_ms".to_string(), v.to_string());
289        }
290        if let Some(v) = options.to_ms {
291            parameters.insert("to_ms".to_string(), v.to_string());
292        }
293        if let Some(v) = options.include_past {
294            parameters.insert("include_past".to_string(), v.to_string());
295        }
296        if let Some(v) = options.limit {
297            parameters.insert("limit".to_string(), v.to_string());
298        }
299        if let Some(v) = options.page {
300            parameters.insert("page".to_string(), v.to_string());
301        }
302        self.client.get("/cex/symbol/delistings", Some(parameters))
303    }
304
305    /// Sums long/short liquidation volume across all events in a rolling window for every exchange × quote pairing of the base asset. Window max 30d; default 24h.
306    pub fn liquidation(&self, base: impl Into<String>, options: CexSymbolLiquidationOptions) -> Result<serde_json::Value> {
307        let mut parameters = HashMap::new();
308        parameters.insert("base".to_string(), base.into());
309        if let Some(v) = options.window {
310            parameters.insert("window".to_string(), v.to_string());
311        }
312        self.client.get("/cex/symbol/liquidation", Some(parameters))
313    }
314
315    /// Fetch per-symbol trading status, caution flags, tags and timing metadata collected by tfsymbolmeta.
316    pub fn metadata(&self, options: CexSymbolMetadataOptions) -> Result<serde_json::Value> {
317        let mut parameters = HashMap::new();
318        if let Some(v) = options.exchange {
319            parameters.insert("exchange".to_string(), v.to_string());
320        }
321        if let Some(v) = options.market {
322            parameters.insert("market".to_string(), v.to_string());
323        }
324        if let Some(v) = options.base {
325            parameters.insert("base".to_string(), v.to_string());
326        }
327        if let Some(v) = options.quote {
328            parameters.insert("quote".to_string(), v.to_string());
329        }
330        if let Some(v) = options.status {
331            parameters.insert("status".to_string(), v.to_string());
332        }
333        if let Some(v) = options.limit {
334            parameters.insert("limit".to_string(), v.to_string());
335        }
336        if let Some(v) = options.page {
337            parameters.insert("page".to_string(), v.to_string());
338        }
339        self.client.get("/cex/symbol/metadata", Some(parameters))
340    }
341
342    /// Latest Open Interest snapshot across every futures venue carrying the given base. Sorted by USD value descending, NULLs last.
343    pub fn oi(&self, base: impl Into<String>, options: CexSymbolOiOptions) -> Result<serde_json::Value> {
344        let mut parameters = HashMap::new();
345        parameters.insert("base".to_string(), base.into());
346        if let Some(v) = options.exchange {
347            parameters.insert("exchange".to_string(), v.to_string());
348        }
349        self.client.get("/cex/symbol/oi", Some(parameters))
350    }
351
352    /// Enriched snapshot combining the latest OI (USD) with 1h/4h/24h change percentages and OI/24h volume ratio. Backed by the tfopeninterest taskflow's Redis HASH.
353    pub fn oi_stats(&self, base: impl Into<String>, options: CexSymbolOiStatsOptions) -> Result<serde_json::Value> {
354        let mut parameters = HashMap::new();
355        parameters.insert("base".to_string(), base.into());
356        if let Some(v) = options.exchange {
357            parameters.insert("exchange".to_string(), v.to_string());
358        }
359        if let Some(v) = options.currency {
360            parameters.insert("currency".to_string(), v.to_string());
361        }
362        self.client.get("/cex/symbol/oi-stats", Some(parameters))
363    }
364
365    /// Fetch (exchange, market, base, quote, tag) rows from cex_symbol_tag. Use to find every symbol flagged with a given tag (e.g. all meme coins across exchanges).
366    pub fn tags(&self, options: CexSymbolTagsOptions) -> Result<serde_json::Value> {
367        let mut parameters = HashMap::new();
368        if let Some(v) = options.tag {
369            parameters.insert("tag".to_string(), v.to_string());
370        }
371        if let Some(v) = options.exchange {
372            parameters.insert("exchange".to_string(), v.to_string());
373        }
374        if let Some(v) = options.market {
375            parameters.insert("market".to_string(), v.to_string());
376        }
377        if let Some(v) = options.base {
378            parameters.insert("base".to_string(), v.to_string());
379        }
380        if let Some(v) = options.source {
381            parameters.insert("source".to_string(), v.to_string());
382        }
383        if let Some(v) = options.min_confidence {
384            parameters.insert("min_confidence".to_string(), v.to_string());
385        }
386        if let Some(v) = options.limit {
387            parameters.insert("limit".to_string(), v.to_string());
388        }
389        if let Some(v) = options.page {
390            parameters.insert("page".to_string(), v.to_string());
391        }
392        self.client.get("/cex/symbol/tags", Some(parameters))
393    }
394
395    /// Latest 24h trading volume across every (exchange, market, quote) a token lists on. Backed by cache.latest_volume.
396    pub fn volume(&self, base: impl Into<String>, options: CexSymbolVolumeOptions) -> Result<serde_json::Value> {
397        let mut parameters = HashMap::new();
398        parameters.insert("base".to_string(), base.into());
399        if let Some(v) = options.market {
400            parameters.insert("market".to_string(), v.to_string());
401        }
402        self.client.get("/cex/symbol/volume", Some(parameters))
403    }
404
405}
406
407pub struct CexSymbolCautionsOptions {
408    pub exchange: Option<String>,
409    pub market: Option<String>,
410    pub min_level: Option<String>,
411    pub active_only: Option<bool>,
412    pub limit: Option<i64>,
413    pub page: Option<i64>,
414}
415
416impl CexSymbolCautionsOptions {
417    pub fn new() -> Self {
418        CexSymbolCautionsOptions {
419            exchange: None,
420            market: None,
421            min_level: None,
422            active_only: None,
423            limit: None,
424            page: None,
425        }
426    }
427
428    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
429        self.exchange = Some(exchange.into());
430        self
431    }
432
433    pub fn market(mut self, market: impl Into<String>) -> Self {
434        self.market = Some(market.into());
435        self
436    }
437
438    pub fn min_level(mut self, min_level: impl Into<String>) -> Self {
439        self.min_level = Some(min_level.into());
440        self
441    }
442
443    pub fn active_only(mut self, active_only: bool) -> Self {
444        self.active_only = Some(active_only);
445        self
446    }
447
448    pub fn limit(mut self, limit: i64) -> Self {
449        self.limit = Some(limit);
450        self
451    }
452
453    pub fn page(mut self, page: i64) -> Self {
454        self.page = Some(page);
455        self
456    }
457
458}
459
460pub struct CexSymbolDelistingsOptions {
461    pub exchange: Option<String>,
462    pub market: Option<String>,
463    pub from_ms: Option<i64>,
464    pub to_ms: Option<i64>,
465    pub include_past: Option<bool>,
466    pub limit: Option<i64>,
467    pub page: Option<i64>,
468}
469
470impl CexSymbolDelistingsOptions {
471    pub fn new() -> Self {
472        CexSymbolDelistingsOptions {
473            exchange: None,
474            market: None,
475            from_ms: None,
476            to_ms: None,
477            include_past: None,
478            limit: None,
479            page: None,
480        }
481    }
482
483    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
484        self.exchange = Some(exchange.into());
485        self
486    }
487
488    pub fn market(mut self, market: impl Into<String>) -> Self {
489        self.market = Some(market.into());
490        self
491    }
492
493    pub fn from_ms(mut self, from_ms: i64) -> Self {
494        self.from_ms = Some(from_ms);
495        self
496    }
497
498    pub fn to_ms(mut self, to_ms: i64) -> Self {
499        self.to_ms = Some(to_ms);
500        self
501    }
502
503    pub fn include_past(mut self, include_past: bool) -> Self {
504        self.include_past = Some(include_past);
505        self
506    }
507
508    pub fn limit(mut self, limit: i64) -> Self {
509        self.limit = Some(limit);
510        self
511    }
512
513    pub fn page(mut self, page: i64) -> Self {
514        self.page = Some(page);
515        self
516    }
517
518}
519
520pub struct CexSymbolLiquidationOptions {
521    pub window: Option<String>,
522}
523
524impl CexSymbolLiquidationOptions {
525    pub fn new() -> Self {
526        CexSymbolLiquidationOptions {
527            window: None,
528        }
529    }
530
531    pub fn window(mut self, window: impl Into<String>) -> Self {
532        self.window = Some(window.into());
533        self
534    }
535
536}
537
538pub struct CexSymbolMetadataOptions {
539    pub exchange: Option<String>,
540    pub market: Option<String>,
541    pub base: Option<String>,
542    pub quote: Option<String>,
543    pub status: Option<String>,
544    pub limit: Option<i64>,
545    pub page: Option<i64>,
546}
547
548impl CexSymbolMetadataOptions {
549    pub fn new() -> Self {
550        CexSymbolMetadataOptions {
551            exchange: None,
552            market: None,
553            base: None,
554            quote: None,
555            status: None,
556            limit: None,
557            page: None,
558        }
559    }
560
561    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
562        self.exchange = Some(exchange.into());
563        self
564    }
565
566    pub fn market(mut self, market: impl Into<String>) -> Self {
567        self.market = Some(market.into());
568        self
569    }
570
571    pub fn base(mut self, base: impl Into<String>) -> Self {
572        self.base = Some(base.into());
573        self
574    }
575
576    pub fn quote(mut self, quote: impl Into<String>) -> Self {
577        self.quote = Some(quote.into());
578        self
579    }
580
581    pub fn status(mut self, status: impl Into<String>) -> Self {
582        self.status = Some(status.into());
583        self
584    }
585
586    pub fn limit(mut self, limit: i64) -> Self {
587        self.limit = Some(limit);
588        self
589    }
590
591    pub fn page(mut self, page: i64) -> Self {
592        self.page = Some(page);
593        self
594    }
595
596}
597
598pub struct CexSymbolOiOptions {
599    pub exchange: Option<String>,
600}
601
602impl CexSymbolOiOptions {
603    pub fn new() -> Self {
604        CexSymbolOiOptions {
605            exchange: None,
606        }
607    }
608
609    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
610        self.exchange = Some(exchange.into());
611        self
612    }
613
614}
615
616pub struct CexSymbolOiStatsOptions {
617    pub exchange: Option<String>,
618    pub currency: Option<String>,
619}
620
621impl CexSymbolOiStatsOptions {
622    pub fn new() -> Self {
623        CexSymbolOiStatsOptions {
624            exchange: None,
625            currency: None,
626        }
627    }
628
629    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
630        self.exchange = Some(exchange.into());
631        self
632    }
633
634    pub fn currency(mut self, currency: impl Into<String>) -> Self {
635        self.currency = Some(currency.into());
636        self
637    }
638
639}
640
641pub struct CexSymbolTagsOptions {
642    pub tag: Option<String>,
643    pub exchange: Option<String>,
644    pub market: Option<String>,
645    pub base: Option<String>,
646    pub source: Option<String>,
647    pub min_confidence: Option<i64>,
648    pub limit: Option<i64>,
649    pub page: Option<i64>,
650}
651
652impl CexSymbolTagsOptions {
653    pub fn new() -> Self {
654        CexSymbolTagsOptions {
655            tag: None,
656            exchange: None,
657            market: None,
658            base: None,
659            source: None,
660            min_confidence: None,
661            limit: None,
662            page: None,
663        }
664    }
665
666    pub fn tag(mut self, tag: impl Into<String>) -> Self {
667        self.tag = Some(tag.into());
668        self
669    }
670
671    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
672        self.exchange = Some(exchange.into());
673        self
674    }
675
676    pub fn market(mut self, market: impl Into<String>) -> Self {
677        self.market = Some(market.into());
678        self
679    }
680
681    pub fn base(mut self, base: impl Into<String>) -> Self {
682        self.base = Some(base.into());
683        self
684    }
685
686    pub fn source(mut self, source: impl Into<String>) -> Self {
687        self.source = Some(source.into());
688        self
689    }
690
691    pub fn min_confidence(mut self, min_confidence: i64) -> Self {
692        self.min_confidence = Some(min_confidence);
693        self
694    }
695
696    pub fn limit(mut self, limit: i64) -> Self {
697        self.limit = Some(limit);
698        self
699    }
700
701    pub fn page(mut self, page: i64) -> Self {
702        self.page = Some(page);
703        self
704    }
705
706}
707
708pub struct CexSymbolVolumeOptions {
709    pub market: Option<String>,
710}
711
712impl CexSymbolVolumeOptions {
713    pub fn new() -> Self {
714        CexSymbolVolumeOptions {
715            market: None,
716        }
717    }
718
719    pub fn market(mut self, market: impl Into<String>) -> Self {
720        self.market = Some(market.into());
721        self
722    }
723
724}
725
726// --- Dex ---
727
728#[derive(Clone)]
729pub struct Dex {
730    pub client: Client,
731}
732
733impl Datamaxi for Dex {
734    fn new(api_key: String) -> Dex {
735        let config = Config { base_url: None, api_key };
736        Dex { client: Client::new(config) }
737    }
738    fn new_with_base_url(api_key: String, base_url: String) -> Dex {
739        let config = Config { base_url: Some(base_url), api_key };
740        Dex { client: Client::new(config) }
741    }
742}
743
744impl Dex {
745    /// Fetch historical candle data for a given `chain`, `exchange`, `pool` and `interval`.
746    pub fn candle(&self, chain: impl Into<String>, exchange: impl Into<String>, pool: impl Into<String>, options: DexCandleOptions) -> Result<serde_json::Value> {
747        let mut parameters = HashMap::new();
748        parameters.insert("chain".to_string(), chain.into());
749        parameters.insert("exchange".to_string(), exchange.into());
750        parameters.insert("pool".to_string(), pool.into());
751        if let Some(v) = options.interval {
752            parameters.insert("interval".to_string(), v.to_string());
753        }
754        if let Some(v) = options.from {
755            parameters.insert("from".to_string(), v.to_string());
756        }
757        if let Some(v) = options.to {
758            parameters.insert("to".to_string(), v.to_string());
759        }
760        if let Some(v) = options.page {
761            parameters.insert("page".to_string(), v.to_string());
762        }
763        if let Some(v) = options.limit {
764            parameters.insert("limit".to_string(), v.to_string());
765        }
766        if let Some(v) = options.sort {
767            parameters.insert("sort".to_string(), v.to_string());
768        }
769        self.client.get("/dex/candle", Some(parameters))
770    }
771
772    /// Get supported chains accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
773    pub fn chains(&self) -> Result<serde_json::Value> {
774        self.client.get("/dex/chains", None)
775    }
776
777    /// Get supported exchanges accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
778    pub fn exchanges(&self) -> Result<serde_json::Value> {
779        self.client.get("/dex/exchanges", None)
780    }
781
782    /// Get supported intervals accepted by `/api/v1/dex/candle` endpoint.
783    pub fn intervals(&self) -> Result<serde_json::Value> {
784        self.client.get("/dex/intervals", None)
785    }
786
787    /// Get supported pools accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
788    pub fn pools(&self, options: DexPoolsOptions) -> Result<serde_json::Value> {
789        let mut parameters = HashMap::new();
790        if let Some(v) = options.exchange {
791            parameters.insert("exchange".to_string(), v.to_string());
792        }
793        if let Some(v) = options.chain {
794            parameters.insert("chain".to_string(), v.to_string());
795        }
796        self.client.get("/dex/pools", Some(parameters))
797    }
798
799    /// Get historical DEX trade data for a given `exchange` and `symbol`.
800    pub fn trade(&self, chain: impl Into<String>, exchange: impl Into<String>, pool: impl Into<String>, options: DexTradeOptions) -> Result<serde_json::Value> {
801        let mut parameters = HashMap::new();
802        parameters.insert("chain".to_string(), chain.into());
803        parameters.insert("exchange".to_string(), exchange.into());
804        parameters.insert("pool".to_string(), pool.into());
805        if let Some(v) = options.from {
806            parameters.insert("from".to_string(), v.to_string());
807        }
808        if let Some(v) = options.to {
809            parameters.insert("to".to_string(), v.to_string());
810        }
811        if let Some(v) = options.page {
812            parameters.insert("page".to_string(), v.to_string());
813        }
814        if let Some(v) = options.limit {
815            parameters.insert("limit".to_string(), v.to_string());
816        }
817        if let Some(v) = options.sort {
818            parameters.insert("sort".to_string(), v.to_string());
819        }
820        self.client.get("/dex/trade", Some(parameters))
821    }
822
823}
824
825pub struct DexCandleOptions {
826    pub interval: Option<String>,
827    pub from: Option<String>,
828    pub to: Option<String>,
829    pub page: Option<i64>,
830    pub limit: Option<i64>,
831    pub sort: Option<String>,
832}
833
834impl DexCandleOptions {
835    pub fn new() -> Self {
836        DexCandleOptions {
837            interval: None,
838            from: None,
839            to: None,
840            page: None,
841            limit: None,
842            sort: None,
843        }
844    }
845
846    pub fn interval(mut self, interval: impl Into<String>) -> Self {
847        self.interval = Some(interval.into());
848        self
849    }
850
851    pub fn from(mut self, from: impl Into<String>) -> Self {
852        self.from = Some(from.into());
853        self
854    }
855
856    pub fn to(mut self, to: impl Into<String>) -> Self {
857        self.to = Some(to.into());
858        self
859    }
860
861    pub fn page(mut self, page: i64) -> Self {
862        self.page = Some(page);
863        self
864    }
865
866    pub fn limit(mut self, limit: i64) -> Self {
867        self.limit = Some(limit);
868        self
869    }
870
871    pub fn sort(mut self, sort: impl Into<String>) -> Self {
872        self.sort = Some(sort.into());
873        self
874    }
875
876}
877
878pub struct DexPoolsOptions {
879    pub exchange: Option<String>,
880    pub chain: Option<String>,
881}
882
883impl DexPoolsOptions {
884    pub fn new() -> Self {
885        DexPoolsOptions {
886            exchange: None,
887            chain: None,
888        }
889    }
890
891    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
892        self.exchange = Some(exchange.into());
893        self
894    }
895
896    pub fn chain(mut self, chain: impl Into<String>) -> Self {
897        self.chain = Some(chain.into());
898        self
899    }
900
901}
902
903pub struct DexTradeOptions {
904    pub from: Option<String>,
905    pub to: Option<String>,
906    pub page: Option<i64>,
907    pub limit: Option<i64>,
908    pub sort: Option<String>,
909}
910
911impl DexTradeOptions {
912    pub fn new() -> Self {
913        DexTradeOptions {
914            from: None,
915            to: None,
916            page: None,
917            limit: None,
918            sort: None,
919        }
920    }
921
922    pub fn from(mut self, from: impl Into<String>) -> Self {
923        self.from = Some(from.into());
924        self
925    }
926
927    pub fn to(mut self, to: impl Into<String>) -> Self {
928        self.to = Some(to.into());
929        self
930    }
931
932    pub fn page(mut self, page: i64) -> Self {
933        self.page = Some(page);
934        self
935    }
936
937    pub fn limit(mut self, limit: i64) -> Self {
938        self.limit = Some(limit);
939        self
940    }
941
942    pub fn sort(mut self, sort: impl Into<String>) -> Self {
943        self.sort = Some(sort.into());
944        self
945    }
946
947}
948
949// --- Forex ---
950
951#[derive(Clone)]
952pub struct Forex {
953    pub client: Client,
954}
955
956impl Datamaxi for Forex {
957    fn new(api_key: String) -> Forex {
958        let config = Config { base_url: None, api_key };
959        Forex { client: Client::new(config) }
960    }
961    fn new_with_base_url(api_key: String, base_url: String) -> Forex {
962        let config = Config { base_url: Some(base_url), api_key };
963        Forex { client: Client::new(config) }
964    }
965}
966
967impl Forex {
968    /// Get the latest forex rate for given symbol.
969    pub fn get(&self, options: ForexOptions) -> Result<serde_json::Value> {
970        let mut parameters = HashMap::new();
971        if let Some(v) = options.symbol {
972            parameters.insert("symbol".to_string(), v.to_string());
973        }
974        self.client.get("/forex", Some(parameters))
975    }
976
977    /// Get supported forex symbols.
978    pub fn symbols(&self) -> Result<serde_json::Value> {
979        self.client.get("/forex/symbols", None)
980    }
981
982}
983
984pub struct ForexOptions {
985    pub symbol: Option<String>,
986}
987
988impl ForexOptions {
989    pub fn new() -> Self {
990        ForexOptions {
991            symbol: None,
992        }
993    }
994
995    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
996        self.symbol = Some(symbol.into());
997        self
998    }
999
1000}
1001
1002// --- FundingRate ---
1003
1004#[derive(Clone)]
1005pub struct FundingRate {
1006    pub client: Client,
1007}
1008
1009impl Datamaxi for FundingRate {
1010    fn new(api_key: String) -> FundingRate {
1011        let config = Config { base_url: None, api_key };
1012        FundingRate { client: Client::new(config) }
1013    }
1014    fn new_with_base_url(api_key: String, base_url: String) -> FundingRate {
1015        let config = Config { base_url: Some(base_url), api_key };
1016        FundingRate { client: Client::new(config) }
1017    }
1018}
1019
1020impl FundingRate {
1021    /// Get supported exchanges accepted by `/api/v1/funding-rate` endpoint.
1022    pub fn exchanges(&self) -> Result<serde_json::Value> {
1023        self.client.get("/funding-rate/exchanges", None)
1024    }
1025
1026    /// Get historical funding rate data for a given `exchange` and `symbol`.
1027    pub fn history(&self, exchange: impl Into<String>, symbol: impl Into<String>, options: FundingRateHistoryOptions) -> Result<serde_json::Value> {
1028        let mut parameters = HashMap::new();
1029        parameters.insert("exchange".to_string(), exchange.into());
1030        parameters.insert("symbol".to_string(), symbol.into());
1031        if let Some(v) = options.page {
1032            parameters.insert("page".to_string(), v.to_string());
1033        }
1034        if let Some(v) = options.limit {
1035            parameters.insert("limit".to_string(), v.to_string());
1036        }
1037        if let Some(v) = options.from {
1038            parameters.insert("from".to_string(), v.to_string());
1039        }
1040        if let Some(v) = options.to {
1041            parameters.insert("to".to_string(), v.to_string());
1042        }
1043        if let Some(v) = options.sort {
1044            parameters.insert("sort".to_string(), v.to_string());
1045        }
1046        self.client.get("/funding-rate/history", Some(parameters))
1047    }
1048
1049    /// Fetch the latest funding rate data for a given `exchange` and `symbol`.
1050    pub fn latest(&self, exchange: impl Into<String>, symbol: impl Into<String>) -> Result<serde_json::Value> {
1051        let mut parameters = HashMap::new();
1052        parameters.insert("exchange".to_string(), exchange.into());
1053        parameters.insert("symbol".to_string(), symbol.into());
1054        self.client.get("/funding-rate/latest", Some(parameters))
1055    }
1056
1057    /// Fetch supported symbols accepted by `/api/v1/funding-rate` endpoint.
1058    pub fn symbols(&self, exchange: impl Into<String>) -> Result<serde_json::Value> {
1059        let mut parameters = HashMap::new();
1060        parameters.insert("exchange".to_string(), exchange.into());
1061        self.client.get("/funding-rate/symbols", Some(parameters))
1062    }
1063
1064}
1065
1066pub struct FundingRateHistoryOptions {
1067    pub page: Option<String>,
1068    pub limit: Option<String>,
1069    pub from: Option<String>,
1070    pub to: Option<String>,
1071    pub sort: Option<String>,
1072}
1073
1074impl FundingRateHistoryOptions {
1075    pub fn new() -> Self {
1076        FundingRateHistoryOptions {
1077            page: None,
1078            limit: None,
1079            from: None,
1080            to: None,
1081            sort: None,
1082        }
1083    }
1084
1085    pub fn page(mut self, page: impl Into<String>) -> Self {
1086        self.page = Some(page.into());
1087        self
1088    }
1089
1090    pub fn limit(mut self, limit: impl Into<String>) -> Self {
1091        self.limit = Some(limit.into());
1092        self
1093    }
1094
1095    pub fn from(mut self, from: impl Into<String>) -> Self {
1096        self.from = Some(from.into());
1097        self
1098    }
1099
1100    pub fn to(mut self, to: impl Into<String>) -> Self {
1101        self.to = Some(to.into());
1102        self
1103    }
1104
1105    pub fn sort(mut self, sort: impl Into<String>) -> Self {
1106        self.sort = Some(sort.into());
1107        self
1108    }
1109
1110}
1111
1112// --- IndexPrice ---
1113
1114#[derive(Clone)]
1115pub struct IndexPrice {
1116    pub client: Client,
1117}
1118
1119impl Datamaxi for IndexPrice {
1120    fn new(api_key: String) -> IndexPrice {
1121        let config = Config { base_url: None, api_key };
1122        IndexPrice { client: Client::new(config) }
1123    }
1124    fn new_with_base_url(api_key: String, base_url: String) -> IndexPrice {
1125        let config = Config { base_url: Some(base_url), api_key };
1126        IndexPrice { client: Client::new(config) }
1127    }
1128}
1129
1130impl IndexPrice {
1131    /// Get index price
1132    pub fn get(&self, asset: impl Into<String>, options: IndexPriceOptions) -> Result<serde_json::Value> {
1133        let mut parameters = HashMap::new();
1134        parameters.insert("asset".to_string(), asset.into());
1135        if let Some(v) = options.from {
1136            parameters.insert("from".to_string(), v.to_string());
1137        }
1138        if let Some(v) = options.to {
1139            parameters.insert("to".to_string(), v.to_string());
1140        }
1141        if let Some(v) = options.interval {
1142            parameters.insert("interval".to_string(), v.to_string());
1143        }
1144        self.client.get("/index-price", Some(parameters))
1145    }
1146
1147}
1148
1149pub struct IndexPriceOptions {
1150    pub from: Option<String>,
1151    pub to: Option<String>,
1152    pub interval: Option<String>,
1153}
1154
1155impl IndexPriceOptions {
1156    pub fn new() -> Self {
1157        IndexPriceOptions {
1158            from: None,
1159            to: None,
1160            interval: None,
1161        }
1162    }
1163
1164    pub fn from(mut self, from: impl Into<String>) -> Self {
1165        self.from = Some(from.into());
1166        self
1167    }
1168
1169    pub fn to(mut self, to: impl Into<String>) -> Self {
1170        self.to = Some(to.into());
1171        self
1172    }
1173
1174    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1175        self.interval = Some(interval.into());
1176        self
1177    }
1178
1179}
1180
1181// --- Liquidation ---
1182
1183#[derive(Clone)]
1184pub struct Liquidation {
1185    pub client: Client,
1186}
1187
1188impl Datamaxi for Liquidation {
1189    fn new(api_key: String) -> Liquidation {
1190        let config = Config { base_url: None, api_key };
1191        Liquidation { client: Client::new(config) }
1192    }
1193    fn new_with_base_url(api_key: String, base_url: String) -> Liquidation {
1194        let config = Config { base_url: Some(base_url), api_key };
1195        Liquidation { client: Client::new(config) }
1196    }
1197}
1198
1199impl Liquidation {
1200    /// Fetch recent liquidation events for a futures symbol on a given exchange, newest first.
1201    pub fn get(&self, exchange: impl Into<String>, symbol: impl Into<String>, options: LiquidationOptions) -> Result<serde_json::Value> {
1202        let mut parameters = HashMap::new();
1203        parameters.insert("exchange".to_string(), exchange.into());
1204        parameters.insert("symbol".to_string(), symbol.into());
1205        if let Some(v) = options.limit {
1206            parameters.insert("limit".to_string(), v.to_string());
1207        }
1208        self.client.get("/liquidation", Some(parameters))
1209    }
1210
1211    /// Fetch most recent liquidation events across all futures symbols, newest first. Use together with the `/ws/v1/liquidation/feed` firehose for a live feed view.
1212    pub fn feed(&self, options: LiquidationFeedOptions) -> Result<serde_json::Value> {
1213        let mut parameters = HashMap::new();
1214        if let Some(v) = options.exchange {
1215            parameters.insert("exchange".to_string(), v.to_string());
1216        }
1217        if let Some(v) = options.base {
1218            parameters.insert("base".to_string(), v.to_string());
1219        }
1220        if let Some(v) = options.minVolumeUsd {
1221            parameters.insert("minVolumeUsd".to_string(), v.to_string());
1222        }
1223        if let Some(v) = options.limit {
1224            parameters.insert("limit".to_string(), v.to_string());
1225        }
1226        self.client.get("/liquidation/feed", Some(parameters))
1227    }
1228
1229    /// Aggregated long/short liquidation USD by (token, exchange) over a rolling window. Result is cached for ~10s. Sub-1h windows are not supported (in-memory buckets are 30min); use the WS feed for finer granularity.
1230    pub fn heatmap(&self, options: LiquidationHeatmapOptions) -> Result<serde_json::Value> {
1231        let mut parameters = HashMap::new();
1232        if let Some(v) = options.window {
1233            parameters.insert("window".to_string(), v.to_string());
1234        }
1235        if let Some(v) = options.topN {
1236            parameters.insert("topN".to_string(), v.to_string());
1237        }
1238        self.client.get("/liquidation/heatmap", Some(parameters))
1239    }
1240
1241    /// Coinglass-style liquidation map for one perpetual pair. Returns a price-grid breakdown of where leveraged positions would be liquidated, split by leverage tier (10x / 25x / 50x / 100x) and side (long below current price, short above). Built from current OI + last-24h candle entries + a fixed leverage-cohort prior. Read the `assumptions` field in the response for the modelling disclaimer. Cached server-side (~5s) so back-to-back polls are cheap.
1242    pub fn map(&self, base: impl Into<String>, options: LiquidationMapOptions) -> Result<serde_json::Value> {
1243        let mut parameters = HashMap::new();
1244        parameters.insert("base".to_string(), base.into());
1245        if let Some(v) = options.exchange {
1246            parameters.insert("exchange".to_string(), v.to_string());
1247        }
1248        if let Some(v) = options.quote {
1249            parameters.insert("quote".to_string(), v.to_string());
1250        }
1251        self.client.get("/liquidation/map", Some(parameters))
1252    }
1253
1254    /// Bucketed long / short liquidation USD over time for a single (base, quote) pair, joined with the futures-candle close as a reference price line. Long/short USD comes from `cex.liquidation` (Side='sell' = long position liquidated, 'buy' = short). Price comes from `candle.futures_1m` on the requested exchange — or Binance as the reference when none is specified. Cached ~30s server-side.
1255    pub fn symbol_history(&self, symbol: impl Into<String>, options: LiquidationSymbolHistoryOptions) -> Result<serde_json::Value> {
1256        let mut parameters = HashMap::new();
1257        parameters.insert("symbol".to_string(), symbol.into());
1258        if let Some(v) = options.quote {
1259            parameters.insert("quote".to_string(), v.to_string());
1260        }
1261        if let Some(v) = options.exchange {
1262            parameters.insert("exchange".to_string(), v.to_string());
1263        }
1264        if let Some(v) = options.interval {
1265            parameters.insert("interval".to_string(), v.to_string());
1266        }
1267        if let Some(v) = options.window {
1268            parameters.insert("window".to_string(), v.to_string());
1269        }
1270        self.client.get("/liquidation/symbol-history", Some(parameters))
1271    }
1272
1273}
1274
1275pub struct LiquidationOptions {
1276    pub limit: Option<i64>,
1277}
1278
1279impl LiquidationOptions {
1280    pub fn new() -> Self {
1281        LiquidationOptions {
1282            limit: None,
1283        }
1284    }
1285
1286    pub fn limit(mut self, limit: i64) -> Self {
1287        self.limit = Some(limit);
1288        self
1289    }
1290
1291}
1292
1293pub struct LiquidationFeedOptions {
1294    pub exchange: Option<String>,
1295    pub base: Option<String>,
1296    pub minVolumeUsd: Option<f64>,
1297    pub limit: Option<i64>,
1298}
1299
1300impl LiquidationFeedOptions {
1301    pub fn new() -> Self {
1302        LiquidationFeedOptions {
1303            exchange: None,
1304            base: None,
1305            minVolumeUsd: None,
1306            limit: None,
1307        }
1308    }
1309
1310    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1311        self.exchange = Some(exchange.into());
1312        self
1313    }
1314
1315    pub fn base(mut self, base: impl Into<String>) -> Self {
1316        self.base = Some(base.into());
1317        self
1318    }
1319
1320    pub fn minVolumeUsd(mut self, minVolumeUsd: f64) -> Self {
1321        self.minVolumeUsd = Some(minVolumeUsd);
1322        self
1323    }
1324
1325    pub fn limit(mut self, limit: i64) -> Self {
1326        self.limit = Some(limit);
1327        self
1328    }
1329
1330}
1331
1332pub struct LiquidationHeatmapOptions {
1333    pub window: Option<String>,
1334    pub topN: Option<i64>,
1335}
1336
1337impl LiquidationHeatmapOptions {
1338    pub fn new() -> Self {
1339        LiquidationHeatmapOptions {
1340            window: None,
1341            topN: None,
1342        }
1343    }
1344
1345    pub fn window(mut self, window: impl Into<String>) -> Self {
1346        self.window = Some(window.into());
1347        self
1348    }
1349
1350    pub fn topN(mut self, topN: i64) -> Self {
1351        self.topN = Some(topN);
1352        self
1353    }
1354
1355}
1356
1357pub struct LiquidationMapOptions {
1358    pub exchange: Option<String>,
1359    pub quote: Option<String>,
1360}
1361
1362impl LiquidationMapOptions {
1363    pub fn new() -> Self {
1364        LiquidationMapOptions {
1365            exchange: None,
1366            quote: None,
1367        }
1368    }
1369
1370    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1371        self.exchange = Some(exchange.into());
1372        self
1373    }
1374
1375    pub fn quote(mut self, quote: impl Into<String>) -> Self {
1376        self.quote = Some(quote.into());
1377        self
1378    }
1379
1380}
1381
1382pub struct LiquidationSymbolHistoryOptions {
1383    pub quote: Option<String>,
1384    pub exchange: Option<String>,
1385    pub interval: Option<String>,
1386    pub window: Option<String>,
1387}
1388
1389impl LiquidationSymbolHistoryOptions {
1390    pub fn new() -> Self {
1391        LiquidationSymbolHistoryOptions {
1392            quote: None,
1393            exchange: None,
1394            interval: None,
1395            window: None,
1396        }
1397    }
1398
1399    pub fn quote(mut self, quote: impl Into<String>) -> Self {
1400        self.quote = Some(quote.into());
1401        self
1402    }
1403
1404    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1405        self.exchange = Some(exchange.into());
1406        self
1407    }
1408
1409    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1410        self.interval = Some(interval.into());
1411        self
1412    }
1413
1414    pub fn window(mut self, window: impl Into<String>) -> Self {
1415        self.window = Some(window.into());
1416        self
1417    }
1418
1419}
1420
1421// --- Listing ---
1422
1423#[derive(Clone)]
1424pub struct Listing {
1425    pub client: Client,
1426}
1427
1428impl Datamaxi for Listing {
1429    fn new(api_key: String) -> Listing {
1430        let config = Config { base_url: None, api_key };
1431        Listing { client: Client::new(config) }
1432    }
1433    fn new_with_base_url(api_key: String, base_url: String) -> Listing {
1434        let config = Config { base_url: Some(base_url), api_key };
1435        Listing { client: Client::new(config) }
1436    }
1437}
1438
1439impl Listing {
1440    /// Get historical token listings for Upbit and Bithumb for KRW market
1441    pub fn historical(&self, options: ListingsHistoricalOptions) -> Result<serde_json::Value> {
1442        let mut parameters = HashMap::new();
1443        if let Some(v) = options.refresh {
1444            parameters.insert("refresh".to_string(), v.to_string());
1445        }
1446        self.client.get("/listings/historical", Some(parameters))
1447    }
1448
1449}
1450
1451pub struct ListingsHistoricalOptions {
1452    pub refresh: Option<bool>,
1453}
1454
1455impl ListingsHistoricalOptions {
1456    pub fn new() -> Self {
1457        ListingsHistoricalOptions {
1458            refresh: None,
1459        }
1460    }
1461
1462    pub fn refresh(mut self, refresh: bool) -> Self {
1463        self.refresh = Some(refresh);
1464        self
1465    }
1466
1467}
1468
1469// --- MarginBorrow ---
1470
1471#[derive(Clone)]
1472pub struct MarginBorrow {
1473    pub client: Client,
1474}
1475
1476impl Datamaxi for MarginBorrow {
1477    fn new(api_key: String) -> MarginBorrow {
1478        let config = Config { base_url: None, api_key };
1479        MarginBorrow { client: Client::new(config) }
1480    }
1481    fn new_with_base_url(api_key: String, base_url: String) -> MarginBorrow {
1482        let config = Config { base_url: Some(base_url), api_key };
1483        MarginBorrow { client: Client::new(config) }
1484    }
1485}
1486
1487impl MarginBorrow {
1488    /// Get the margin borrow data.
1489    pub fn get(&self, asset: impl Into<String>) -> Result<serde_json::Value> {
1490        let mut parameters = HashMap::new();
1491        parameters.insert("asset".to_string(), asset.into());
1492        self.client.get("/margin-borrow", Some(parameters))
1493    }
1494
1495}
1496
1497// --- NaverTrend ---
1498
1499#[derive(Clone)]
1500pub struct NaverTrend {
1501    pub client: Client,
1502}
1503
1504impl Datamaxi for NaverTrend {
1505    fn new(api_key: String) -> NaverTrend {
1506        let config = Config { base_url: None, api_key };
1507        NaverTrend { client: Client::new(config) }
1508    }
1509    fn new_with_base_url(api_key: String, base_url: String) -> NaverTrend {
1510        let config = Config { base_url: Some(base_url), api_key };
1511        NaverTrend { client: Client::new(config) }
1512    }
1513}
1514
1515impl NaverTrend {
1516    /// Get Naver trend data with a daily frequency for a project that is associated with a given [symbol](./symbols). The values in response are normalized into a range from 0 to 100, where 0 corresponds to a minimum interest, and 100 corresponds to a maximum interest of users in Naver search engine.
1517    pub fn get(&self, symbol: impl Into<String>) -> Result<serde_json::Value> {
1518        let mut parameters = HashMap::new();
1519        parameters.insert("symbol".to_string(), symbol.into());
1520        self.client.get("/naver-trend", Some(parameters))
1521    }
1522
1523    /// Get crypto symbols that are accepted by [Naver trend endpoint](./trend).
1524    pub fn symbols(&self) -> Result<serde_json::Value> {
1525        self.client.get("/naver-trend/symbols", None)
1526    }
1527
1528}
1529
1530// --- OpenInterest ---
1531
1532#[derive(Clone)]
1533pub struct OpenInterest {
1534    pub client: Client,
1535}
1536
1537impl Datamaxi for OpenInterest {
1538    fn new(api_key: String) -> OpenInterest {
1539        let config = Config { base_url: None, api_key };
1540        OpenInterest { client: Client::new(config) }
1541    }
1542    fn new_with_base_url(api_key: String, base_url: String) -> OpenInterest {
1543        let config = Config { base_url: Some(base_url), api_key };
1544        OpenInterest { client: Client::new(config) }
1545    }
1546}
1547
1548impl OpenInterest {
1549    /// Fetch the most recent Open Interest snapshot for a futures symbol on a given exchange.
1550    pub fn get(&self, exchange: impl Into<String>, symbol: impl Into<String>) -> Result<serde_json::Value> {
1551        let mut parameters = HashMap::new();
1552        parameters.insert("exchange".to_string(), exchange.into());
1553        parameters.insert("symbol".to_string(), symbol.into());
1554        self.client.get("/open-interest", Some(parameters))
1555    }
1556
1557    /// Historical Open Interest time series for a single token, broken down per exchange and aggregated to a fixed bucket (avg within bucket). The default lookback depends on the requested interval — 7 days for 1h, 30 days for 4h, 1 year for 1d — so callers don't have to hand-tune `from`/`to` for typical queries. The response also includes token metadata (icon, symbol, name) so a single call paints the whole header strip.
1558    pub fn history_aggregated(&self, token_id: impl Into<String>, options: OpenInterestHistoryAggregatedOptions) -> Result<serde_json::Value> {
1559        let mut parameters = HashMap::new();
1560        parameters.insert("token_id".to_string(), token_id.into());
1561        if let Some(v) = options.interval {
1562            parameters.insert("interval".to_string(), v.to_string());
1563        }
1564        if let Some(v) = options.from {
1565            parameters.insert("from".to_string(), v.to_string());
1566        }
1567        if let Some(v) = options.to {
1568            parameters.insert("to".to_string(), v.to_string());
1569        }
1570        self.client.get("/open-interest/history-aggregated", Some(parameters))
1571    }
1572
1573    /// Fetch latest Open Interest snapshots across exchanges/symbols. Optionally filter by `exchange`. Results are sorted by `openInterestUsd` descending (null values last).
1574    pub fn list(&self, options: OpenInterestListOptions) -> Result<serde_json::Value> {
1575        let mut parameters = HashMap::new();
1576        if let Some(v) = options.exchange {
1577            parameters.insert("exchange".to_string(), v.to_string());
1578        }
1579        self.client.get("/open-interest/list", Some(parameters))
1580    }
1581
1582    /// Paginated token × exchange Open Interest matrix. For each base asset we list the per-exchange notional OI in USD (when a venue carries the token) and `null` when it doesn't trade there. The matrix is sortable by any exchange column and searchable by base symbol — same shape the DataMaxi+ dashboard uses on `/open-interest`. Cached snapshot rebuilds every few seconds, so back-to-back requests are cheap.
1583    pub fn overview(&self, options: OpenInterestOverviewOptions) -> Result<serde_json::Value> {
1584        let mut parameters = HashMap::new();
1585        if let Some(v) = options.page {
1586            parameters.insert("page".to_string(), v.to_string());
1587        }
1588        if let Some(v) = options.limit {
1589            parameters.insert("limit".to_string(), v.to_string());
1590        }
1591        if let Some(v) = options.key {
1592            parameters.insert("key".to_string(), v.to_string());
1593        }
1594        if let Some(v) = options.sort {
1595            parameters.insert("sort".to_string(), v.to_string());
1596        }
1597        if let Some(v) = options.query {
1598            parameters.insert("query".to_string(), v.to_string());
1599        }
1600        self.client.get("/open-interest/overview", Some(parameters))
1601    }
1602
1603    /// Top-line aggregates over the current Open Interest snapshot — total OI USD, top tokens by OI, top exchanges by OI, and the count of venues currently reporting any base. Powers the OI page's KPI strip and breakdown card without forcing the caller to fetch the full token list.
1604    pub fn summary(&self, options: OpenInterestSummaryOptions) -> Result<serde_json::Value> {
1605        let mut parameters = HashMap::new();
1606        if let Some(v) = options.topN {
1607            parameters.insert("topN".to_string(), v.to_string());
1608        }
1609        self.client.get("/open-interest/summary", Some(parameters))
1610    }
1611
1612}
1613
1614pub struct OpenInterestHistoryAggregatedOptions {
1615    pub interval: Option<String>,
1616    pub from: Option<i64>,
1617    pub to: Option<i64>,
1618}
1619
1620impl OpenInterestHistoryAggregatedOptions {
1621    pub fn new() -> Self {
1622        OpenInterestHistoryAggregatedOptions {
1623            interval: None,
1624            from: None,
1625            to: None,
1626        }
1627    }
1628
1629    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1630        self.interval = Some(interval.into());
1631        self
1632    }
1633
1634    pub fn from(mut self, from: i64) -> Self {
1635        self.from = Some(from);
1636        self
1637    }
1638
1639    pub fn to(mut self, to: i64) -> Self {
1640        self.to = Some(to);
1641        self
1642    }
1643
1644}
1645
1646pub struct OpenInterestListOptions {
1647    pub exchange: Option<String>,
1648}
1649
1650impl OpenInterestListOptions {
1651    pub fn new() -> Self {
1652        OpenInterestListOptions {
1653            exchange: None,
1654        }
1655    }
1656
1657    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1658        self.exchange = Some(exchange.into());
1659        self
1660    }
1661
1662}
1663
1664pub struct OpenInterestOverviewOptions {
1665    pub page: Option<i64>,
1666    pub limit: Option<i64>,
1667    pub key: Option<String>,
1668    pub sort: Option<String>,
1669    pub query: Option<String>,
1670}
1671
1672impl OpenInterestOverviewOptions {
1673    pub fn new() -> Self {
1674        OpenInterestOverviewOptions {
1675            page: None,
1676            limit: None,
1677            key: None,
1678            sort: None,
1679            query: None,
1680        }
1681    }
1682
1683    pub fn page(mut self, page: i64) -> Self {
1684        self.page = Some(page);
1685        self
1686    }
1687
1688    pub fn limit(mut self, limit: i64) -> Self {
1689        self.limit = Some(limit);
1690        self
1691    }
1692
1693    pub fn key(mut self, key: impl Into<String>) -> Self {
1694        self.key = Some(key.into());
1695        self
1696    }
1697
1698    pub fn sort(mut self, sort: impl Into<String>) -> Self {
1699        self.sort = Some(sort.into());
1700        self
1701    }
1702
1703    pub fn query(mut self, query: impl Into<String>) -> Self {
1704        self.query = Some(query.into());
1705        self
1706    }
1707
1708}
1709
1710pub struct OpenInterestSummaryOptions {
1711    pub topN: Option<i64>,
1712}
1713
1714impl OpenInterestSummaryOptions {
1715    pub fn new() -> Self {
1716        OpenInterestSummaryOptions {
1717            topN: None,
1718        }
1719    }
1720
1721    pub fn topN(mut self, topN: i64) -> Self {
1722        self.topN = Some(topN);
1723        self
1724    }
1725
1726}
1727
1728// --- Premium ---
1729
1730#[derive(Clone)]
1731pub struct Premium {
1732    pub client: Client,
1733}
1734
1735impl Datamaxi for Premium {
1736    fn new(api_key: String) -> Premium {
1737        let config = Config { base_url: None, api_key };
1738        Premium { client: Client::new(config) }
1739    }
1740    fn new_with_base_url(api_key: String, base_url: String) -> Premium {
1741        let config = Config { base_url: Some(base_url), api_key };
1742        Premium { client: Client::new(config) }
1743    }
1744}
1745
1746impl Premium {
1747    /// Returns the sorted list of categorical token tags currently indexed for the premium table filter. Updated on the aggregator's tagstate reload cadence.
1748    pub fn tags(&self) -> Result<serde_json::Value> {
1749        self.client.get("/front/premium/tags", None)
1750    }
1751
1752    /// Get real-time premium (price difference) data across exchanges.
1753    pub fn get(&self, options: PremiumOptions) -> Result<serde_json::Value> {
1754        let mut parameters = HashMap::new();
1755        if let Some(v) = options.source_exchange {
1756            parameters.insert("source_exchange".to_string(), v.to_string());
1757        }
1758        if let Some(v) = options.target_exchange {
1759            parameters.insert("target_exchange".to_string(), v.to_string());
1760        }
1761        if let Some(v) = options.asset {
1762            parameters.insert("asset".to_string(), v.to_string());
1763        }
1764        if let Some(v) = options.source_quote {
1765            parameters.insert("source_quote".to_string(), v.to_string());
1766        }
1767        if let Some(v) = options.target_quote {
1768            parameters.insert("target_quote".to_string(), v.to_string());
1769        }
1770        if let Some(v) = options.source_market {
1771            parameters.insert("source_market".to_string(), v.to_string());
1772        }
1773        if let Some(v) = options.target_market {
1774            parameters.insert("target_market".to_string(), v.to_string());
1775        }
1776        if let Some(v) = options.premium_type {
1777            parameters.insert("premium_type".to_string(), v.to_string());
1778        }
1779        if let Some(v) = options.currency {
1780            parameters.insert("currency".to_string(), v.to_string());
1781        }
1782        if let Some(v) = options.conversion_base {
1783            parameters.insert("conversion_base".to_string(), v.to_string());
1784        }
1785        if let Some(v) = options.page {
1786            parameters.insert("page".to_string(), v.to_string());
1787        }
1788        if let Some(v) = options.limit {
1789            parameters.insert("limit".to_string(), v.to_string());
1790        }
1791        if let Some(v) = options.sort {
1792            parameters.insert("sort".to_string(), v.to_string());
1793        }
1794        if let Some(v) = options.key {
1795            parameters.insert("key".to_string(), v.to_string());
1796        }
1797        if let Some(v) = options.query {
1798            parameters.insert("query".to_string(), v.to_string());
1799        }
1800        if let Some(v) = options.only_transferable {
1801            parameters.insert("only_transferable".to_string(), v.to_string());
1802        }
1803        if let Some(v) = options.network {
1804            parameters.insert("network".to_string(), v.to_string());
1805        }
1806        if let Some(v) = options.min_sv {
1807            parameters.insert("min_sv".to_string(), v.to_string());
1808        }
1809        if let Some(v) = options.min_tv {
1810            parameters.insert("min_tv".to_string(), v.to_string());
1811        }
1812        self.client.get("/premium", Some(parameters))
1813    }
1814
1815    /// Get supported source exchanges for premium data.
1816    pub fn exchanges(&self) -> Result<serde_json::Value> {
1817        self.client.get("/premium/exchanges", None)
1818    }
1819
1820}
1821
1822pub struct PremiumOptions {
1823    pub source_exchange: Option<String>,
1824    pub target_exchange: Option<String>,
1825    pub asset: Option<String>,
1826    pub source_quote: Option<String>,
1827    pub target_quote: Option<String>,
1828    pub source_market: Option<String>,
1829    pub target_market: Option<String>,
1830    pub premium_type: Option<String>,
1831    pub currency: Option<String>,
1832    pub conversion_base: Option<String>,
1833    pub page: Option<i64>,
1834    pub limit: Option<i64>,
1835    pub sort: Option<String>,
1836    pub key: Option<String>,
1837    pub query: Option<String>,
1838    pub only_transferable: Option<bool>,
1839    pub network: Option<String>,
1840    pub min_sv: Option<f64>,
1841    pub min_tv: Option<f64>,
1842}
1843
1844impl PremiumOptions {
1845    pub fn new() -> Self {
1846        PremiumOptions {
1847            source_exchange: None,
1848            target_exchange: None,
1849            asset: None,
1850            source_quote: None,
1851            target_quote: None,
1852            source_market: None,
1853            target_market: None,
1854            premium_type: None,
1855            currency: None,
1856            conversion_base: None,
1857            page: None,
1858            limit: None,
1859            sort: None,
1860            key: None,
1861            query: None,
1862            only_transferable: None,
1863            network: None,
1864            min_sv: None,
1865            min_tv: None,
1866        }
1867    }
1868
1869    pub fn source_exchange(mut self, source_exchange: impl Into<String>) -> Self {
1870        self.source_exchange = Some(source_exchange.into());
1871        self
1872    }
1873
1874    pub fn target_exchange(mut self, target_exchange: impl Into<String>) -> Self {
1875        self.target_exchange = Some(target_exchange.into());
1876        self
1877    }
1878
1879    pub fn asset(mut self, asset: impl Into<String>) -> Self {
1880        self.asset = Some(asset.into());
1881        self
1882    }
1883
1884    pub fn source_quote(mut self, source_quote: impl Into<String>) -> Self {
1885        self.source_quote = Some(source_quote.into());
1886        self
1887    }
1888
1889    pub fn target_quote(mut self, target_quote: impl Into<String>) -> Self {
1890        self.target_quote = Some(target_quote.into());
1891        self
1892    }
1893
1894    pub fn source_market(mut self, source_market: impl Into<String>) -> Self {
1895        self.source_market = Some(source_market.into());
1896        self
1897    }
1898
1899    pub fn target_market(mut self, target_market: impl Into<String>) -> Self {
1900        self.target_market = Some(target_market.into());
1901        self
1902    }
1903
1904    pub fn premium_type(mut self, premium_type: impl Into<String>) -> Self {
1905        self.premium_type = Some(premium_type.into());
1906        self
1907    }
1908
1909    pub fn currency(mut self, currency: impl Into<String>) -> Self {
1910        self.currency = Some(currency.into());
1911        self
1912    }
1913
1914    pub fn conversion_base(mut self, conversion_base: impl Into<String>) -> Self {
1915        self.conversion_base = Some(conversion_base.into());
1916        self
1917    }
1918
1919    pub fn page(mut self, page: i64) -> Self {
1920        self.page = Some(page);
1921        self
1922    }
1923
1924    pub fn limit(mut self, limit: i64) -> Self {
1925        self.limit = Some(limit);
1926        self
1927    }
1928
1929    pub fn sort(mut self, sort: impl Into<String>) -> Self {
1930        self.sort = Some(sort.into());
1931        self
1932    }
1933
1934    pub fn key(mut self, key: impl Into<String>) -> Self {
1935        self.key = Some(key.into());
1936        self
1937    }
1938
1939    pub fn query(mut self, query: impl Into<String>) -> Self {
1940        self.query = Some(query.into());
1941        self
1942    }
1943
1944    pub fn only_transferable(mut self, only_transferable: bool) -> Self {
1945        self.only_transferable = Some(only_transferable);
1946        self
1947    }
1948
1949    pub fn network(mut self, network: impl Into<String>) -> Self {
1950        self.network = Some(network.into());
1951        self
1952    }
1953
1954    pub fn min_sv(mut self, min_sv: f64) -> Self {
1955        self.min_sv = Some(min_sv);
1956        self
1957    }
1958
1959    pub fn min_tv(mut self, min_tv: f64) -> Self {
1960        self.min_tv = Some(min_tv);
1961        self
1962    }
1963
1964}
1965
1966// --- Telegram ---
1967
1968#[derive(Clone)]
1969pub struct Telegram {
1970    pub client: Client,
1971}
1972
1973impl Datamaxi for Telegram {
1974    fn new(api_key: String) -> Telegram {
1975        let config = Config { base_url: None, api_key };
1976        Telegram { client: Client::new(config) }
1977    }
1978    fn new_with_base_url(api_key: String, base_url: String) -> Telegram {
1979        let config = Config { base_url: Some(base_url), api_key };
1980        Telegram { client: Client::new(config) }
1981    }
1982}
1983
1984impl Telegram {
1985    /// Get Telegram channels
1986    pub fn channels(&self, options: TelegramChannelsOptions) -> Result<serde_json::Value> {
1987        let mut parameters = HashMap::new();
1988        if let Some(v) = options.page {
1989            parameters.insert("page".to_string(), v.to_string());
1990        }
1991        if let Some(v) = options.limit {
1992            parameters.insert("limit".to_string(), v.to_string());
1993        }
1994        if let Some(v) = options.category {
1995            parameters.insert("category".to_string(), v.to_string());
1996        }
1997        if let Some(v) = options.key {
1998            parameters.insert("key".to_string(), v.to_string());
1999        }
2000        if let Some(v) = options.sort {
2001            parameters.insert("sort".to_string(), v.to_string());
2002        }
2003        self.client.get("/telegram/channels", Some(parameters))
2004    }
2005
2006    /// Get Telegram messages.
2007    pub fn messages(&self, options: TelegramMessagesOptions) -> Result<serde_json::Value> {
2008        let mut parameters = HashMap::new();
2009        if let Some(v) = options.channel {
2010            parameters.insert("channel".to_string(), v.to_string());
2011        }
2012        if let Some(v) = options.page {
2013            parameters.insert("page".to_string(), v.to_string());
2014        }
2015        if let Some(v) = options.limit {
2016            parameters.insert("limit".to_string(), v.to_string());
2017        }
2018        if let Some(v) = options.key {
2019            parameters.insert("key".to_string(), v.to_string());
2020        }
2021        if let Some(v) = options.sort {
2022            parameters.insert("sort".to_string(), v.to_string());
2023        }
2024        if let Some(v) = options.category {
2025            parameters.insert("category".to_string(), v.to_string());
2026        }
2027        if let Some(v) = options.search_query {
2028            parameters.insert("search_query".to_string(), v.to_string());
2029        }
2030        self.client.get("/telegram/messages", Some(parameters))
2031    }
2032
2033}
2034
2035pub struct TelegramChannelsOptions {
2036    pub page: Option<i64>,
2037    pub limit: Option<i64>,
2038    pub category: Option<String>,
2039    pub key: Option<String>,
2040    pub sort: Option<String>,
2041}
2042
2043impl TelegramChannelsOptions {
2044    pub fn new() -> Self {
2045        TelegramChannelsOptions {
2046            page: None,
2047            limit: None,
2048            category: None,
2049            key: None,
2050            sort: None,
2051        }
2052    }
2053
2054    pub fn page(mut self, page: i64) -> Self {
2055        self.page = Some(page);
2056        self
2057    }
2058
2059    pub fn limit(mut self, limit: i64) -> Self {
2060        self.limit = Some(limit);
2061        self
2062    }
2063
2064    pub fn category(mut self, category: impl Into<String>) -> Self {
2065        self.category = Some(category.into());
2066        self
2067    }
2068
2069    pub fn key(mut self, key: impl Into<String>) -> Self {
2070        self.key = Some(key.into());
2071        self
2072    }
2073
2074    pub fn sort(mut self, sort: impl Into<String>) -> Self {
2075        self.sort = Some(sort.into());
2076        self
2077    }
2078
2079}
2080
2081pub struct TelegramMessagesOptions {
2082    pub channel: Option<String>,
2083    pub page: Option<i64>,
2084    pub limit: Option<i64>,
2085    pub key: Option<String>,
2086    pub sort: Option<String>,
2087    pub category: Option<String>,
2088    pub search_query: Option<String>,
2089}
2090
2091impl TelegramMessagesOptions {
2092    pub fn new() -> Self {
2093        TelegramMessagesOptions {
2094            channel: None,
2095            page: None,
2096            limit: None,
2097            key: None,
2098            sort: None,
2099            category: None,
2100            search_query: None,
2101        }
2102    }
2103
2104    pub fn channel(mut self, channel: impl Into<String>) -> Self {
2105        self.channel = Some(channel.into());
2106        self
2107    }
2108
2109    pub fn page(mut self, page: i64) -> Self {
2110        self.page = Some(page);
2111        self
2112    }
2113
2114    pub fn limit(mut self, limit: i64) -> Self {
2115        self.limit = Some(limit);
2116        self
2117    }
2118
2119    pub fn key(mut self, key: impl Into<String>) -> Self {
2120        self.key = Some(key.into());
2121        self
2122    }
2123
2124    pub fn sort(mut self, sort: impl Into<String>) -> Self {
2125        self.sort = Some(sort.into());
2126        self
2127    }
2128
2129    pub fn category(mut self, category: impl Into<String>) -> Self {
2130        self.category = Some(category.into());
2131        self
2132    }
2133
2134    pub fn search_query(mut self, search_query: impl Into<String>) -> Self {
2135        self.search_query = Some(search_query.into());
2136        self
2137    }
2138
2139}
2140
2141// --- Ticker ---
2142
2143#[derive(Clone)]
2144pub struct Ticker {
2145    pub client: Client,
2146}
2147
2148impl Datamaxi for Ticker {
2149    fn new(api_key: String) -> Ticker {
2150        let config = Config { base_url: None, api_key };
2151        Ticker { client: Client::new(config) }
2152    }
2153    fn new_with_base_url(api_key: String, base_url: String) -> Ticker {
2154        let config = Config { base_url: Some(base_url), api_key };
2155        Ticker { client: Client::new(config) }
2156    }
2157}
2158
2159impl Ticker {
2160    /// Fetch the latest ticker for symbol from given exchange.
2161    pub fn get(&self, exchange: impl Into<String>, symbol: impl Into<String>, options: TickerOptions) -> Result<serde_json::Value> {
2162        let mut parameters = HashMap::new();
2163        parameters.insert("exchange".to_string(), exchange.into());
2164        parameters.insert("symbol".to_string(), symbol.into());
2165        if let Some(v) = options.market {
2166            parameters.insert("market".to_string(), v.to_string());
2167        }
2168        if let Some(v) = options.currency {
2169            parameters.insert("currency".to_string(), v.to_string());
2170        }
2171        if let Some(v) = options.conversion_base {
2172            parameters.insert("conversion_base".to_string(), v.to_string());
2173        }
2174        self.client.get("/ticker", Some(parameters))
2175    }
2176
2177    /// Get supported exchanges accepted by `/api/v1/ticker` endpoint.
2178    pub fn exchanges(&self, options: TickerExchangesOptions) -> Result<serde_json::Value> {
2179        let mut parameters = HashMap::new();
2180        if let Some(v) = options.market {
2181            parameters.insert("market".to_string(), v.to_string());
2182        }
2183        self.client.get("/ticker/exchanges", Some(parameters))
2184    }
2185
2186    /// Get supported symbols accepted by `/api/v1/ticker` endpoint.
2187    pub fn symbols(&self, exchange: impl Into<String>, options: TickerSymbolsOptions) -> Result<serde_json::Value> {
2188        let mut parameters = HashMap::new();
2189        parameters.insert("exchange".to_string(), exchange.into());
2190        if let Some(v) = options.market {
2191            parameters.insert("market".to_string(), v.to_string());
2192        }
2193        self.client.get("/ticker/symbols", Some(parameters))
2194    }
2195
2196}
2197
2198pub struct TickerOptions {
2199    pub market: Option<String>,
2200    pub currency: Option<String>,
2201    pub conversion_base: Option<String>,
2202}
2203
2204impl TickerOptions {
2205    pub fn new() -> Self {
2206        TickerOptions {
2207            market: None,
2208            currency: None,
2209            conversion_base: None,
2210        }
2211    }
2212
2213    pub fn market(mut self, market: impl Into<String>) -> Self {
2214        self.market = Some(market.into());
2215        self
2216    }
2217
2218    pub fn currency(mut self, currency: impl Into<String>) -> Self {
2219        self.currency = Some(currency.into());
2220        self
2221    }
2222
2223    pub fn conversion_base(mut self, conversion_base: impl Into<String>) -> Self {
2224        self.conversion_base = Some(conversion_base.into());
2225        self
2226    }
2227
2228}
2229
2230pub struct TickerExchangesOptions {
2231    pub market: Option<String>,
2232}
2233
2234impl TickerExchangesOptions {
2235    pub fn new() -> Self {
2236        TickerExchangesOptions {
2237            market: None,
2238        }
2239    }
2240
2241    pub fn market(mut self, market: impl Into<String>) -> Self {
2242        self.market = Some(market.into());
2243        self
2244    }
2245
2246}
2247
2248pub struct TickerSymbolsOptions {
2249    pub market: Option<String>,
2250}
2251
2252impl TickerSymbolsOptions {
2253    pub fn new() -> Self {
2254        TickerSymbolsOptions {
2255            market: None,
2256        }
2257    }
2258
2259    pub fn market(mut self, market: impl Into<String>) -> Self {
2260        self.market = Some(market.into());
2261        self
2262    }
2263
2264}
2265
2266// --- Token ---
2267
2268#[derive(Clone)]
2269pub struct Token {
2270    pub client: Client,
2271}
2272
2273impl Datamaxi for Token {
2274    fn new(api_key: String) -> Token {
2275        let config = Config { base_url: None, api_key };
2276        Token { client: Client::new(config) }
2277    }
2278    fn new_with_base_url(api_key: String, base_url: String) -> Token {
2279        let config = Config { base_url: Some(base_url), api_key };
2280        Token { client: Client::new(config) }
2281    }
2282}
2283
2284impl Token {
2285    /// Fetch latest token updates
2286    pub fn updates(&self, options: CexTokenUpdatesOptions) -> Result<serde_json::Value> {
2287        let mut parameters = HashMap::new();
2288        if let Some(v) = options.page {
2289            parameters.insert("page".to_string(), v.to_string());
2290        }
2291        if let Some(v) = options.limit {
2292            parameters.insert("limit".to_string(), v.to_string());
2293        }
2294        if let Some(v) = options.r#type {
2295            parameters.insert("type".to_string(), v.to_string());
2296        }
2297        self.client.get("/cex/token/updates", Some(parameters))
2298    }
2299
2300}
2301
2302pub struct CexTokenUpdatesOptions {
2303    pub page: Option<String>,
2304    pub limit: Option<String>,
2305    pub r#type: Option<String>,
2306}
2307
2308impl CexTokenUpdatesOptions {
2309    pub fn new() -> Self {
2310        CexTokenUpdatesOptions {
2311            page: None,
2312            limit: None,
2313            r#type: None,
2314        }
2315    }
2316
2317    pub fn page(mut self, page: impl Into<String>) -> Self {
2318        self.page = Some(page.into());
2319        self
2320    }
2321
2322    pub fn limit(mut self, limit: impl Into<String>) -> Self {
2323        self.limit = Some(limit.into());
2324        self
2325    }
2326
2327    pub fn r#type(mut self, r#type: impl Into<String>) -> Self {
2328        self.r#type = Some(r#type.into());
2329        self
2330    }
2331
2332}
2333
2334// --- TradingFees ---
2335
2336#[derive(Clone)]
2337pub struct TradingFees {
2338    pub client: Client,
2339}
2340
2341impl Datamaxi for TradingFees {
2342    fn new(api_key: String) -> TradingFees {
2343        let config = Config { base_url: None, api_key };
2344        TradingFees { client: Client::new(config) }
2345    }
2346    fn new_with_base_url(api_key: String, base_url: String) -> TradingFees {
2347        let config = Config { base_url: Some(base_url), api_key };
2348        TradingFees { client: Client::new(config) }
2349    }
2350}
2351
2352impl TradingFees {
2353    /// Get trading fees.
2354    pub fn fees(&self, options: CexFeesOptions) -> Result<serde_json::Value> {
2355        let mut parameters = HashMap::new();
2356        if let Some(v) = options.exchange {
2357            parameters.insert("exchange".to_string(), v.to_string());
2358        }
2359        if let Some(v) = options.symbol {
2360            parameters.insert("symbol".to_string(), v.to_string());
2361        }
2362        self.client.get("/cex/fees", Some(parameters))
2363    }
2364
2365    /// Get supported exchanges accepted by `/api/v1/trading-fees` endpoint.
2366    pub fn exchanges(&self) -> Result<serde_json::Value> {
2367        self.client.get("/cex/fees/exchanges", None)
2368    }
2369
2370    /// Get supported symbols accepted by `/api/v1/trading-fees` endpoint.
2371    pub fn symbols(&self, exchange: impl Into<String>) -> Result<serde_json::Value> {
2372        let mut parameters = HashMap::new();
2373        parameters.insert("exchange".to_string(), exchange.into());
2374        self.client.get("/cex/fees/symbols", Some(parameters))
2375    }
2376
2377}
2378
2379pub struct CexFeesOptions {
2380    pub exchange: Option<String>,
2381    pub symbol: Option<String>,
2382}
2383
2384impl CexFeesOptions {
2385    pub fn new() -> Self {
2386        CexFeesOptions {
2387            exchange: None,
2388            symbol: None,
2389        }
2390    }
2391
2392    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
2393        self.exchange = Some(exchange.into());
2394        self
2395    }
2396
2397    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
2398        self.symbol = Some(symbol.into());
2399        self
2400    }
2401
2402}
2403
2404// --- WalletStatus ---
2405
2406#[derive(Clone)]
2407pub struct WalletStatus {
2408    pub client: Client,
2409}
2410
2411impl Datamaxi for WalletStatus {
2412    fn new(api_key: String) -> WalletStatus {
2413        let config = Config { base_url: None, api_key };
2414        WalletStatus { client: Client::new(config) }
2415    }
2416    fn new_with_base_url(api_key: String, base_url: String) -> WalletStatus {
2417        let config = Config { base_url: Some(base_url), api_key };
2418        WalletStatus { client: Client::new(config) }
2419    }
2420}
2421
2422impl WalletStatus {
2423    /// Get the latest wallet status for asset from given exchange.
2424    pub fn get(&self, asset: impl Into<String>, options: WalletStatusOptions) -> Result<serde_json::Value> {
2425        let mut parameters = HashMap::new();
2426        parameters.insert("asset".to_string(), asset.into());
2427        if let Some(v) = options.exchange {
2428            parameters.insert("exchange".to_string(), v.to_string());
2429        }
2430        self.client.get("/wallet-status", Some(parameters))
2431    }
2432
2433    /// Get assets accepted by `/api/v1/wallet-status` endpoint.
2434    pub fn assets(&self, exchange: impl Into<String>) -> Result<serde_json::Value> {
2435        let mut parameters = HashMap::new();
2436        parameters.insert("exchange".to_string(), exchange.into());
2437        self.client.get("/wallet-status/assets", Some(parameters))
2438    }
2439
2440    /// Get exchanges accepted by `/api/v1/wallet-status` endpoint.
2441    pub fn exchanges(&self) -> Result<serde_json::Value> {
2442        self.client.get("/wallet-status/exchanges", None)
2443    }
2444
2445}
2446
2447pub struct WalletStatusOptions {
2448    pub exchange: Option<String>,
2449}
2450
2451impl WalletStatusOptions {
2452    pub fn new() -> Self {
2453        WalletStatusOptions {
2454            exchange: None,
2455        }
2456    }
2457
2458    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
2459        self.exchange = Some(exchange.into());
2460        self
2461    }
2462
2463}