tycho_simulation/rfq/protocols/hashflow/
client_builder.rs

1use std::collections::HashSet;
2
3use tokio::time::Duration;
4use tycho_common::{models::Chain, Bytes};
5
6use super::client::HashflowClient;
7use crate::rfq::{errors::RFQError, protocols::utils::default_quote_tokens_for_chain};
8
9/// `HashflowClientBuilder` is a builder pattern implementation for creating instances of
10/// `HashflowClient`.
11///
12/// # Example
13/// ```rust
14/// use tycho_simulation::rfq::protocols::hashflow::client_builder::HashflowClientBuilder;
15/// use tycho_common::{models::Chain, Bytes};
16/// use std::{collections::HashSet, str::FromStr, time::Duration};
17///
18/// let mut tokens = HashSet::new();
19/// tokens.insert(Bytes::from_str("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").unwrap()); // WETH
20/// tokens.insert(Bytes::from_str("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48").unwrap()); // USDC
21///
22/// let client = HashflowClientBuilder::new(
23///     Chain::Ethereum,
24///     "auth_user".to_string(),
25///     "auth_key".to_string()
26/// )
27/// .tokens(tokens)
28/// .tvl_threshold(500.0)
29/// .poll_time(Duration::from_secs(10))
30/// .build()
31/// .unwrap();
32/// ```
33pub struct HashflowClientBuilder {
34    chain: Chain,
35    auth_user: String,
36    auth_key: String,
37    tokens: HashSet<Bytes>,
38    tvl: f64,
39    quote_tokens: Option<HashSet<Bytes>>,
40    poll_time: Duration,
41    quote_timeout: Duration,
42}
43
44impl HashflowClientBuilder {
45    pub fn new(chain: Chain, auth_user: String, auth_key: String) -> Self {
46        Self {
47            chain,
48            auth_user,
49            auth_key,
50            tokens: HashSet::new(),
51            tvl: 100.0, // Default $100 minimum TVL
52            quote_tokens: None,
53            poll_time: Duration::from_secs(5), // Default 5 second polling
54            quote_timeout: Duration::from_secs(5), // Default 5 second timeout
55        }
56    }
57
58    /// Set the tokens for which to monitor prices
59    pub fn tokens(mut self, tokens: HashSet<Bytes>) -> Self {
60        self.tokens = tokens;
61        self
62    }
63
64    /// Set the minimum TVL threshold for pools
65    pub fn tvl_threshold(mut self, tvl: f64) -> Self {
66        self.tvl = tvl;
67        self
68    }
69
70    /// Set custom quote tokens for TVL calculation
71    /// If not set, will use chain-specific defaults
72    pub fn quote_tokens(mut self, quote_tokens: HashSet<Bytes>) -> Self {
73        self.quote_tokens = Some(quote_tokens);
74        self
75    }
76
77    /// Set the polling interval for fetching price levels
78    pub fn poll_time(mut self, poll_time: Duration) -> Self {
79        self.poll_time = poll_time;
80        self
81    }
82
83    /// Set the timeout for firm quote requests
84    pub fn quote_timeout(mut self, timeout: Duration) -> Self {
85        self.quote_timeout = timeout;
86        self
87    }
88
89    pub fn build(self) -> Result<HashflowClient, RFQError> {
90        let quote_tokens;
91        if let Some(tokens) = self.quote_tokens {
92            quote_tokens = tokens;
93        } else {
94            quote_tokens = default_quote_tokens_for_chain(&self.chain)?
95        }
96
97        HashflowClient::new(
98            self.chain,
99            self.tokens,
100            self.tvl,
101            quote_tokens,
102            self.auth_user,
103            self.auth_key,
104            self.poll_time,
105            self.quote_timeout,
106        )
107    }
108}