drm_exchange_polymarket/
client.rs

1use reqwest::Client;
2use serde::de::DeserializeOwned;
3
4use crate::config::PolymarketConfig;
5use crate::error::PolymarketError;
6
7pub struct HttpClient {
8    client: Client,
9    gamma_url: String,
10    clob_url: String,
11    verbose: bool,
12}
13
14impl HttpClient {
15    pub fn new(config: &PolymarketConfig) -> Result<Self, PolymarketError> {
16        let client = Client::builder().timeout(config.base.timeout).build()?;
17
18        Ok(Self {
19            client,
20            gamma_url: config.gamma_url.clone(),
21            clob_url: config.clob_url.clone(),
22            verbose: config.base.verbose,
23        })
24    }
25
26    pub async fn get_gamma<T: DeserializeOwned>(
27        &self,
28        endpoint: &str,
29    ) -> Result<T, PolymarketError> {
30        let url = format!("{}{}", self.gamma_url, endpoint);
31        self.get(&url).await
32    }
33
34    pub async fn get_clob<T: DeserializeOwned>(
35        &self,
36        endpoint: &str,
37    ) -> Result<T, PolymarketError> {
38        let url = format!("{}{}", self.clob_url, endpoint);
39        self.get(&url).await
40    }
41
42    async fn get<T: DeserializeOwned>(&self, url: &str) -> Result<T, PolymarketError> {
43        if self.verbose {
44            tracing::debug!("GET {}", url);
45        }
46
47        let response = self.client.get(url).send().await?;
48        let status = response.status();
49
50        if status == 429 {
51            let retry_after = response
52                .headers()
53                .get("retry-after")
54                .and_then(|h| h.to_str().ok())
55                .and_then(|s| s.parse().ok())
56                .unwrap_or(1);
57            return Err(PolymarketError::RateLimited { retry_after });
58        }
59
60        if !status.is_success() {
61            let message = response.text().await.unwrap_or_default();
62            return Err(PolymarketError::Api(format!("{status}: {message}")));
63        }
64
65        let body = response.json().await?;
66        Ok(body)
67    }
68}