circles_types/
avatar.rs

1use alloy_primitives::{Address, TxHash, U256};
2use serde::{Deserialize, Serialize};
3
4/// Avatar type variants
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub enum AvatarType {
7    #[serde(rename = "CrcV2_RegisterHuman")]
8    CrcV2RegisterHuman,
9    #[serde(rename = "CrcV2_RegisterGroup")]
10    CrcV2RegisterGroup,
11    #[serde(rename = "CrcV2_RegisterOrganization")]
12    CrcV2RegisterOrganization,
13    #[serde(rename = "CrcV1_Signup")]
14    CrcV1Signup,
15    #[serde(rename = "CrcV1_OrganizationSignup")]
16    CrcV1OrganizationSignup,
17}
18
19/// Geographic location coordinates
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct GeoLocation {
22    pub lat: f64,
23    pub lng: f64,
24}
25
26/// Avatar information
27/// Contains basic information about a Circles avatar.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct AvatarInfo {
30    /// The block number of the event
31    #[serde(default, rename = "blockNumber")]
32    pub block_number: u64,
33    /// The timestamp of the last change to the avatar
34    /// Note: May be undefined for some avatars
35    #[serde(default)]
36    pub timestamp: Option<u64>,
37    /// The transaction index
38    #[serde(default, rename = "transactionIndex")]
39    pub transaction_index: u32,
40    /// The log index
41    #[serde(default, rename = "logIndex")]
42    pub log_index: u32,
43    /// The hash of the transaction that last changed the avatar
44    #[serde(default, rename = "transactionHash")]
45    pub transaction_hash: TxHash,
46    /// If the avatar is currently active in version 1 or 2
47    /// Note: An avatar that's active in v2 can still have a v1 token. See `has_v1` and `v1_token`.
48    pub version: u32,
49    /// The type of the avatar
50    #[serde(rename = "type")]
51    pub avatar_type: AvatarType,
52    /// The address of the avatar
53    pub avatar: Address,
54    /// The personal or group token address (v1) or tokenId (v2)
55    /// Note: v1 tokens are erc20 and have a token address. v2 tokens are erc1155 and have a tokenId.
56    ///       The v2 tokenId is always an encoded version of the avatar address.
57    #[serde(rename = "tokenId")]
58    pub token_id: Option<U256>,
59    /// If the avatar is signed up at v1
60    #[serde(rename = "hasV1")]
61    pub has_v1: bool,
62    /// If the avatar has a v1 token, this is the token address
63    #[serde(rename = "v1Token")]
64    pub v1_token: Option<Address>,
65    /// The bytes of the avatar's metadata cidv0
66    #[serde(rename = "cidV0Digest")]
67    pub cid_v0_digest: Option<String>,
68    /// The CIDv0 of the avatar's metadata (profile)
69    #[serde(rename = "cidV0")]
70    pub cid_v0: Option<String>,
71    /// If the avatar is stopped in v1
72    /// Note: This is only set during Avatar initialization.
73    #[serde(rename = "v1Stopped")]
74    pub v1_stopped: Option<bool>,
75    /// Indicates whether the entity is a human
76    #[serde(rename = "isHuman")]
77    pub is_human: bool,
78    /// Groups have a name
79    pub name: Option<String>,
80    /// Groups have a symbol
81    pub symbol: Option<String>,
82}
83
84/// Profile information
85#[derive(Debug, Clone, Serialize, Deserialize)]
86#[serde(rename_all = "camelCase")]
87pub struct Profile {
88    pub name: String,
89    pub description: Option<String>,
90    pub preview_image_url: Option<String>,
91    pub image_url: Option<String>,
92    pub location: Option<String>,
93    pub geo_location: Option<GeoLocation>,
94    pub extensions: Option<serde_json::Map<String, serde_json::Value>>,
95}
96
97/// Group profile with additional symbol field
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct GroupProfile {
100    #[serde(flatten)]
101    pub profile: Profile,
102    pub symbol: String,
103}
104
105#[cfg(test)]
106mod tests {
107    use super::Profile;
108
109    #[test]
110    fn profile_deserializes_camel_case() {
111        let json = r#"{
112            "name": "franco",
113            "previewImageUrl": "data:image/jpeg;base64,abc",
114            "imageUrl": "https://example.com/full.jpg",
115            "location": "Berlin"
116        }"#;
117
118        let profile: Profile = serde_json::from_str(json).expect("should deserialize");
119        assert_eq!(profile.name, "franco");
120        assert_eq!(
121            profile.preview_image_url.as_deref(),
122            Some("data:image/jpeg;base64,abc")
123        );
124        assert_eq!(
125            profile.image_url.as_deref(),
126            Some("https://example.com/full.jpg")
127        );
128        assert_eq!(profile.location.as_deref(), Some("Berlin"));
129    }
130}