bot_cli/config.rs
1//! Bot CLI configuration types - V2 format.
2//!
3//! Strategy config structs (`GridConfigJson`, `MMConfigJson`, etc.) are defined
4//! once in `bot-engine` and re-exported here. Only CLI/schema-specific types
5//! (`BotConfig`, `MarketConfig`, `Hip3ConfigJson`, `InstrumentMetaConfig`) live here.
6//!
7//! This avoids duplication: adding a new strategy config means adding it once
8//! in `bot-engine/src/config.rs` — it's automatically available here.
9
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12
13// Re-export strategy config structs from bot-engine (single source of truth)
14pub use bot_engine::{
15 ArbitrageConfigJson, BuilderFeeConfig, DCAConfigJson, GridConfigJson, MMConfigJson,
16 OrchestratorConfigJson, SyncConfigJson,
17};
18
19/// V2 Bot configuration - the full config format for all strategies.
20///
21/// This is the **schema-generation** version of BotConfig. It uses flat
22/// `MarketConfig` structs (for clean JSON Schema output), unlike the engine's
23/// `BotConfig` which uses typed `bot_core::Market` enums for runtime parsing.
24#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
25pub struct BotConfig {
26 /// Environment: "testnet" or "mainnet"
27 pub environment: String,
28
29 /// Private key (hex, with or without 0x prefix)
30 pub private_key: String,
31
32 /// Wallet address
33 pub address: String,
34
35 /// Optional vault address
36 #[serde(default)]
37 pub vault_address: Option<String>,
38
39 /// Optional Hyperliquid base URL override.
40 /// When set, both /info and /exchange requests use this gateway.
41 #[serde(default)]
42 pub base_url_override: Option<String>,
43
44 /// Strategy type: "grid", "mm", "dca", "arbitrage", or "orchestrator"
45 pub strategy_type: String,
46
47 /// Markets to trade on (V2 format)
48 #[serde(default)]
49 pub markets: Vec<MarketConfig>,
50
51 /// Polling delay in milliseconds
52 #[serde(default = "default_poll_delay_ms")]
53 pub poll_delay_ms: u64,
54
55 // -------------------------------------------------------------------------
56 // Strategy-specific config objects (only one should be set)
57 // -------------------------------------------------------------------------
58 /// Grid strategy configuration
59 #[serde(default)]
60 pub grid: Option<GridConfigJson>,
61
62 /// Market Maker strategy configuration
63 #[serde(default)]
64 pub mm: Option<MMConfigJson>,
65
66 /// DCA strategy configuration
67 #[serde(default)]
68 pub dca: Option<DCAConfigJson>,
69
70 /// Arbitrage strategy configuration
71 #[serde(default)]
72 pub arbitrage: Option<ArbitrageConfigJson>,
73
74 /// Orchestrator strategy configuration
75 #[serde(default)]
76 pub orchestrator: Option<OrchestratorConfigJson>,
77
78 // -------------------------------------------------------------------------
79 // Common config
80 // -------------------------------------------------------------------------
81 /// Builder fee configuration
82 #[serde(default)]
83 pub builder_fee: Option<BuilderFeeConfig>,
84
85 /// HIP-3 configuration
86 #[serde(default)]
87 pub hip3: Option<Hip3ConfigJson>,
88
89 /// Trade sync configuration
90 #[serde(default)]
91 pub sync: Option<SyncConfigJson>,
92}
93
94// =============================================================================
95// CLI-specific types (not in bot-engine)
96// =============================================================================
97
98/// Market configuration (V2 format) — flat representation for JSON Schema.
99///
100/// The engine uses `bot_core::Market` (tagged enum) instead. This flat struct
101/// exists so the generated JSON Schema is clean for external consumers.
102#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
103pub struct MarketConfig {
104 /// Exchange name (e.g., "hyperliquid")
105 pub exchange: String,
106
107 /// Market type: "perp", "spot", "hip3", or "outcome"
108 #[serde(rename = "type")]
109 pub market_type: String,
110
111 /// Base asset (e.g., "BTC")
112 pub base: String,
113
114 /// Quote asset (e.g., "USDC")
115 #[serde(default)]
116 pub quote: Option<String>,
117
118 /// Market index
119 #[serde(default)]
120 pub index: Option<u32>,
121
122 /// DEX name (for HIP-3)
123 #[serde(default)]
124 pub dex: Option<String>,
125
126 /// Human-readable outcome name (for prediction markets)
127 #[serde(default)]
128 pub name: Option<String>,
129
130 /// Outcome ID from outcomeMeta (for prediction markets)
131 #[serde(default)]
132 pub outcome_id: Option<u32>,
133
134 /// Outcome side: 0 = Yes, 1 = No
135 #[serde(default)]
136 pub side: Option<u8>,
137
138 /// Instrument metadata
139 #[serde(default)]
140 pub instrument_meta: Option<InstrumentMetaConfig>,
141}
142
143/// HIP-3 configuration
144#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
145pub struct Hip3ConfigJson {
146 /// The HIP-3 DEX name
147 pub dex_name: String,
148
149 /// The index of the DEX
150 pub dex_index: u32,
151
152 /// Quote currency: "USDC" or "USDH"
153 #[serde(default = "default_quote_currency")]
154 pub quote_currency: String,
155
156 /// Asset index within the DEX
157 #[serde(default)]
158 pub asset_index: u32,
159}
160
161/// Instrument metadata configuration
162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
163pub struct InstrumentMetaConfig {
164 /// Tick size (price precision)
165 pub tick_size: String,
166
167 /// Lot size (quantity precision)
168 pub lot_size: String,
169
170 /// Minimum order quantity
171 #[serde(default)]
172 pub min_qty: Option<String>,
173
174 /// Minimum notional value
175 #[serde(default)]
176 pub min_notional: Option<String>,
177}
178
179// =============================================================================
180// Default value functions (only for CLI-specific types)
181// =============================================================================
182
183fn default_poll_delay_ms() -> u64 {
184 500
185}
186
187fn default_quote_currency() -> String {
188 "USDC".to_string()
189}