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