nautilus_hyperliquid/common/
consts.rs1use std::{sync::LazyLock, time::Duration};
17
18use nautilus_model::{
19 enums::OrderType,
20 identifiers::{ClientId, Venue},
21};
22use ustr::Ustr;
23
24use super::enums::HyperliquidEnvironment;
25
26pub const HYPERLIQUID: &str = "HYPERLIQUID";
28
29pub static HYPERLIQUID_VENUE: LazyLock<Venue> =
31 LazyLock::new(|| Venue::new(Ustr::from(HYPERLIQUID)));
32
33pub static HYPERLIQUID_CLIENT_ID: LazyLock<ClientId> =
35 LazyLock::new(|| ClientId::new(Ustr::from(HYPERLIQUID)));
36
37pub const HYPERLIQUID_WS_URL: &str = "wss://api.hyperliquid.xyz/ws";
38pub const HYPERLIQUID_INFO_URL: &str = "https://api.hyperliquid.xyz/info";
39pub const HYPERLIQUID_EXCHANGE_URL: &str = "https://api.hyperliquid.xyz/exchange";
40
41pub const HYPERLIQUID_TESTNET_WS_URL: &str = "wss://api.hyperliquid-testnet.xyz/ws";
42pub const HYPERLIQUID_TESTNET_INFO_URL: &str = "https://api.hyperliquid-testnet.xyz/info";
43pub const HYPERLIQUID_TESTNET_EXCHANGE_URL: &str = "https://api.hyperliquid-testnet.xyz/exchange";
44
45pub(crate) const HYPERLIQUID_REST_WEIGHT_PER_MINUTE: u32 = 1_200;
46pub(crate) const HYPERLIQUID_WS_MESSAGES_PER_MINUTE: u32 = 2_000;
47pub(crate) const HYPERLIQUID_WS_CONNECTIONS_MAX: usize = 10;
48pub(crate) const HYPERLIQUID_WS_CONNECTIONS_PER_MINUTE: u32 = 30;
49pub(crate) const HYPERLIQUID_WS_SUBSCRIPTIONS_MAX: usize = 1_000;
50pub(crate) const HYPERLIQUID_WS_SUBSCRIPTION_USERS_MAX: usize = 10;
51pub(crate) const HYPERLIQUID_WS_POST_INFLIGHT_MAX: usize = 100;
52pub const INFLIGHT_MAX: usize = HYPERLIQUID_WS_POST_INFLIGHT_MAX;
53
54pub const NAUTILUS_BUILDER_ADDRESS: &str = "0x0c8d970c462726e014ad36f6c5a63e99db48a8e7";
57
58pub const HYPERLIQUID_BUILDER_APPROVAL_DOCS_URL: &str =
60 "https://nautilustrader.io/docs/nightly/integrations/hyperliquid/#builder-fee-approval";
61
62pub const HYPERLIQUID_CHAIN_ID: u64 = 421614;
64
65pub const ASSET_INDEX_INFO_KEY: &str = "asset_index";
70
71pub const HYPERLIQUID_POST_ONLY_WOULD_MATCH: &str =
73 "Post only order would have immediately matched";
74pub const HYPERLIQUID_BUILDER_FEE_NOT_APPROVED: &str = "Builder fee has not been approved";
75
76pub const HYPERLIQUID_SUPPORTED_ORDER_TYPES: &[OrderType] = &[
91 OrderType::Market, OrderType::Limit, OrderType::StopMarket, OrderType::StopLimit, OrderType::MarketIfTouched, OrderType::LimitIfTouched, ];
98
99pub const HYPERLIQUID_CONDITIONAL_ORDER_TYPES: &[OrderType] = &[
104 OrderType::StopMarket,
105 OrderType::StopLimit,
106 OrderType::MarketIfTouched,
107 OrderType::LimitIfTouched,
108];
109
110pub fn ws_url(environment: HyperliquidEnvironment) -> &'static str {
112 match environment {
113 HyperliquidEnvironment::Testnet => HYPERLIQUID_TESTNET_WS_URL,
114 HyperliquidEnvironment::Mainnet => HYPERLIQUID_WS_URL,
115 }
116}
117
118pub fn info_url(environment: HyperliquidEnvironment) -> &'static str {
120 match environment {
121 HyperliquidEnvironment::Testnet => HYPERLIQUID_TESTNET_INFO_URL,
122 HyperliquidEnvironment::Mainnet => HYPERLIQUID_INFO_URL,
123 }
124}
125
126pub fn exchange_url(environment: HyperliquidEnvironment) -> &'static str {
128 match environment {
129 HyperliquidEnvironment::Testnet => HYPERLIQUID_TESTNET_EXCHANGE_URL,
130 HyperliquidEnvironment::Mainnet => HYPERLIQUID_EXCHANGE_URL,
131 }
132}
133
134pub const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(30);
137pub const RECONNECT_BASE_BACKOFF: Duration = Duration::from_millis(250);
138pub const RECONNECT_MAX_BACKOFF: Duration = Duration::from_secs(30);
139pub const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
140pub const QUEUE_MAX: usize = 1000;
141
142#[cfg(test)]
143mod tests {
144 use rstest::rstest;
145
146 use super::*;
147
148 #[rstest]
149 fn test_ws_url() {
150 assert_eq!(ws_url(HyperliquidEnvironment::Mainnet), HYPERLIQUID_WS_URL);
151 assert_eq!(
152 ws_url(HyperliquidEnvironment::Testnet),
153 HYPERLIQUID_TESTNET_WS_URL
154 );
155 }
156
157 #[rstest]
158 fn test_info_url() {
159 assert_eq!(
160 info_url(HyperliquidEnvironment::Mainnet),
161 HYPERLIQUID_INFO_URL
162 );
163 assert_eq!(
164 info_url(HyperliquidEnvironment::Testnet),
165 HYPERLIQUID_TESTNET_INFO_URL
166 );
167 }
168
169 #[rstest]
170 fn test_exchange_url() {
171 assert_eq!(
172 exchange_url(HyperliquidEnvironment::Mainnet),
173 HYPERLIQUID_EXCHANGE_URL
174 );
175 assert_eq!(
176 exchange_url(HyperliquidEnvironment::Testnet),
177 HYPERLIQUID_TESTNET_EXCHANGE_URL
178 );
179 }
180
181 #[rstest]
182 fn test_constants_values() {
183 assert_eq!(HEARTBEAT_INTERVAL, Duration::from_secs(30));
184 assert_eq!(RECONNECT_BASE_BACKOFF, Duration::from_millis(250));
185 assert_eq!(RECONNECT_MAX_BACKOFF, Duration::from_secs(30));
186 assert_eq!(HTTP_TIMEOUT, Duration::from_secs(10));
187 assert_eq!(HYPERLIQUID_REST_WEIGHT_PER_MINUTE, 1_200);
188 assert_eq!(HYPERLIQUID_WS_MESSAGES_PER_MINUTE, 2_000);
189 assert_eq!(HYPERLIQUID_WS_CONNECTIONS_MAX, 10);
190 assert_eq!(HYPERLIQUID_WS_CONNECTIONS_PER_MINUTE, 30);
191 assert_eq!(HYPERLIQUID_WS_SUBSCRIPTIONS_MAX, 1_000);
192 assert_eq!(HYPERLIQUID_WS_SUBSCRIPTION_USERS_MAX, 10);
193 assert_eq!(HYPERLIQUID_WS_POST_INFLIGHT_MAX, 100);
194 assert_eq!(INFLIGHT_MAX, HYPERLIQUID_WS_POST_INFLIGHT_MAX);
195 assert_eq!(QUEUE_MAX, 1000);
196 }
197}