polyte_data/api/
holders.rs

1use reqwest::Client;
2use serde::{Deserialize, Serialize};
3use url::Url;
4
5use crate::request::{QueryBuilder, Request};
6
7/// Holders namespace for holder-related operations
8#[derive(Clone)]
9pub struct Holders {
10    pub(crate) client: Client,
11    pub(crate) base_url: Url,
12}
13
14impl Holders {
15    /// Get top holders for markets
16    pub fn list(&self, markets: impl IntoIterator<Item = impl ToString>) -> ListHolders {
17        let market_ids: Vec<String> = markets.into_iter().map(|s| s.to_string()).collect();
18        let mut request = Request::new(
19            self.client.clone(),
20            self.base_url.clone(),
21            "/holders".to_string(),
22        );
23        if !market_ids.is_empty() {
24            request = request.query("market", market_ids.join(","));
25        }
26
27        ListHolders { request }
28    }
29}
30
31/// Request builder for getting top holders
32pub struct ListHolders {
33    request: Request<Vec<MarketHolders>>,
34}
35
36impl ListHolders {
37    /// Set maximum number of results per market (0-500, default: 100)
38    pub fn limit(mut self, limit: u32) -> Self {
39        self.request = self.request.query("limit", limit);
40        self
41    }
42
43    /// Set minimum balance filter (0-999999, default: 1)
44    pub fn min_balance(mut self, min_balance: u32) -> Self {
45        self.request = self.request.query("minBalance", min_balance);
46        self
47    }
48
49    /// Execute the request
50    pub async fn send(self) -> crate::error::Result<Vec<MarketHolders>> {
51        self.request.send().await
52    }
53}
54
55/// Market holders response containing token and its holders
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(rename_all(deserialize = "camelCase"))]
58pub struct MarketHolders {
59    /// Token identifier
60    pub token: String,
61    /// List of holders for this token
62    pub holders: Vec<Holder>,
63}
64
65/// Individual holder of a market token
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all(deserialize = "camelCase"))]
68pub struct Holder {
69    /// Proxy wallet address
70    pub proxy_wallet: String,
71    /// User bio
72    pub bio: Option<String>,
73    /// Asset identifier (token ID)
74    pub asset: Option<String>,
75    /// User pseudonym
76    pub pseudonym: Option<String>,
77    /// Amount held
78    pub amount: f64,
79    /// Whether username is displayed publicly
80    pub display_username_public: Option<bool>,
81    /// Outcome index (0 or 1 for binary markets)
82    pub outcome_index: u32,
83    /// User display name
84    pub name: Option<String>,
85    /// User profile image URL
86    pub profile_image: Option<String>,
87    /// Optimized profile image URL
88    pub profile_image_optimized: Option<String>,
89}