goldrush_sdk/models/
balances.rs1use serde::Deserialize;
2
3#[derive(Debug, Clone, Deserialize)]
5pub struct BalanceItem {
6 pub contract_address: String,
8
9 #[serde(rename = "contract_ticker_symbol")]
11 pub contract_ticker_symbol: Option<String>,
12
13 #[serde(rename = "contract_name")]
15 pub contract_name: Option<String>,
16
17 pub balance: String,
19
20 #[serde(rename = "contract_decimals")]
22 pub contract_decimals: Option<u32>,
23
24 pub quote_rate: Option<f64>,
26
27 pub quote: Option<f64>,
29
30 #[serde(rename = "type")]
32 pub token_type: Option<String>,
33
34 pub is_spam: Option<bool>,
36
37 pub logo_url: Option<String>,
39
40 pub last_transferred_at: Option<String>,
42
43 pub native_token: Option<bool>,
45
46 #[serde(flatten)]
48 pub metadata: Option<serde_json::Value>,
49}
50
51impl BalanceItem {
52 pub fn symbol(&self) -> &str {
54 self.contract_ticker_symbol.as_deref().unwrap_or("Unknown")
55 }
56
57 pub fn name(&self) -> &str {
59 self.contract_name.as_deref()
60 .or(self.contract_ticker_symbol.as_deref())
61 .unwrap_or("Unknown")
62 }
63
64 pub fn balance_as_float(&self) -> Option<f64> {
66 let balance = self.balance.parse::<f64>().ok()?;
67 let decimals = self.contract_decimals.unwrap_or(18) as u32;
68 Some(balance / 10f64.powi(decimals as i32))
69 }
70
71 pub fn has_balance(&self) -> bool {
73 self.balance.parse::<f64>().unwrap_or(0.0) > 0.0
74 }
75
76 pub fn has_quote_value(&self) -> bool {
78 self.quote.unwrap_or(0.0) > 0.0
79 }
80
81 pub fn is_spam(&self) -> bool {
83 self.is_spam.unwrap_or(false)
84 }
85}
86
87#[derive(Debug, Clone, Deserialize)]
89pub struct BalancesData {
90 pub address: Option<String>,
92
93 pub chain_id: Option<u64>,
95
96 pub chain_name: Option<String>,
98
99 pub items: Vec<BalanceItem>,
101
102 pub quote_currency: Option<String>,
104
105 pub total_quote: Option<f64>,
107}
108
109impl BalancesData {
110 pub fn total_value(&self) -> f64 {
112 self.items.iter()
113 .filter_map(|item| item.quote)
114 .sum()
115 }
116
117 pub fn tokens_by_value(&self) -> Vec<&BalanceItem> {
119 let mut tokens: Vec<_> = self.items.iter()
120 .filter(|item| item.quote.unwrap_or(0.0) > 0.0)
121 .collect();
122 tokens.sort_by(|a, b|
123 b.quote.partial_cmp(&a.quote).unwrap_or(std::cmp::Ordering::Equal)
124 );
125 tokens
126 }
127
128 pub fn tokens_above_value(&self, min_value: f64) -> Vec<&BalanceItem> {
130 self.items.iter()
131 .filter(|item| item.quote.unwrap_or(0.0) >= min_value)
132 .collect()
133 }
134
135 pub fn non_spam_count(&self) -> usize {
137 self.items.iter()
138 .filter(|item| !item.is_spam.unwrap_or(false))
139 .count()
140 }
141}
142
143pub type BalancesResponse = crate::models::ApiResponse<BalancesData>;