polyoxide_data/api/rankings.rs
1use polyoxide_core::{HttpClient, QueryBuilder, Request};
2
3use crate::{
4 error::DataApiError,
5 types::{RankingEntry, RankingWindow},
6};
7
8/// Rankings namespace — `GET /volume` and `GET /profit` on
9/// `lb-api.polymarket.com`.
10///
11/// This is a **different service** from
12/// [`DataApi::leaderboard`](crate::DataApi::leaderboard), which calls
13/// `/v1/leaderboard` on the main Data API host and returns a different shape.
14/// This one ranks traders by all-time or windowed volume and profit.
15///
16/// # Stability
17///
18/// This host is **not covered by any published Polymarket OpenAPI spec**. It
19/// was verified live, but carries no documented compatibility guarantee —
20/// treat it as more likely to change without notice than the rest of this
21/// crate. The base URL is configurable via
22/// [`DataApiBuilder::rankings_base_url`](crate::DataApiBuilder::rankings_base_url).
23#[derive(Clone)]
24pub struct RankingsApi {
25 pub(crate) http_client: HttpClient,
26}
27
28impl RankingsApi {
29 /// Rank traders by traded volume (`GET /volume`).
30 pub fn volume(&self) -> RankingRequest {
31 RankingRequest {
32 request: Request::new(self.http_client.clone(), "/volume"),
33 }
34 }
35
36 /// Rank traders by realized profit (`GET /profit`).
37 pub fn profit(&self) -> RankingRequest {
38 RankingRequest {
39 request: Request::new(self.http_client.clone(), "/profit"),
40 }
41 }
42}
43
44/// Request builder for a rankings query.
45pub struct RankingRequest {
46 request: Request<Vec<RankingEntry>, DataApiError>,
47}
48
49impl RankingRequest {
50 /// Set the ranking window. An unrecognized value is rejected upstream with
51 /// `{"error": "invalid request"}`, which is why this is an enum.
52 pub fn window(mut self, window: RankingWindow) -> Self {
53 self.request = self.request.query("window", window);
54 self
55 }
56
57 /// Limit the number of ranked entries returned.
58 pub fn limit(mut self, limit: u32) -> Self {
59 self.request = self.request.query("limit", limit);
60 self
61 }
62
63 /// Execute the request.
64 pub async fn send(self) -> Result<Vec<RankingEntry>, DataApiError> {
65 self.request.send().await
66 }
67}