Skip to main content

polyoxide_data/
client.rs

1use polyoxide_core::{
2    HttpClient, HttpClientBuilder, RateLimiter, DEFAULT_POOL_SIZE, DEFAULT_TIMEOUT_MS,
3};
4
5use crate::{
6    api::{
7        builders::BuildersApi,
8        health::Health,
9        holders::Holders,
10        live_volume::LiveVolumeApi,
11        open_interest::OpenInterestApi,
12        trades::Trades,
13        users::{UserApi, UserTraded},
14    },
15    error::DataApiError,
16};
17
18const DEFAULT_BASE_URL: &str = "https://data-api.polymarket.com";
19
20/// Main Data API client
21#[derive(Clone)]
22pub struct DataApi {
23    pub(crate) http_client: HttpClient,
24}
25
26impl DataApi {
27    /// Create a new Data API client with default configuration
28    pub fn new() -> Result<Self, DataApiError> {
29        Self::builder().build()
30    }
31
32    /// Create a builder for configuring the client
33    pub fn builder() -> DataApiBuilder {
34        DataApiBuilder::new()
35    }
36
37    /// Get health namespace
38    pub fn health(&self) -> Health {
39        Health {
40            http_client: self.http_client.clone(),
41        }
42    }
43
44    /// Get user namespace for user-specific operations
45    pub fn user(&self, user_address: impl Into<String>) -> UserApi {
46        UserApi {
47            http_client: self.http_client.clone(),
48            user_address: user_address.into(),
49        }
50    }
51
52    /// Alias for `user()` - for backwards compatibility
53    pub fn positions(&self, user_address: impl Into<String>) -> UserApi {
54        self.user(user_address)
55    }
56
57    /// Get traded namespace for backwards compatibility
58    pub fn traded(&self, user_address: impl Into<String>) -> Traded {
59        Traded {
60            user_api: self.user(user_address),
61        }
62    }
63
64    /// Get trades namespace
65    pub fn trades(&self) -> Trades {
66        Trades {
67            http_client: self.http_client.clone(),
68        }
69    }
70
71    /// Get holders namespace
72    pub fn holders(&self) -> Holders {
73        Holders {
74            http_client: self.http_client.clone(),
75        }
76    }
77
78    /// Get open interest namespace
79    pub fn open_interest(&self) -> OpenInterestApi {
80        OpenInterestApi {
81            http_client: self.http_client.clone(),
82        }
83    }
84
85    /// Get live volume namespace
86    pub fn live_volume(&self) -> LiveVolumeApi {
87        LiveVolumeApi {
88            http_client: self.http_client.clone(),
89        }
90    }
91
92    /// Get builders namespace
93    pub fn builders(&self) -> BuildersApi {
94        BuildersApi {
95            http_client: self.http_client.clone(),
96        }
97    }
98}
99
100/// Builder for configuring Data API client
101pub struct DataApiBuilder {
102    base_url: String,
103    timeout_ms: u64,
104    pool_size: usize,
105}
106
107impl DataApiBuilder {
108    fn new() -> Self {
109        Self {
110            base_url: DEFAULT_BASE_URL.to_string(),
111            timeout_ms: DEFAULT_TIMEOUT_MS,
112            pool_size: DEFAULT_POOL_SIZE,
113        }
114    }
115
116    /// Set base URL for the API
117    pub fn base_url(mut self, url: impl Into<String>) -> Self {
118        self.base_url = url.into();
119        self
120    }
121
122    /// Set request timeout in milliseconds
123    pub fn timeout_ms(mut self, timeout: u64) -> Self {
124        self.timeout_ms = timeout;
125        self
126    }
127
128    /// Set connection pool size
129    pub fn pool_size(mut self, size: usize) -> Self {
130        self.pool_size = size;
131        self
132    }
133
134    /// Build the Data API client
135    pub fn build(self) -> Result<DataApi, DataApiError> {
136        let http_client = HttpClientBuilder::new(&self.base_url)
137            .timeout_ms(self.timeout_ms)
138            .pool_size(self.pool_size)
139            .with_rate_limiter(RateLimiter::data_default())
140            .build()?;
141
142        Ok(DataApi { http_client })
143    }
144}
145
146impl Default for DataApiBuilder {
147    fn default() -> Self {
148        Self::new()
149    }
150}
151
152/// Wrapper for backwards compatibility with traded() API
153pub struct Traded {
154    user_api: UserApi,
155}
156
157impl Traded {
158    /// Get total markets traded by the user
159    pub async fn get(self) -> std::result::Result<UserTraded, DataApiError> {
160        self.user_api.traded().await
161    }
162}