Skip to main content

polyoxide_data/api/
pnl.rs

1use polyoxide_core::{HttpClient, QueryBuilder, Request};
2
3use crate::{
4    error::DataApiError,
5    types::{PnlFidelity, PnlPoint},
6};
7
8/// PnL namespace — `GET /user-pnl` on `user-pnl-api.polymarket.com`.
9///
10/// # Stability
11///
12/// This host is **not covered by any published Polymarket OpenAPI spec**. It
13/// backs the PnL chart on the Polymarket web app and was verified live, but it
14/// carries no documented compatibility guarantee — treat it as more likely to
15/// change without notice than the rest of this crate. The base URL is
16/// configurable via
17/// [`DataApiBuilder::pnl_base_url`](crate::DataApiBuilder::pnl_base_url).
18#[derive(Clone)]
19pub struct PnlApi {
20    pub(crate) http_client: HttpClient,
21}
22
23impl PnlApi {
24    /// Get a user's realized-plus-unrealized PnL time series.
25    ///
26    /// Returns points of `{ t, p }` — Unix timestamp in seconds and PnL in
27    /// USDC. `user_address` is required by the upstream API.
28    pub fn history(&self, user_address: impl Into<String>) -> UserPnlRequest {
29        UserPnlRequest {
30            request: Request::new(self.http_client.clone(), "/user-pnl")
31                .query("user_address", user_address.into()),
32        }
33    }
34}
35
36/// Request builder for a user's PnL time series.
37pub struct UserPnlRequest {
38    request: Request<Vec<PnlPoint>, DataApiError>,
39}
40
41impl UserPnlRequest {
42    /// Restrict the series to a trailing window (e.g. `"1d"`, `"1w"`, `"all"`).
43    ///
44    /// Omitted by default, which yields the upstream default window. Unlike
45    /// [`fidelity`](Self::fidelity), the accepted values are not enumerated by
46    /// the API's own error messages, so this takes a string.
47    pub fn interval(mut self, interval: impl Into<String>) -> Self {
48        self.request = self.request.query("interval", interval.into());
49        self
50    }
51
52    /// Set the sampling resolution of the returned series.
53    pub fn fidelity(mut self, fidelity: PnlFidelity) -> Self {
54        self.request = self.request.query("fidelity", fidelity);
55        self
56    }
57
58    /// Execute the request.
59    pub async fn send(self) -> Result<Vec<PnlPoint>, DataApiError> {
60        self.request.send().await
61    }
62}