nautilus_hyperliquid/common/
consts.rs1use std::{env, sync::LazyLock, time::Duration};
17
18use nautilus_model::identifiers::Venue;
19use ustr::Ustr;
20
21pub const HYPERLIQUID: &str = "HYPERLIQUID";
22pub static HYPERLIQUID_VENUE: LazyLock<Venue> =
23 LazyLock::new(|| Venue::new(Ustr::from(HYPERLIQUID)));
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum HyperliquidNetwork {
28 Mainnet,
29 Testnet,
30}
31
32impl HyperliquidNetwork {
33 pub fn from_env() -> Self {
37 match env::var("HYPERLIQUID_NET")
38 .unwrap_or_else(|_| "mainnet".to_string())
39 .to_lowercase()
40 .as_str()
41 {
42 "testnet" | "test" => HyperliquidNetwork::Testnet,
43 _ => HyperliquidNetwork::Mainnet,
44 }
45 }
46}
47
48pub const HYPERLIQUID_WS_URL: &str = "wss://api.hyperliquid.xyz/ws";
50pub const HYPERLIQUID_INFO_URL: &str = "https://api.hyperliquid.xyz/info";
51pub const HYPERLIQUID_EXCHANGE_URL: &str = "https://api.hyperliquid.xyz/exchange";
52
53pub const HYPERLIQUID_TESTNET_WS_URL: &str = "wss://api.hyperliquid-testnet.xyz/ws";
55pub const HYPERLIQUID_TESTNET_INFO_URL: &str = "https://api.hyperliquid-testnet.xyz/info";
56pub const HYPERLIQUID_TESTNET_EXCHANGE_URL: &str = "https://api.hyperliquid-testnet.xyz/exchange";
57
58pub fn ws_url(network: HyperliquidNetwork) -> &'static str {
60 match network {
61 HyperliquidNetwork::Mainnet => HYPERLIQUID_WS_URL,
62 HyperliquidNetwork::Testnet => HYPERLIQUID_TESTNET_WS_URL,
63 }
64}
65
66pub fn info_url(network: HyperliquidNetwork) -> &'static str {
68 match network {
69 HyperliquidNetwork::Mainnet => HYPERLIQUID_INFO_URL,
70 HyperliquidNetwork::Testnet => HYPERLIQUID_TESTNET_INFO_URL,
71 }
72}
73
74pub fn exchange_url(network: HyperliquidNetwork) -> &'static str {
76 match network {
77 HyperliquidNetwork::Mainnet => HYPERLIQUID_EXCHANGE_URL,
78 HyperliquidNetwork::Testnet => HYPERLIQUID_TESTNET_EXCHANGE_URL,
79 }
80}
81
82pub const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(30);
85pub const RECONNECT_BASE_BACKOFF: Duration = Duration::from_millis(250);
86pub const RECONNECT_MAX_BACKOFF: Duration = Duration::from_secs(30);
87pub const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
88pub const INFLIGHT_MAX: usize = 100;
90pub const QUEUE_MAX: usize = 1000;
91
92#[cfg(test)]
97mod tests {
98 use rstest::rstest;
99
100 use super::*;
101
102 #[rstest]
103 fn test_network_variants() {
104 assert_eq!(HyperliquidNetwork::Mainnet, HyperliquidNetwork::Mainnet);
105 assert_eq!(HyperliquidNetwork::Testnet, HyperliquidNetwork::Testnet);
106 assert_ne!(HyperliquidNetwork::Mainnet, HyperliquidNetwork::Testnet);
107 }
108
109 #[rstest]
110 fn test_network_from_env_handles_default() {
111 let network = HyperliquidNetwork::from_env();
112
113 assert!(matches!(
114 network,
115 HyperliquidNetwork::Mainnet | HyperliquidNetwork::Testnet
116 ));
117 }
118
119 #[rstest]
120 fn test_ws_url() {
121 assert_eq!(ws_url(HyperliquidNetwork::Mainnet), HYPERLIQUID_WS_URL);
122 assert_eq!(
123 ws_url(HyperliquidNetwork::Testnet),
124 HYPERLIQUID_TESTNET_WS_URL
125 );
126 }
127
128 #[rstest]
129 fn test_info_url() {
130 assert_eq!(info_url(HyperliquidNetwork::Mainnet), HYPERLIQUID_INFO_URL);
131 assert_eq!(
132 info_url(HyperliquidNetwork::Testnet),
133 HYPERLIQUID_TESTNET_INFO_URL
134 );
135 }
136
137 #[rstest]
138 fn test_exchange_url() {
139 assert_eq!(
140 exchange_url(HyperliquidNetwork::Mainnet),
141 HYPERLIQUID_EXCHANGE_URL
142 );
143 assert_eq!(
144 exchange_url(HyperliquidNetwork::Testnet),
145 HYPERLIQUID_TESTNET_EXCHANGE_URL
146 );
147 }
148
149 #[rstest]
150 fn test_constants_values() {
151 assert_eq!(HEARTBEAT_INTERVAL, Duration::from_secs(30));
152 assert_eq!(RECONNECT_BASE_BACKOFF, Duration::from_millis(250));
153 assert_eq!(RECONNECT_MAX_BACKOFF, Duration::from_secs(30));
154 assert_eq!(HTTP_TIMEOUT, Duration::from_secs(10));
155 assert_eq!(INFLIGHT_MAX, 100);
156 assert_eq!(QUEUE_MAX, 1000);
157 }
158}