nautilus_blockchain/
config.rs1use std::any::Any;
17
18use nautilus_common::factories::ClientConfig;
19use nautilus_infrastructure::sql::pg::PostgresConnectOptions;
20use nautilus_model::{
21 defi::{Chain, DexType, SharedChain},
22 identifiers::{AccountId, TraderId},
23};
24use nautilus_network::websocket::TransportBackend;
25use serde::{Deserialize, Serialize};
26
27#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
29#[serde(default, deny_unknown_fields)]
30#[cfg_attr(
31 feature = "python",
32 pyo3::pyclass(
33 module = "nautilus_trader.core.nautilus_pyo3.blockchain",
34 from_py_object
35 )
36)]
37#[cfg_attr(
38 feature = "python",
39 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.adapters.blockchain")
40)]
41pub struct DexPoolFilters {
42 #[builder(default = true)]
44 pub remove_pools_with_empty_erc20fields: bool,
45}
46
47impl Default for DexPoolFilters {
48 fn default() -> Self {
49 Self::builder().build()
50 }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
55#[serde(deny_unknown_fields)]
56#[cfg_attr(
57 feature = "python",
58 pyo3::pyclass(
59 module = "nautilus_trader.core.nautilus_pyo3.blockchain",
60 from_py_object
61 )
62)]
63#[cfg_attr(
64 feature = "python",
65 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.adapters.blockchain")
66)]
67pub struct BlockchainDataClientConfig {
68 pub chain: SharedChain,
70 #[builder(default)]
72 #[serde(default)]
73 pub dex_ids: Vec<DexType>,
74 #[builder(default)]
76 #[serde(default)]
77 pub use_hypersync_for_live_data: bool,
78 pub http_rpc_url: String,
80 pub rpc_requests_per_second: Option<u32>,
82 #[builder(default = 200)]
84 #[serde(default = "default_multicall_calls_per_rpc_request")]
85 pub multicall_calls_per_rpc_request: u32,
86 pub wss_rpc_url: Option<String>,
88 pub proxy_url: Option<String>,
90 pub from_block: Option<u64>,
92 #[builder(default)]
94 #[serde(default)]
95 pub pool_filters: DexPoolFilters,
96 pub postgres_cache_database_config: Option<PostgresConnectOptions>,
98 #[builder(default)]
100 #[serde(default)]
101 pub transport_backend: TransportBackend,
102}
103
104const fn default_multicall_calls_per_rpc_request() -> u32 {
105 200
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
109#[serde(deny_unknown_fields)]
110pub struct BlockchainExecutionClientConfig {
111 pub trader_id: TraderId,
113 pub client_id: AccountId,
115 pub chain: Chain,
117 pub wallet_address: String,
119 pub tokens: Option<Vec<String>>,
121 pub http_rpc_url: String,
123 pub rpc_requests_per_second: Option<u32>,
125 #[builder(default)]
127 #[serde(default)]
128 pub transport_backend: TransportBackend,
129}
130
131impl ClientConfig for BlockchainExecutionClientConfig {
132 fn as_any(&self) -> &dyn Any {
133 self
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use rstest::rstest;
140
141 use super::*;
142
143 #[rstest]
144 fn test_data_config_toml_minimal() {
145 let config: BlockchainDataClientConfig = toml::from_str(
146 r#"
147http_rpc_url = "https://eth-mainnet.example.com"
148
149[chain]
150name = "Ethereum"
151chain_id = 1
152hypersync_url = "https://1.hypersync.xyz"
153native_currency_decimals = 18
154"#,
155 )
156 .unwrap();
157
158 assert_eq!(config.http_rpc_url, "https://eth-mainnet.example.com");
159 assert_eq!(config.chain.chain_id, 1);
160 assert!(config.dex_ids.is_empty());
161 assert!(!config.use_hypersync_for_live_data);
162 assert_eq!(config.multicall_calls_per_rpc_request, 200);
163 assert!(config.pool_filters.remove_pools_with_empty_erc20fields);
164 assert_eq!(config.transport_backend, TransportBackend::default());
165 }
166
167 #[rstest]
168 fn test_execution_config_toml_minimal() {
169 let config: BlockchainExecutionClientConfig = toml::from_str(
170 r#"
171trader_id = "TRADER-001"
172client_id = "BLOCKCHAIN-001"
173wallet_address = "0x0000000000000000000000000000000000000000"
174http_rpc_url = "https://eth-mainnet.example.com"
175
176[chain]
177name = "Ethereum"
178chain_id = 1
179hypersync_url = "https://1.hypersync.xyz"
180native_currency_decimals = 18
181"#,
182 )
183 .unwrap();
184
185 assert_eq!(config.http_rpc_url, "https://eth-mainnet.example.com");
186 assert_eq!(config.chain.chain_id, 1);
187 assert_eq!(
188 config.wallet_address,
189 "0x0000000000000000000000000000000000000000",
190 );
191 assert!(config.tokens.is_none());
192 assert!(config.rpc_requests_per_second.is_none());
193 assert_eq!(config.transport_backend, TransportBackend::default());
194 }
195}