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#[derive(Clone)]
22pub struct DataApi {
23 pub(crate) client: Client,
24 pub(crate) base_url: Url,
25}
26
27impl DataApi {
28 pub fn new() -> Result<Self, DataApiError> {
30 Self::builder().build()
31 }
32
33 pub fn builder() -> DataApiBuilder {
35 DataApiBuilder::new()
36 }
37
38 pub fn health(&self) -> Health {
40 Health {
41 client: self.client.clone(),
42 base_url: self.base_url.clone(),
43 }
44 }
45
46 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 pub fn positions(&self, user_address: impl Into<String>) -> UserApi {
57 self.user(user_address)
58 }
59
60 pub fn traded(&self, user_address: impl Into<String>) -> Traded {
62 Traded {
63 user_api: self.user(user_address),
64 }
65 }
66
67 pub fn trades(&self) -> Trades {
69 Trades {
70 client: self.client.clone(),
71 base_url: self.base_url.clone(),
72 }
73 }
74
75 pub fn holders(&self) -> Holders {
77 Holders {
78 client: self.client.clone(),
79 base_url: self.base_url.clone(),
80 }
81 }
82
83 pub fn open_interest(&self) -> OpenInterestApi {
85 OpenInterestApi {
86 client: self.client.clone(),
87 base_url: self.base_url.clone(),
88 }
89 }
90
91 pub fn live_volume(&self) -> LiveVolumeApi {
93 LiveVolumeApi {
94 client: self.client.clone(),
95 base_url: self.base_url.clone(),
96 }
97 }
98
99 pub fn builders(&self) -> BuildersApi {
101 BuildersApi {
102 client: self.client.clone(),
103 base_url: self.base_url.clone(),
104 }
105 }
106}
107
108pub 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 pub fn base_url(mut self, url: impl Into<String>) -> Self {
126 self.base_url = url.into();
127 self
128 }
129
130 pub fn timeout_ms(mut self, timeout: u64) -> Self {
132 self.timeout_ms = timeout;
133 self
134 }
135
136 pub fn pool_size(mut self, size: usize) -> Self {
138 self.pool_size = size;
139 self
140 }
141
142 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
159pub struct Traded {
161 user_api: UserApi,
162}
163
164impl Traded {
165 pub async fn get(self) -> std::result::Result<UserTraded, DataApiError> {
167 self.user_api.traded().await
168 }
169}