Skip to main content

polyoxide_data/
client.rs

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