Skip to main content

polyoxide_gamma/api/
user.rs

1use polyoxide_core::{HttpClient, QueryBuilder, Request};
2use serde::{Deserialize, Serialize};
3
4use crate::{error::GammaError, types::Profile};
5
6/// User API namespace
7#[derive(Clone)]
8pub struct User {
9    pub(crate) http_client: HttpClient,
10}
11
12impl User {
13    /// Get user details
14    pub fn get(&self, signer_address: impl Into<String>) -> Request<UserResponse, GammaError> {
15        Request::new(self.http_client.clone(), "/public-profile")
16            .query("address", signer_address.into())
17    }
18
19    /// Get a public profile by wallet address
20    /// (`GET /profiles/user_address/{user_address}`).
21    ///
22    /// `address` must be a 0x-prefixed EVM address. Responses are modelled by
23    /// [`Profile`], which is field-for-field compatible with the upstream
24    /// `Profile` schema.
25    pub fn get_by_address(&self, address: impl Into<String>) -> Request<Profile, GammaError> {
26        Request::new(
27            self.http_client.clone(),
28            format!(
29                "/profiles/user_address/{}",
30                urlencoding::encode(&address.into())
31            ),
32        )
33    }
34}
35
36/// User details response from the `/public-profile` endpoint
37#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct UserResponse {
40    /// The user's proxy wallet address (Treasury)
41    #[serde(rename = "proxyWallet")]
42    pub proxy: Option<String>,
43    /// The user's EOA address (Signer)
44    pub address: Option<String>,
45    /// Account ID
46    pub id: Option<String>,
47    /// Username/Display name
48    pub name: Option<String>,
49    /// Account creation timestamp (ISO 8601)
50    pub created_at: Option<String>,
51    /// Profile image URL
52    pub profile_image: Option<String>,
53    /// Whether the username is displayed publicly
54    pub display_username_public: Option<bool>,
55    /// User biography
56    pub bio: Option<String>,
57    /// Auto-generated pseudonym
58    pub pseudonym: Option<String>,
59    /// Twitter/X handle
60    pub x_username: Option<String>,
61    /// Whether the user has a verified badge
62    pub verified_badge: Option<bool>,
63    /// User identity entries
64    #[serde(default)]
65    pub users: Vec<UserInfo>,
66}
67
68/// User identity entry returned inside a profile's `users` array
69#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(rename_all = "camelCase")]
71pub struct UserInfo {
72    /// User ID
73    pub id: Option<String>,
74    /// Whether this user is a creator
75    #[serde(default)]
76    pub creator: bool,
77    /// Whether this user is a moderator
78    #[serde(rename = "mod")]
79    #[serde(default)]
80    pub moderator: bool,
81}
82
83#[cfg(test)]
84mod tests {
85    use crate::Gamma;
86
87    fn gamma() -> Gamma {
88        Gamma::new().unwrap()
89    }
90
91    #[test]
92    fn test_get_by_address_accepts_str_and_string() {
93        let _r1 = gamma().user().get_by_address("0xdeadbeef");
94        let _r2 = gamma().user().get_by_address(String::from("0xdeadbeef"));
95    }
96}