polyte/
lib.rs

1//! # polyte
2//!
3//! Unified Rust client for Polymarket APIs, combining CLOB (trading), Gamma (market data), and Data APIs.
4//!
5//! ## Features
6//!
7//! - Unified access to CLOB, Gamma, and Data APIs
8//! - Type-safe API with idiomatic Rust patterns
9//! - EIP-712 order signing and HMAC authentication
10//! - Comprehensive market data and trading operations
11//!
12//! ## Example
13//!
14//! ```no_run
15//! use polyte::prelude::*;
16//!
17//! #[tokio::main]
18//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
19//!     // Load account from environment variables
20//!     let account = Account::from_env()?;
21//!
22//!     // Create unified client
23//!     let polymarket = Polymarket::builder(account)
24//!         .chain(Chain::PolygonMainnet)
25//!         .build()?;
26//!
27//!     // Use Gamma API to list markets
28//!     let markets = polymarket.gamma.markets()
29//!         .list()
30//!         .active(true)
31//!         .limit(10)
32//!         .send()
33//!         .await?;
34//!
35//!     // Use CLOB API to place an order
36//!     if let Some(first_market) = markets.first() {
37//!         if let Some(token) = first_market.tokens.first() {
38//!             let order_params = CreateOrderParams {
39//!                 token_id: token.token_id.clone(),
40//!                 price: 0.52,
41//!                 size: 100.0,
42//!                 side: OrderSide::Buy,
43//!                 expiration: None,
44//!             };
45//!
46//!             let response = polymarket.clob.place_order(&order_params).await?;
47//!             println!("Order placed: {:?}", response.order_id);
48//!         }
49//!     }
50//!
51//!     Ok(())
52//! }
53//! ```
54
55#[cfg(all(feature = "clob", feature = "gamma"))]
56use polyte_clob::{Account, Chain, Clob, ClobBuilder};
57#[cfg(all(feature = "clob", feature = "gamma"))]
58use polyte_gamma::Gamma;
59
60#[cfg(feature = "clob")]
61pub use polyte_clob;
62#[cfg(feature = "data")]
63pub use polyte_data;
64#[cfg(feature = "gamma")]
65pub use polyte_gamma;
66
67/// Prelude module for convenient imports
68pub mod prelude {
69    #[cfg(all(feature = "clob", feature = "gamma", feature = "data"))]
70    pub use crate::{Polymarket, PolymarketBuilder, PolymarketError};
71
72    #[cfg(feature = "clob")]
73    pub use polyte_clob::{
74        Account, Chain, Clob, ClobBuilder, ClobError, CreateOrderParams, Credentials, OrderSide,
75    };
76
77    #[cfg(feature = "data")]
78    pub use polyte_data::{DataApi, DataApiError};
79
80    #[cfg(feature = "gamma")]
81    pub use polyte_gamma::{Gamma, GammaError};
82
83    #[cfg(feature = "ws")]
84    pub use polyte_clob::ws;
85}
86
87/// Error types for Polymarket operations
88#[derive(Debug, thiserror::Error)]
89pub enum PolymarketError {
90    /// CLOB API error
91    #[cfg(feature = "clob")]
92    #[error("CLOB error: {0}")]
93    Clob(#[from] polyte_clob::ClobError),
94
95    /// Data API error
96    #[cfg(feature = "data")]
97    #[error("Data error: {0}")]
98    Data(#[from] polyte_data::DataApiError),
99
100    /// Gamma API error
101    #[cfg(feature = "gamma")]
102    #[error("Gamma error: {0}")]
103    Gamma(#[from] polyte_gamma::GammaError),
104
105    /// Configuration error
106    #[error("Configuration error: {0}")]
107    Config(String),
108}
109
110/// Unified Polymarket client
111#[cfg(all(feature = "clob", feature = "gamma"))]
112#[derive(Clone)]
113pub struct Polymarket {
114    /// CLOB (trading) API client
115    pub clob: Clob,
116    /// Gamma (market data) API client
117    pub gamma: Gamma,
118}
119
120#[cfg(all(feature = "clob", feature = "gamma"))]
121impl Polymarket {
122    /// Create a new client from an Account
123    pub fn new(account: Account) -> Result<Self, PolymarketError> {
124        PolymarketBuilder::new(account).build()
125    }
126
127    /// Create a new builder with an Account
128    pub fn builder(account: Account) -> PolymarketBuilder {
129        PolymarketBuilder::new(account)
130    }
131}
132
133/// Builder for Polymarket client
134#[cfg(all(feature = "clob", feature = "gamma"))]
135pub struct PolymarketBuilder {
136    clob_base_url: Option<String>,
137    gamma_base_url: Option<String>,
138    timeout_ms: Option<u64>,
139    chain: Option<Chain>,
140    account: Account,
141}
142
143#[cfg(all(feature = "clob", feature = "gamma"))]
144impl PolymarketBuilder {
145    fn new(account: Account) -> Self {
146        Self {
147            clob_base_url: None,
148            gamma_base_url: None,
149            timeout_ms: None,
150            chain: None,
151            account,
152        }
153    }
154
155    /// Set CLOB base URL
156    pub fn clob_base_url(mut self, url: impl Into<String>) -> Self {
157        self.clob_base_url = Some(url.into());
158        self
159    }
160
161    /// Set Gamma base URL
162    pub fn gamma_base_url(mut self, url: impl Into<String>) -> Self {
163        self.gamma_base_url = Some(url.into());
164        self
165    }
166
167    /// Set request timeout in milliseconds
168    pub fn timeout_ms(mut self, timeout: u64) -> Self {
169        self.timeout_ms = Some(timeout);
170        self
171    }
172
173    /// Set chain
174    pub fn chain(mut self, chain: Chain) -> Self {
175        self.chain = Some(chain);
176        self
177    }
178
179    /// Build the Polymarket client
180    pub fn build(self) -> Result<Polymarket, PolymarketError> {
181        // Build Gamma client
182        let mut gamma_builder = Gamma::builder();
183
184        if let Some(url) = self.gamma_base_url {
185            gamma_builder = gamma_builder.base_url(url);
186        }
187        if let Some(timeout) = self.timeout_ms {
188            gamma_builder = gamma_builder.timeout_ms(timeout);
189        }
190
191        let gamma = gamma_builder.build()?;
192
193        // Build CLOB client
194        let mut clob_builder = ClobBuilder::new(self.account);
195
196        if let Some(url) = self.clob_base_url {
197            clob_builder = clob_builder.base_url(url);
198        }
199        if let Some(timeout) = self.timeout_ms {
200            clob_builder = clob_builder.timeout_ms(timeout);
201        }
202        if let Some(chain) = self.chain {
203            clob_builder = clob_builder.chain(chain);
204        }
205
206        let clob = clob_builder.build()?;
207
208        Ok(Polymarket { clob, gamma })
209    }
210}