df_hyperliquid_core/transfer/send/
token.rs1use crate::client::{Network, Token};
6use crate::transfer::evm::{HYPE_SYSTEM, system_address};
7use crate::utils::Address;
8use serde::Deserialize;
9
10pub const HYPE_EVM_DECIMALS: u32 = 18;
12
13#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct SpotToken {
17 pub name: String,
18 pub index: u32,
20 pub token_id: String,
22 pub wei_decimals: u32,
24 #[serde(default)]
27 pub evm_contract: Option<EvmContract>,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
32pub struct EvmContract {
33 pub address: Address,
34 #[serde(rename = "evm_extra_wei_decimals")]
36 pub extra_wei_decimals: i32,
37}
38
39impl SpotToken {
40 #[must_use]
42 pub fn wire(&self) -> String {
43 format!("{}:{}", self.name, self.token_id)
44 }
45
46 #[must_use]
48 pub fn is_hype(&self, network: Network) -> bool {
49 self.index == network.hype().index
50 }
51
52 #[must_use]
55 pub fn system_address(&self, network: Network) -> Address {
56 match self.is_hype(network) {
57 true => HYPE_SYSTEM,
58 false => system_address(u64::from(self.index)),
59 }
60 }
61
62 #[must_use]
65 pub fn evm_decimals(&self, network: Network) -> Option<u32> {
66 if self.is_hype(network) {
67 return Some(HYPE_EVM_DECIMALS);
68 }
69 let link = self.evm_contract?;
70 u32::try_from(i64::from(self.wei_decimals) + i64::from(link.extra_wei_decimals)).ok()
71 }
72
73 #[must_use]
76 pub fn crossing_places(&self, network: Network) -> Option<u32> {
77 self.evm_decimals(network).map(|evm| evm.min(self.wei_decimals))
78 }
79}
80
81impl From<Token> for SpotToken {
84 fn from(token: Token) -> SpotToken {
85 SpotToken {
86 name: token.name.to_owned(),
87 index: token.index,
88 token_id: token.token_id.to_owned(),
89 wei_decimals: token.wei_decimals,
90 evm_contract: None,
91 }
92 }
93}
94
95#[cfg(test)]
96#[path = "tests/token.rs"]
97mod tests;