hyperliquid_rust_sdk_abrkn/
helpers.rs1use 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 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}