|
| 1 | +use std::collections::HashSet; |
| 2 | + |
| 3 | +use tokio::time::Duration; |
| 4 | +use tycho_common::{models::Chain, Bytes}; |
| 5 | + |
| 6 | +use super::client::HashflowClient; |
| 7 | +use 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 | +/// ``` |
| 33 | +pub 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 | +} |
| 42 | + |
| 43 | +impl HashflowClientBuilder { |
| 44 | + pub fn new(chain: Chain, auth_user: String, auth_key: String) -> Self { |
| 45 | + Self { |
| 46 | + chain, |
| 47 | + auth_user, |
| 48 | + auth_key, |
| 49 | + tokens: HashSet::new(), |
| 50 | + tvl: 100.0, // Default $100 minimum TVL |
| 51 | + quote_tokens: None, |
| 52 | + poll_time: Duration::from_secs(5), // Default 5 second polling |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + /// Set the tokens for which to monitor prices |
| 57 | + pub fn tokens(mut self, tokens: HashSet<Bytes>) -> Self { |
| 58 | + self.tokens = tokens; |
| 59 | + self |
| 60 | + } |
| 61 | + |
| 62 | + /// Set the minimum TVL threshold for pools |
| 63 | + pub fn tvl_threshold(mut self, tvl: f64) -> Self { |
| 64 | + self.tvl = tvl; |
| 65 | + self |
| 66 | + } |
| 67 | + |
| 68 | + /// Set custom quote tokens for TVL calculation |
| 69 | + /// If not set, will use chain-specific defaults |
| 70 | + pub fn quote_tokens(mut self, quote_tokens: HashSet<Bytes>) -> Self { |
| 71 | + self.quote_tokens = Some(quote_tokens); |
| 72 | + self |
| 73 | + } |
| 74 | + |
| 75 | + /// Set the polling interval for fetching price levels |
| 76 | + pub fn poll_time(mut self, poll_time: Duration) -> Self { |
| 77 | + self.poll_time = poll_time; |
| 78 | + self |
| 79 | + } |
| 80 | + |
| 81 | + pub fn build(self) -> Result<HashflowClient, RFQError> { |
| 82 | + let quote_tokens; |
| 83 | + if let Some(tokens) = self.quote_tokens { |
| 84 | + quote_tokens = tokens; |
| 85 | + } else { |
| 86 | + quote_tokens = default_quote_tokens_for_chain(&self.chain)? |
| 87 | + } |
| 88 | + |
| 89 | + HashflowClient::new( |
| 90 | + self.chain, |
| 91 | + self.tokens, |
| 92 | + self.tvl, |
| 93 | + quote_tokens, |
| 94 | + self.auth_user, |
| 95 | + self.auth_key, |
| 96 | + self.poll_time, |
| 97 | + ) |
| 98 | + } |
| 99 | +} |
0 commit comments