nautilus_derive/common/
consts.rs1use std::{sync::LazyLock, time::Duration};
25
26use nautilus_model::identifiers::{ClientId, Venue};
27use ustr::Ustr;
28
29use crate::common::enums::DeriveEnvironment;
30
31pub const DERIVE: &str = "DERIVE";
33
34pub static DERIVE_VENUE: LazyLock<Venue> = LazyLock::new(|| Venue::new(Ustr::from(DERIVE)));
36
37pub static DERIVE_CLIENT_ID: LazyLock<ClientId> =
39 LazyLock::new(|| ClientId::new(Ustr::from(DERIVE)));
40
41pub const DERIVE_NAUTILUS_REFERRAL_CODE: &str = "nautilus";
44
45pub const REST_URL_MAINNET: &str = "https://api.derive.xyz/v3";
46pub const REST_URL_TESTNET: &str = "https://testnet.api.derive.xyz/v3";
47pub const WS_URL_MAINNET: &str = "wss://api.derive.xyz/v3/ws";
48pub const WS_URL_TESTNET: &str = "wss://testnet.api.derive.xyz/v3/ws";
49
50pub const DERIVE_TRADES_PAGE_SIZE: u32 = 1000;
51pub const DERIVE_CANDLES_DEFAULT_LIMIT: usize = 1000;
52pub const DERIVE_CANDLES_MAX_PAGES: usize = 100;
53
54pub const DOMAIN_SEPARATOR_MAINNET: &str =
56 "0xda616dfabb88681b08e1592820a41d55ddc62d68de110e327ae99d734506fe19";
57
58pub const DOMAIN_SEPARATOR_TESTNET: &str =
60 "0x24d674cd5f2b9d564691c51e9d88f649b99246a2244dd74ce27b96578d773e85";
61
62pub const ACTION_TYPEHASH: &str =
64 "0x4d7a9f27c403ff9c0f19bce61d76d82f9aa29f8d6d4b0c5474607d9770d1af17";
65
66pub const TRADE_MODULE_ADDRESS_MAINNET: &str = "0xB8D20c2B7a1Ad2EE33Bc50eF10876eD3035b5e7b";
68
69pub const TRADE_MODULE_ADDRESS_TESTNET: &str = TRADE_MODULE_ADDRESS_MAINNET;
71
72pub const WITHDRAW_MODULE_ADDRESS_MAINNET: &str = "0x9d0E8f5b25384C7310CB8C6aE32C8fbeb645d083";
74
75pub const WITHDRAW_MODULE_ADDRESS_TESTNET: &str = "0xe850641C5207dc5E9423fB15f89ae6031A05fd92";
77
78pub const TRANSFER_MODULE_ADDRESS_MAINNET: &str = "0x01259207A40925b794C8ac320456F7F6c8FE2636";
80
81pub const TRANSFER_MODULE_ADDRESS_TESTNET: &str = "0x0CFC1a4a90741aB242cAfaCD798b409E12e68926";
83
84pub const DEPOSIT_MODULE_ADDRESS_MAINNET: &str = "0x9B3FE5E5a3bcEa5df4E08c41Ce89C4e3Ff01Ace3";
86
87pub const DEPOSIT_MODULE_ADDRESS_TESTNET: &str = "0x43223Db33AdA0575D2E100829543f8B04A37a1ec";
89
90#[must_use]
92pub const fn domain_separator_for(environment: DeriveEnvironment) -> &'static str {
93 match environment {
94 DeriveEnvironment::Mainnet => DOMAIN_SEPARATOR_MAINNET,
95 DeriveEnvironment::Testnet => DOMAIN_SEPARATOR_TESTNET,
96 }
97}
98
99#[must_use]
101pub const fn trade_module_address_for(environment: DeriveEnvironment) -> &'static str {
102 match environment {
103 DeriveEnvironment::Mainnet => TRADE_MODULE_ADDRESS_MAINNET,
104 DeriveEnvironment::Testnet => TRADE_MODULE_ADDRESS_TESTNET,
105 }
106}
107
108pub const HEADER_DERIVE_WALLET: &str = "X-DeriveWallet";
110
111pub const HEADER_DERIVE_TIMESTAMP: &str = "X-DeriveTimestamp";
113
114pub const HEADER_DERIVE_SIGNATURE: &str = "X-DeriveSignature";
116
117pub const MIN_SIGNATURE_TTL: Duration = Duration::from_secs(10);
121
122pub const TRIGGER_ORDER_SIGNATURE_TTL: Duration = Duration::from_secs(31 * 24 * 60 * 60);
126
127pub const DECIMAL_SCALE: u128 = 1_000_000_000_000_000_000;
129
130pub const DECIMAL_PRECISION: u32 = 12;
132
133pub const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
134pub const HTTP_MAX_RETRIES: u32 = 3;
135pub const HTTP_RETRY_DELAY_INITIAL_MS: u64 = 100;
136pub const HTTP_RETRY_DELAY_MAX_MS: u64 = 5_000;
137
138pub const DERIVE_ACCOUNT_REGISTRATION_TIMEOUT_SECS: f64 = 30.0;
141
142pub const WS_HEARTBEAT_SECS: u64 = 30;
143pub const WS_HEARTBEAT_TIMEOUT: Duration = Duration::from_mins(1);
144
145pub const RECONNECT_BASE_BACKOFF: Duration = Duration::from_millis(250);
146pub const RECONNECT_MAX_BACKOFF: Duration = Duration::from_secs(30);
147pub const RECONNECT_JITTER_MS: u64 = 200;
148pub const RECONNECT_BACKOFF_FACTOR: f64 = 2.0;
149pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(15);
150
151pub const WS_DISCONNECT_TIMEOUT: Duration = Duration::from_secs(5);
152
153pub const WS_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
157
158#[cfg(test)]
159mod tests {
160 use rstest::rstest;
161
162 use super::*;
163
164 #[rstest]
165 fn test_venue_constant() {
166 assert_eq!(DERIVE_VENUE.as_str(), DERIVE);
167 }
168
169 #[rstest]
170 fn test_url_constants_have_expected_schemes() {
171 assert!(REST_URL_MAINNET.starts_with("https://"));
172 assert!(REST_URL_TESTNET.starts_with("https://"));
173 assert!(WS_URL_MAINNET.starts_with("wss://"));
174 assert!(WS_URL_TESTNET.starts_with("wss://"));
175 }
176
177 #[rstest]
178 fn test_decimal_scale_is_1e18() {
179 assert_eq!(DECIMAL_SCALE, 10u128.pow(18));
180 }
181
182 #[rstest]
183 fn test_min_signature_ttl_is_ten_seconds() {
184 assert_eq!(MIN_SIGNATURE_TTL, Duration::from_secs(10));
185 }
186
187 #[rstest]
188 fn test_trigger_order_signature_ttl_is_thirty_one_days() {
189 assert_eq!(
190 TRIGGER_ORDER_SIGNATURE_TTL,
191 Duration::from_secs(31 * 24 * 60 * 60),
192 );
193 }
194
195 #[rstest]
196 fn test_domain_separator_for_routes_per_environment() {
197 assert_eq!(
198 domain_separator_for(DeriveEnvironment::Mainnet),
199 DOMAIN_SEPARATOR_MAINNET,
200 );
201 assert_eq!(
202 domain_separator_for(DeriveEnvironment::Testnet),
203 DOMAIN_SEPARATOR_TESTNET,
204 );
205 }
206
207 #[rstest]
208 fn test_trade_module_address_for_routes_per_environment() {
209 assert_eq!(
210 trade_module_address_for(DeriveEnvironment::Mainnet),
211 TRADE_MODULE_ADDRESS_MAINNET,
212 );
213 assert_eq!(
214 trade_module_address_for(DeriveEnvironment::Testnet),
215 TRADE_MODULE_ADDRESS_TESTNET,
216 );
217 }
218}