kabu_core_components/
kabu_builder.rs

1use crate::traits::{
2    BroadcasterBuilder, EstimatorBuilder, ExecutorBuilder, HealthMonitorBuilder, MarketBuilder, MergerBuilder, MonitoringBuilder,
3    NetworkBuilder, PoolBuilder, SignerBuilder, StrategyBuilder, WebServerBuilder,
4};
5use crate::{BuilderContext, KabuComponentsSet, KabuNode, KabuNodeComponentsBuilder, KabuNodeTypes, MevComponentChannels};
6use eyre::Result;
7use reth_tasks::TaskExecutor;
8use std::marker::PhantomData;
9
10/// Kabu MEV bot builder - follows Reth's builder pattern
11pub struct KabuBuilder<State, Node = ()> {
12    state: State,
13    node: Node,
14}
15
16impl<State> KabuBuilder<State, ()> {
17    /// Create a new Kabu builder with the given state
18    pub fn new(state: State) -> Self {
19        Self { state, node: () }
20    }
21}
22
23impl<State> KabuBuilder<State, ()> {
24    pub fn node<N>(self, node: N) -> KabuBuilder<State, N>
25    where
26        N: KabuNode<N> + KabuNodeTypes,
27    {
28        KabuBuilder { state: self.state, node }
29    }
30}
31
32impl<State, N> KabuBuilder<State, N>
33where
34    N: KabuNode<N> + KabuNodeTypes<State = State>,
35    State: Clone + Send + Sync + 'static,
36{
37    /// Build the node with the configured components
38    pub fn build(self) -> KabuBuiltNode<State, N> {
39        KabuBuiltNode { state: self.state, node: self.node }
40    }
41}
42
43/// A built Kabu node ready to be launched
44pub struct KabuBuiltNode<State, N: KabuNode<N> + KabuNodeTypes> {
45    state: State,
46    node: N,
47}
48
49impl<State, N> KabuBuiltNode<State, N>
50where
51    N: KabuNode<N> + KabuNodeTypes<State = State>,
52    State: Clone + Send + Sync + 'static,
53{
54    /// Launch the node with the given task executor
55    pub async fn launch(self, executor: TaskExecutor) -> Result<KabuHandle> {
56        // Create channels
57        let channels = MevComponentChannels::default();
58
59        // Create builder context
60        let context = BuilderContext::with_channels(self.state.clone(), channels.clone());
61
62        // Get component builders from the node
63        let components_builder = self.node.components_builder();
64        let components_set = components_builder.build_components();
65
66        // Build and spawn all components
67        self.spawn_all_components(context, components_set, executor).await?;
68
69        Ok(KabuHandle { _phantom: PhantomData })
70    }
71
72    /// Launch with custom channels
73    pub async fn launch_with_channels(self, executor: TaskExecutor, channels: MevComponentChannels) -> Result<KabuHandle> {
74        // Create builder context with custom channels
75        let context = BuilderContext::with_channels(self.state.clone(), channels);
76
77        // Get component builders from the node
78        let components_builder = self.node.components_builder();
79        let components_set = components_builder.build_components();
80
81        // Build and spawn all components
82        self.spawn_all_components(context, components_set, executor).await?;
83
84        Ok(KabuHandle { _phantom: PhantomData })
85    }
86
87    async fn spawn_all_components<CB>(
88        &self,
89        context: BuilderContext<State>,
90        components: KabuComponentsSet<State, CB, N>,
91        executor: TaskExecutor,
92    ) -> Result<()>
93    where
94        CB: KabuNodeComponentsBuilder<N>,
95    {
96        // Build components in dependency order
97        let pool = components.pool.build_pool(&context).await?;
98        let network = components.network.build_network(&context).await?;
99        let market = components.market.build_market(&context).await?;
100        let estimator = components.estimator.build_estimator(&context).await?;
101        let strategy = components.strategy.build_strategy(&context).await?;
102        let merger = components.merger.build_merger(&context).await?;
103        let executor_comp = components.executor.build_executor(&context).await?;
104        let signer = components.signer.build_signer(&context).await?;
105        let broadcaster = components.broadcaster.build_broadcaster(&context).await?;
106        let health_monitor = components.health_monitor.build_health_monitor(&context).await?;
107        let web_server = components.web_server.build_web_server(&context).await?;
108        let monitoring = components.monitoring.build_monitoring(&context).await?;
109
110        // Spawn components in dependency order
111        use crate::Component;
112
113        market.spawn(executor.clone())?;
114        pool.spawn(executor.clone())?;
115        network.spawn(executor.clone())?;
116        estimator.spawn(executor.clone())?;
117        strategy.spawn(executor.clone())?;
118        merger.spawn(executor.clone())?;
119        executor_comp.spawn(executor.clone())?;
120        signer.spawn(executor.clone())?;
121        broadcaster.spawn(executor.clone())?;
122        health_monitor.spawn(executor.clone())?;
123        web_server.spawn(executor.clone())?;
124        monitoring.spawn(executor)?;
125
126        Ok(())
127    }
128}
129
130/// Handle to a running Kabu node
131pub struct KabuHandle {
132    _phantom: PhantomData<()>,
133}
134
135impl KabuHandle {
136    /// Wait for the node to shutdown
137    pub async fn wait_for_shutdown(self) -> Result<()> {
138        // In a real implementation, this would wait for shutdown signals
139        tokio::signal::ctrl_c().await?;
140        Ok(())
141    }
142}