use std::time::Duration;
use reqwest::Client;
use url::Url;
use crate::{
api::{
builders::BuildersApi,
health::Health,
holders::Holders,
live_volume::LiveVolumeApi,
open_interest::OpenInterestApi,
trades::Trades,
users::{UserApi, UserTraded},
},
error::{DataApiError, Result},
};
const DEFAULT_BASE_URL: &str = "https://data-api.polymarket.com";
const DEFAULT_TIMEOUT_MS: u64 = 30_000;
const DEFAULT_POOL_SIZE: usize = 10;
#[derive(Clone)]
pub struct DataApi {
pub(crate) client: Client,
pub(crate) base_url: Url,
}
impl DataApi {
pub fn new() -> Result<Self> {
Self::builder().build()
}
pub fn builder() -> DataApiBuilder {
DataApiBuilder::new()
}
pub fn health(&self) -> Health {
Health {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
pub fn user(&self, user_address: impl Into<String>) -> UserApi {
UserApi {
client: self.client.clone(),
base_url: self.base_url.clone(),
user_address: user_address.into(),
}
}
pub fn positions(&self, user_address: impl Into<String>) -> UserApi {
self.user(user_address)
}
pub fn traded(&self, user_address: impl Into<String>) -> Traded {
Traded {
user_api: self.user(user_address),
}
}
pub fn trades(&self) -> Trades {
Trades {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
pub fn holders(&self) -> Holders {
Holders {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
pub fn open_interest(&self) -> OpenInterestApi {
OpenInterestApi {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
pub fn live_volume(&self) -> LiveVolumeApi {
LiveVolumeApi {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
pub fn builders(&self) -> BuildersApi {
BuildersApi {
client: self.client.clone(),
base_url: self.base_url.clone(),
}
}
}
pub struct DataApiBuilder {
base_url: String,
timeout_ms: u64,
pool_size: usize,
}
impl DataApiBuilder {
fn new() -> Self {
Self {
base_url: DEFAULT_BASE_URL.to_string(),
timeout_ms: DEFAULT_TIMEOUT_MS,
pool_size: DEFAULT_POOL_SIZE,
}
}
pub fn base_url(mut self, url: impl Into<String>) -> Self {
self.base_url = url.into();
self
}
pub fn timeout_ms(mut self, timeout: u64) -> Self {
self.timeout_ms = timeout;
self
}
pub fn pool_size(mut self, size: usize) -> Self {
self.pool_size = size;
self
}
pub fn build(self) -> Result<DataApi> {
let client = Client::builder()
.timeout(Duration::from_millis(self.timeout_ms))
.pool_max_idle_per_host(self.pool_size)
.build()?;
let base_url = Url::parse(&self.base_url)?;
Ok(DataApi { client, base_url })
}
}
impl Default for DataApiBuilder {
fn default() -> Self {
Self::new()
}
}
pub struct Traded {
user_api: UserApi,
}
impl Traded {
pub async fn get(self) -> std::result::Result<UserTraded, DataApiError> {
self.user_api.traded().await
}
}