deribit_http/model/
currency.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 15/9/25
5******************************************************************************/
6use crate::model::withdrawal::WithdrawalPriority;
7use pretty_simple_display::{DebugPretty, DisplaySimple};
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10
11/// Supported cryptocurrency currencies in the Deribit platform
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(rename_all = "UPPERCASE")]
14pub enum Currency {
15    /// Bitcoin cryptocurrency
16    Btc,
17    /// Ethereum cryptocurrency
18    Eth,
19    /// USD Coin stablecoin
20    Usdc,
21    /// Tether USD stablecoin
22    Usdt,
23    /// Euro-backed stablecoin
24    Eurr,
25}
26
27impl std::fmt::Display for Currency {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Currency::Btc => write!(f, "BTC"),
31            Currency::Eth => write!(f, "ETH"),
32            Currency::Usdc => write!(f, "USDC"),
33            Currency::Usdt => write!(f, "USDT"),
34            Currency::Eurr => write!(f, "EURR"),
35        }
36    }
37}
38
39/// Currency structure
40#[skip_serializing_none]
41#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
42pub struct CurrencyStruct {
43    /// Currency symbol (BTC, ETH, etc.)
44    pub currency: String,
45    /// Long currency name
46    pub currency_long: String,
47    /// Number of decimal places for the currency
48    pub decimals: Option<u32>,
49    /// Fee precision (decimal places)
50    pub fee_precision: Option<u32>,
51    /// Minimum confirmations required
52    pub min_confirmations: u32,
53    /// Minimum withdrawal fee
54    pub min_withdrawal_fee: f64,
55    /// Standard withdrawal fee
56    pub withdrawal_fee: f64,
57    /// Withdrawal priorities
58    pub withdrawal_priorities: Vec<WithdrawalPriority>,
59    /// APR for yield-generating tokens
60    pub apr: Option<f64>,
61    /// Coin type identifier (e.g., "BTC", "ETH", "USDC")
62    pub coin_type: Option<String>,
63    /// Network fee
64    pub network_fee: Option<f64>,
65    /// Network currency used for fees
66    pub network_currency: Option<String>,
67    /// Whether the currency is part of the cross collateral pool
68    pub in_cross_collateral_pool: Option<bool>,
69}
70
71/// Currency information and configuration
72#[skip_serializing_none]
73#[derive(DebugPretty, DisplaySimple, Clone, PartialEq, Serialize, Deserialize)]
74pub struct CurrencyInfo {
75    /// Coin type identifier (e.g., "BITCOIN", "ETHEREUM")
76    pub coin_type: String,
77    /// Currency code
78    pub currency: String,
79    /// Full currency name
80    pub currency_long: String,
81    /// Fee precision (decimal places)
82    pub fee_precision: i32,
83    /// Minimum confirmations required
84    pub min_confirmations: i32,
85    /// Minimum withdrawal fee
86    pub min_withdrawal_fee: f64,
87    /// Standard withdrawal fee
88    pub withdrawal_fee: f64,
89    /// Available withdrawal priorities
90    pub withdrawal_priorities: Vec<WithdrawalPriority>,
91    /// Whether the currency is disabled
92    pub disabled: Option<bool>,
93    /// Minimum deposit amount
94    pub min_deposit_amount: Option<f64>,
95    /// Maximum withdrawal amount
96    pub max_withdrawal_amount: Option<f64>,
97}
98
99impl CurrencyInfo {
100    /// Create new currency info
101    pub fn new(
102        coin_type: String,
103        currency: String,
104        currency_long: String,
105        fee_precision: i32,
106        min_confirmations: i32,
107        min_withdrawal_fee: f64,
108        withdrawal_fee: f64,
109    ) -> Self {
110        Self {
111            coin_type,
112            currency,
113            currency_long,
114            fee_precision,
115            min_confirmations,
116            min_withdrawal_fee,
117            withdrawal_fee,
118            withdrawal_priorities: Vec::new(),
119            disabled: None,
120            min_deposit_amount: None,
121            max_withdrawal_amount: None,
122        }
123    }
124
125    /// Add withdrawal priority
126    pub fn add_priority(&mut self, priority: WithdrawalPriority) {
127        self.withdrawal_priorities.push(priority);
128    }
129
130    /// Set disabled status
131    pub fn with_disabled(mut self, disabled: bool) -> Self {
132        self.disabled = Some(disabled);
133        self
134    }
135
136    /// Set deposit limits
137    pub fn with_deposit_limit(mut self, min_amount: f64) -> Self {
138        self.min_deposit_amount = Some(min_amount);
139        self
140    }
141
142    /// Set withdrawal limits
143    pub fn with_withdrawal_limit(mut self, max_amount: f64) -> Self {
144        self.max_withdrawal_amount = Some(max_amount);
145        self
146    }
147
148    /// Check if currency is enabled
149    pub fn is_enabled(&self) -> bool {
150        !self.disabled.unwrap_or(false)
151    }
152
153    /// Get priority by name
154    pub fn get_priority(&self, name: &str) -> Option<&WithdrawalPriority> {
155        self.withdrawal_priorities.iter().find(|p| p.name == name)
156    }
157
158    /// Get highest priority
159    pub fn highest_priority(&self) -> Option<&WithdrawalPriority> {
160        self.withdrawal_priorities
161            .iter()
162            .max_by(|a, b| a.value.partial_cmp(&b.value).unwrap())
163    }
164
165    /// Get lowest priority
166    pub fn lowest_priority(&self) -> Option<&WithdrawalPriority> {
167        self.withdrawal_priorities
168            .iter()
169            .min_by(|a, b| a.value.partial_cmp(&b.value).unwrap())
170    }
171}
172
173/// Collection of currency information
174#[derive(DebugPretty, DisplaySimple, Clone, PartialEq, Serialize, Deserialize)]
175pub struct CurrencyInfoCollection {
176    /// List of currency information
177    pub currencies: Vec<CurrencyInfo>,
178}
179
180impl CurrencyInfoCollection {
181    /// Create new collection
182    pub fn new() -> Self {
183        Self {
184            currencies: Vec::new(),
185        }
186    }
187
188    /// Add currency info
189    pub fn add(&mut self, info: CurrencyInfo) {
190        self.currencies.push(info);
191    }
192
193    /// Get currency info by currency
194    pub fn get(&self, currency: String) -> Option<&CurrencyInfo> {
195        self.currencies.iter().find(|c| c.currency == currency)
196    }
197
198    /// Get enabled currencies
199    pub fn enabled(&self) -> Vec<&CurrencyInfo> {
200        self.currencies.iter().filter(|c| c.is_enabled()).collect()
201    }
202
203    /// Get currencies with withdrawal support
204    pub fn with_withdrawal(&self) -> Vec<&CurrencyInfo> {
205        self.currencies
206            .iter()
207            .filter(|c| !c.withdrawal_priorities.is_empty())
208            .collect()
209    }
210}
211
212impl Default for CurrencyInfoCollection {
213    fn default() -> Self {
214        Self::new()
215    }
216}
217
218/// Currency-specific expirations
219#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
220pub struct CurrencyExpirations {
221    /// Future instrument expirations
222    pub future: Option<Vec<String>>,
223    /// Option instrument expirations
224    pub option: Option<Vec<String>>,
225}