tg4/
query.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
5#[serde(rename_all = "snake_case")]
6pub enum Tg4QueryMsg {
7    /// Return AdminResponse
8    Admin {},
9    /// Return TotalPointsResponse
10    TotalPoints {},
11    /// Returns MemberListResponse.
12    /// The result is sorted by address ascending
13    ListMembers {
14        start_after: Option<String>,
15        limit: Option<u32>,
16    },
17    /// Returns MemberListResponse, sorted by points descending
18    ListMembersByPoints {
19        start_after: Option<Member>,
20        limit: Option<u32>,
21    },
22    /// Returns MemberResponse
23    Member {
24        addr: String,
25        at_height: Option<u64>,
26    },
27    /// Shows all registered hooks. Returns HooksResponse.
28    Hooks {},
29}
30
31#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
32pub struct AdminResponse {
33    pub admin: Option<String>,
34}
35
36#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
37pub struct MemberInfo {
38    pub points: u64,
39    pub start_height: Option<u64>,
40}
41
42impl MemberInfo {
43    pub fn new(points: u64) -> Self {
44        Self {
45            points,
46            start_height: None,
47        }
48    }
49
50    pub fn new_with_height(points: u64, height: u64) -> Self {
51        Self {
52            points,
53            start_height: Some(height),
54        }
55    }
56}
57
58/// A group member has some points associated with them.
59/// This may all be equal, or may have meaning in the app that
60/// makes use of the group (eg. voting power)
61#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
62pub struct Member {
63    pub addr: String,
64    pub points: u64,
65    pub start_height: Option<u64>,
66}
67
68#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
69pub struct MemberListResponse {
70    pub members: Vec<Member>,
71}
72
73#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
74pub struct MemberResponse {
75    pub points: Option<u64>,
76    pub start_height: Option<u64>,
77}
78
79impl From<Option<MemberInfo>> for MemberResponse {
80    fn from(mi: Option<MemberInfo>) -> Self {
81        match mi {
82            None => Self {
83                points: None,
84                start_height: None,
85            },
86            Some(mi) => Self {
87                points: Some(mi.points),
88                start_height: mi.start_height,
89            },
90        }
91    }
92}
93
94#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
95pub struct TotalPointsResponse {
96    pub points: u64,
97}
98
99#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
100pub struct HooksResponse {
101    pub hooks: Vec<String>,
102}
103
104/// TOTAL_KEY is meant for raw queries
105pub const TOTAL_KEY: &str = "total";
106pub const MEMBERS_KEY: &str = "members";
107pub const MEMBERS_CHECKPOINTS: &str = "members__checkpoints";
108pub const MEMBERS_CHANGELOG: &str = "members__changelog";
109
110/// member_key is meant for raw queries for one member, given address
111pub fn member_key(address: &str) -> Vec<u8> {
112    // FIXME: Inlined here to avoid storage-plus import
113    let mut key = [b"\x00", &[MEMBERS_KEY.len() as u8], MEMBERS_KEY.as_bytes()].concat();
114    key.extend_from_slice(address.as_bytes());
115    key
116}