nautilus_blockchain/
factories.rs1use std::{any::Any, cell::RefCell, rc::Rc};
19
20use nautilus_common::{cache::Cache, clock::Clock};
21use nautilus_data::client::DataClient;
22use nautilus_system::factories::{ClientConfig, DataClientFactory};
23
24use crate::{config::BlockchainDataClientConfig, data::client::BlockchainDataClient};
25
26impl ClientConfig for BlockchainDataClientConfig {
27 fn as_any(&self) -> &dyn Any {
28 self
29 }
30}
31
32#[derive(Debug, Clone)]
37#[cfg_attr(
38 feature = "python",
39 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.blockchain")
40)]
41pub struct BlockchainDataClientFactory;
42
43impl BlockchainDataClientFactory {
44 #[must_use]
46 pub const fn new() -> Self {
47 Self
48 }
49}
50
51impl Default for BlockchainDataClientFactory {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl DataClientFactory for BlockchainDataClientFactory {
58 fn create(
59 &self,
60 _name: &str,
61 config: &dyn ClientConfig,
62 _cache: Rc<RefCell<Cache>>,
63 _clock: Rc<RefCell<dyn Clock>>,
64 ) -> anyhow::Result<Box<dyn DataClient>> {
65 let blockchain_config = config
66 .as_any()
67 .downcast_ref::<BlockchainDataClientConfig>()
68 .ok_or_else(|| {
69 anyhow::anyhow!(
70 "Invalid config type for BlockchainDataClientFactory. Expected `BlockchainDataClientConfig`, was {config:?}"
71 )
72 })?;
73
74 let client = BlockchainDataClient::new(blockchain_config.clone());
75
76 Ok(Box::new(client))
77 }
78
79 fn name(&self) -> &'static str {
80 "BLOCKCHAIN"
81 }
82
83 fn config_type(&self) -> &'static str {
84 "BlockchainDataClientConfig"
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use std::sync::Arc;
91
92 use nautilus_model::defi::chain::{Blockchain, chains};
93 use nautilus_system::factories::DataClientFactory;
94 use rstest::rstest;
95
96 use crate::{config::BlockchainDataClientConfig, factories::BlockchainDataClientFactory};
97
98 #[rstest]
99 fn test_blockchain_data_client_config_creation() {
100 let chain = Arc::new(chains::ETHEREUM.clone());
101 let config = BlockchainDataClientConfig::new(
102 chain,
103 vec![],
104 "https://eth-mainnet.example.com".to_string(),
105 None,
106 None,
107 None,
108 false,
109 None,
110 None,
111 None,
112 );
113
114 assert_eq!(config.chain.name, Blockchain::Ethereum);
115 assert_eq!(config.http_rpc_url, "https://eth-mainnet.example.com");
116 }
117
118 #[rstest]
119 fn test_factory_creation() {
120 let factory = BlockchainDataClientFactory::new();
121 assert_eq!(factory.name(), "BLOCKCHAIN");
122 assert_eq!(factory.config_type(), "BlockchainDataClientConfig");
123 }
124}