Skip to main content

tycho_simulation/rfq/
constants.rs

1use std::{env, str::FromStr};
2
3use tycho_common::Bytes;
4
5use crate::rfq::errors::RFQError;
6
7pub const DEFAULT_METRIC_API_URL: &str = "http://54.199.103.16:8080";
8
9/// Hashflow authentication configuration
10pub struct HashflowAuth {
11    pub user: String,
12    pub key: String,
13}
14
15/// Bebop authentication configuration
16pub struct BebopAuth {
17    pub key: String,
18}
19
20/// Metric API configuration
21pub struct MetricConfig {
22    pub base_url: String,
23    pub secret_key: Option<String>,
24}
25
26/// Read Hashflow authentication from environment variables
27/// Returns the HASHFLOW_USER and HASHFLOW_KEY environment variables
28pub fn get_hashflow_auth() -> Result<HashflowAuth, RFQError> {
29    let user = env::var("HASHFLOW_USER").map_err(|_| {
30        RFQError::InvalidInput("HASHFLOW_USER environment variable is required".into())
31    })?;
32
33    let key = env::var("HASHFLOW_KEY").map_err(|_| {
34        RFQError::InvalidInput("HASHFLOW_KEY environment variable is required".into())
35    })?;
36
37    Ok(HashflowAuth { user, key })
38}
39
40/// Liquorice authentication configuration
41pub struct LiquoriceAuth {
42    pub solver: String,
43    pub key: String,
44}
45
46/// Read Liquorice authentication from environment variables
47/// Returns the LIQUORICE_USER and LIQUORICE_KEY environment variables
48pub fn get_liquorice_auth() -> Result<LiquoriceAuth, RFQError> {
49    let solver = env::var("LIQUORICE_USER").map_err(|_| {
50        RFQError::InvalidInput("LIQUORICE_USER environment variable is required".into())
51    })?;
52
53    let key = env::var("LIQUORICE_KEY").map_err(|_| {
54        RFQError::InvalidInput("LIQUORICE_KEY environment variable is required".into())
55    })?;
56
57    Ok(LiquoriceAuth { solver, key })
58}
59
60/// Read Bebop authentication from environment variables
61/// Returns the BEBOP_KEY environment variable
62pub fn get_bebop_auth() -> Result<BebopAuth, RFQError> {
63    let key = env::var("BEBOP_KEY")
64        .map_err(|_| RFQError::InvalidInput("BEBOP_KEY environment variable is required".into()))?;
65
66    Ok(BebopAuth { key })
67}
68
69/// Bebop origin identification, sent with binding quote requests. Bebop can configure API
70/// accounts to require these fields. See the `BebopClientBuilder` docs for their meaning.
71#[derive(Debug, Default)]
72pub struct BebopOrigins {
73    pub address: Option<Bytes>,
74    pub target: Option<Bytes>,
75    pub source: Option<String>,
76}
77
78/// Read optional Bebop origin identification from the BEBOP_ORIGIN_ADDRESS,
79/// BEBOP_ORIGIN_TARGET and BEBOP_ORIGIN_SOURCE environment variables.
80///
81/// Unset variables yield `None`; a set but unparseable address is an error.
82pub fn get_bebop_origins() -> Result<BebopOrigins, RFQError> {
83    let parse_address = |var: &str| -> Result<Option<Bytes>, RFQError> {
84        match env::var(var) {
85            Ok(value) => Bytes::from_str(&value)
86                .map(Some)
87                .map_err(|e| RFQError::InvalidInput(format!("Invalid {var}: {e}"))),
88            Err(_) => Ok(None),
89        }
90    };
91    Ok(BebopOrigins {
92        address: parse_address("BEBOP_ORIGIN_ADDRESS")?,
93        target: parse_address("BEBOP_ORIGIN_TARGET")?,
94        source: env::var("BEBOP_ORIGIN_SOURCE").ok(),
95    })
96}
97
98/// Read Metric API configuration from environment variables.
99/// METRIC_API_URL defaults to the public Metric endpoint; METRIC_SECRET_KEY is optional.
100pub fn get_metric_config() -> MetricConfig {
101    let base_url = env::var("METRIC_API_URL")
102        .ok()
103        .filter(|url| !url.trim().is_empty())
104        .unwrap_or_else(|| DEFAULT_METRIC_API_URL.to_string());
105    let secret_key = env::var("METRIC_SECRET_KEY")
106        .ok()
107        .filter(|key| !key.trim().is_empty());
108
109    MetricConfig { base_url, secret_key }
110}
111
112#[cfg(test)]
113mod tests {
114    use std::env;
115
116    use super::*;
117
118    #[test]
119    fn test_hashflow_auth_success() {
120        env::set_var("HASHFLOW_USER", "test_user");
121        env::set_var("HASHFLOW_KEY", "test_key");
122
123        let auth = get_hashflow_auth().unwrap();
124        assert_eq!(auth.user, "test_user");
125        assert_eq!(auth.key, "test_key");
126
127        env::remove_var("HASHFLOW_USER");
128        env::remove_var("HASHFLOW_KEY");
129    }
130
131    #[test]
132    fn test_hashflow_auth_missing_user() {
133        env::remove_var("HASHFLOW_USER");
134        env::set_var("HASHFLOW_KEY", "test_key");
135
136        let result = get_hashflow_auth();
137        assert!(result.is_err());
138
139        env::remove_var("HASHFLOW_KEY");
140    }
141
142    #[test]
143    fn test_hashflow_auth_missing_key() {
144        env::set_var("HASHFLOW_USER", "test_user");
145        env::remove_var("HASHFLOW_KEY");
146
147        let result = get_hashflow_auth();
148        assert!(result.is_err());
149
150        env::remove_var("HASHFLOW_USER");
151    }
152
153    #[test]
154    fn test_bebop_auth_success() {
155        env::set_var("BEBOP_KEY", "test_key");
156
157        let auth = get_bebop_auth().unwrap();
158        assert_eq!(auth.key, "test_key");
159
160        env::remove_var("BEBOP_KEY");
161    }
162
163    #[test]
164    fn test_bebop_auth_missing_key() {
165        env::remove_var("BEBOP_KEY");
166
167        let result = get_bebop_auth();
168        assert!(result.is_err());
169    }
170
171    #[test]
172    fn test_metric_config_defaults_and_reads_env() {
173        env::remove_var("METRIC_API_URL");
174        env::remove_var("METRIC_SECRET_KEY");
175
176        let config = get_metric_config();
177        assert_eq!(config.base_url, DEFAULT_METRIC_API_URL);
178        assert_eq!(config.secret_key, None);
179
180        env::set_var("METRIC_API_URL", "https://metric.example");
181        env::set_var("METRIC_SECRET_KEY", "secret");
182
183        let config = get_metric_config();
184        assert_eq!(config.base_url, "https://metric.example");
185        assert_eq!(config.secret_key.as_deref(), Some("secret"));
186
187        env::remove_var("METRIC_API_URL");
188        env::remove_var("METRIC_SECRET_KEY");
189    }
190}