hyperliquid_rust_sdk_abrkn/
helpers.rs

1use crate::{consts::*, prelude::*, Error};
2use chrono::prelude::Utc;
3use lazy_static::lazy_static;
4use log::info;
5use rand::{thread_rng, Rng};
6use std::sync::atomic::{AtomicU64, Ordering};
7use uuid::Uuid;
8
9fn now_timestamp_ms() -> u64 {
10    let now = Utc::now();
11    now.timestamp_millis() as u64
12}
13
14pub(crate) fn next_nonce() -> u64 {
15    let nonce = CUR_NONCE.fetch_add(1, Ordering::Relaxed);
16    let now_ms = now_timestamp_ms();
17    if nonce > now_ms + 1000 {
18        info!("nonce progressed too far ahead {nonce} {now_ms}");
19    }
20    // more than 300 seconds behind
21    if nonce + 300000 < now_ms {
22        CUR_NONCE.fetch_max(now_ms, Ordering::Relaxed);
23    }
24    nonce
25}
26
27pub(crate) const WIRE_DECIMALS: u8 = 8;
28
29pub(crate) fn float_to_string_for_hashing(x: f64) -> String {
30    let mut x = format!("{:.*}", WIRE_DECIMALS.into(), x);
31    while x.ends_with('0') {
32        x.pop();
33    }
34    if x.ends_with('.') {
35        x.pop();
36    }
37    if x == "-0" {
38        "0".to_string()
39    } else {
40        x
41    }
42}
43
44pub(crate) fn uuid_to_hex_string(uuid: Uuid) -> String {
45    let hex_string = uuid
46        .as_bytes()
47        .iter()
48        .map(|byte| format!("{:02x}", byte))
49        .collect::<Vec<String>>()
50        .join("");
51    format!("0x{}", hex_string)
52}
53
54pub(crate) fn generate_random_key() -> Result<[u8; 32]> {
55    let mut arr = [0u8; 32];
56    thread_rng()
57        .try_fill(&mut arr[..])
58        .map_err(|e| Error::RandGen(e.to_string()))?;
59    Ok(arr)
60}
61
62pub fn truncate_float(float: f64, decimals: u32, round_up: bool) -> f64 {
63    let pow10 = 10i64.pow(decimals) as f64;
64    let mut float = (float * pow10) as u64;
65    if round_up {
66        float += 1;
67    }
68    float as f64 / pow10
69}
70
71pub fn bps_diff(x: f64, y: f64) -> u16 {
72    if x.abs() < EPSILON {
73        INF_BPS
74    } else {
75        (((y - x).abs() / (x)) * 10_000.0) as u16
76    }
77}
78
79#[derive(Copy, Clone)]
80pub enum BaseUrl {
81    Localhost,
82    Testnet,
83    Mainnet,
84}
85
86impl BaseUrl {
87    pub fn get_url(&self) -> String {
88        match self {
89            BaseUrl::Localhost => LOCAL_API_URL.to_string(),
90            BaseUrl::Mainnet => MAINNET_API_URL.to_string(),
91            BaseUrl::Testnet => TESTNET_API_URL.to_string(),
92        }
93    }
94}
95
96lazy_static! {
97    static ref CUR_NONCE: AtomicU64 = AtomicU64::new(now_timestamp_ms());
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn float_to_string_for_hashing_test() {
106        assert_eq!(float_to_string_for_hashing(0.), "0".to_string());
107        assert_eq!(float_to_string_for_hashing(-0.), "0".to_string());
108        assert_eq!(float_to_string_for_hashing(-0.0000), "0".to_string());
109        assert_eq!(
110            float_to_string_for_hashing(0.00076000),
111            "0.00076".to_string()
112        );
113        assert_eq!(
114            float_to_string_for_hashing(0.00000001),
115            "0.00000001".to_string()
116        );
117        assert_eq!(
118            float_to_string_for_hashing(0.12345678),
119            "0.12345678".to_string()
120        );
121        assert_eq!(
122            float_to_string_for_hashing(87654321.12345678),
123            "87654321.12345678".to_string()
124        );
125        assert_eq!(
126            float_to_string_for_hashing(987654321.00000000),
127            "987654321".to_string()
128        );
129        assert_eq!(
130            float_to_string_for_hashing(87654321.1234),
131            "87654321.1234".to_string()
132        );
133        assert_eq!(float_to_string_for_hashing(0.000760), "0.00076".to_string());
134        assert_eq!(float_to_string_for_hashing(0.00076), "0.00076".to_string());
135        assert_eq!(
136            float_to_string_for_hashing(987654321.0),
137            "987654321".to_string()
138        );
139        assert_eq!(
140            float_to_string_for_hashing(987654321.),
141            "987654321".to_string()
142        );
143    }
144}