use crate::common::consts::{info_url, ws_url};
#[derive(Clone, Debug, bon::Builder)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.hyperliquid",
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.hyperliquid")
)]
pub struct HyperliquidDataClientConfig {
pub private_key: Option<String>,
pub base_url_ws: Option<String>,
pub base_url_http: Option<String>,
pub http_proxy_url: Option<String>,
pub ws_proxy_url: Option<String>,
#[builder(default)]
pub is_testnet: bool,
#[builder(default = 60)]
pub http_timeout_secs: u64,
#[builder(default = 30)]
pub ws_timeout_secs: u64,
#[builder(default = 60)]
pub update_instruments_interval_mins: u64,
}
impl Default for HyperliquidDataClientConfig {
fn default() -> Self {
Self::builder().build()
}
}
impl HyperliquidDataClientConfig {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn has_credentials(&self) -> bool {
self.private_key
.as_deref()
.is_some_and(|s| !s.trim().is_empty())
}
#[must_use]
pub fn ws_url(&self) -> String {
self.base_url_ws
.clone()
.unwrap_or_else(|| ws_url(self.is_testnet).to_string())
}
#[must_use]
pub fn http_url(&self) -> String {
self.base_url_http
.clone()
.unwrap_or_else(|| info_url(self.is_testnet).to_string())
}
}
#[derive(Clone, Debug, bon::Builder)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.hyperliquid",
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.hyperliquid")
)]
pub struct HyperliquidExecClientConfig {
pub private_key: Option<String>,
pub vault_address: Option<String>,
pub account_address: Option<String>,
pub base_url_ws: Option<String>,
pub base_url_http: Option<String>,
pub base_url_exchange: Option<String>,
pub http_proxy_url: Option<String>,
pub ws_proxy_url: Option<String>,
#[builder(default)]
pub is_testnet: bool,
#[builder(default = 60)]
pub http_timeout_secs: u64,
#[builder(default = 3)]
pub max_retries: u32,
#[builder(default = 100)]
pub retry_delay_initial_ms: u64,
#[builder(default = 5000)]
pub retry_delay_max_ms: u64,
#[builder(default = true)]
pub normalize_prices: bool,
}
impl Default for HyperliquidExecClientConfig {
fn default() -> Self {
Self::builder().build()
}
}
impl HyperliquidExecClientConfig {
#[must_use]
pub fn new(private_key: Option<String>) -> Self {
Self {
private_key,
..Self::default()
}
}
#[must_use]
pub fn has_credentials(&self) -> bool {
self.private_key
.as_deref()
.is_some_and(|s| !s.trim().is_empty())
}
#[must_use]
pub fn ws_url(&self) -> String {
self.base_url_ws
.clone()
.unwrap_or_else(|| ws_url(self.is_testnet).to_string())
}
#[must_use]
pub fn http_url(&self) -> String {
self.base_url_http
.clone()
.unwrap_or_else(|| info_url(self.is_testnet).to_string())
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
fn test_exec_config_default_account_address_is_none() {
let config = HyperliquidExecClientConfig::default();
assert!(config.account_address.is_none());
}
#[rstest]
fn test_exec_config_with_account_address() {
let config = HyperliquidExecClientConfig {
account_address: Some("0x1234".to_string()),
..HyperliquidExecClientConfig::default()
};
assert_eq!(config.account_address.as_deref(), Some("0x1234"));
}
}