node_test/
node_test.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::sync::Arc;
17
18use nautilus_blockchain::{
19    config::BlockchainAdapterConfig,
20    factories::{BlockchainClientConfig, BlockchainDataClientFactory},
21};
22use nautilus_common::enums::Environment;
23use nautilus_core::env::get_env_var;
24use nautilus_live::node::LiveNode;
25use nautilus_model::{
26    defi::chain::{Blockchain, Chain, chains},
27    identifiers::TraderId,
28};
29use tokio::time::Duration;
30
31// Run with `cargo run -p nautilus-blockchain --bin node_test --features hypersync,python`
32
33#[tokio::main]
34async fn main() -> Result<(), Box<dyn std::error::Error>> {
35    // TODO: Initialize Python interpreter only if python feature is enabled
36    // #[cfg(feature = "python")]
37    pyo3::prepare_freethreaded_python();
38
39    dotenvy::dotenv().ok();
40
41    let environment = Environment::Live;
42    let trader_id = TraderId::default();
43    let node_name = "TESTER-001".to_string();
44
45    let chain: Chain = match std::env::var("CHAIN")
46        .ok()
47        .and_then(|s| s.parse::<Blockchain>().ok())
48    {
49        Some(Blockchain::Ethereum) => chains::ETHEREUM.clone(),
50        Some(Blockchain::Base) => chains::BASE.clone(),
51        Some(Blockchain::Arbitrum) => chains::ARBITRUM.clone(),
52        Some(Blockchain::Polygon) => chains::POLYGON.clone(),
53        _ => {
54            println!("⚠️  No valid CHAIN env var found, using Ethereum as default");
55            chains::ETHEREUM.clone()
56        }
57    };
58
59    let chain = Arc::new(chain);
60    println!("   - Using chain: {}", chain.name);
61
62    // Try to get RPC URLs from environment, fallback to test values if not available
63    let http_rpc_url = get_env_var("RPC_HTTP_URL").unwrap_or_else(|_| {
64        println!("⚠️  RPC_HTTP_URL not found, using placeholder");
65        "https://eth-mainnet.example.com".to_string()
66    });
67    let wss_rpc_url = get_env_var("RPC_WSS_URL").ok();
68
69    let blockchain_config = BlockchainAdapterConfig::new(
70        http_rpc_url,
71        None, // HyperSync URL not needed for this test
72        wss_rpc_url,
73        false, // Don't cache locally for this test
74    );
75
76    let client_factory = Box::new(BlockchainDataClientFactory::new());
77    let client_config = BlockchainClientConfig::new(blockchain_config, chain.clone());
78
79    let mut node = LiveNode::builder(node_name, trader_id, environment)?
80        .with_load_state(false)
81        .with_save_state(false)
82        .add_data_client(
83            None, // Use factory name
84            client_factory,
85            Box::new(client_config),
86        )?
87        .build()?;
88
89    node.start().await?;
90
91    // Let it run briefly to ensure all components are properly initialized
92    tokio::time::sleep(Duration::from_millis(100)).await;
93
94    node.stop().await?;
95
96    Ok(())
97}
98
99#[cfg(not(feature = "hypersync"))]
100fn main() {
101    println!("⚠️  kernel_test binary requires the 'hypersync' feature to be enabled.");
102    println!("   Run with: cargo run --bin kernel_test --features hypersync");
103    std::process::exit(1);
104}