variable_manager_pkg/
lib.rs

1pub mod msgs {
2    use std::collections::BTreeMap;
3
4    use cosmwasm_schema::{cw_serde, QueryResponses};
5    use cosmwasm_std::Addr;
6
7    use crate::definitions::Config;
8
9    use super::definitions::Variable;
10
11    #[cw_serde]
12    pub struct InstantiateMsg {
13        pub owners: Vec<String>,
14    }
15
16    #[cw_serde]
17    pub enum ExecuteMsg {
18        RegisterVariable(RegisterVariableMsg),
19        RegisterVariables(Vec<RegisterVariableMsg>),
20        UpdateVariable(RegisterVariableMsg),
21        UpdateVariables(Vec<RegisterVariableMsg>),
22        RemoveVariable(RemoveVariableMsg),
23        UpdateOwners(UpdateOwnerMsg),
24    }
25
26    #[cw_serde]
27    pub struct RegisterVariableMsg {
28        pub key: String,
29        pub value: Variable,
30    }
31
32    impl RegisterVariableMsg {
33        pub fn new(key: String, value: Variable) -> Self {
34            Self { key, value }
35        }
36    }
37
38    #[cw_serde]
39    pub struct RemoveVariableMsg {
40        pub key: String,
41    }
42
43    #[cw_serde]
44    pub struct UpdateOwnerMsg {
45        pub add: Option<Vec<String>>,
46        pub remove: Option<Vec<String>>,
47    }
48
49    #[cw_serde]
50    #[derive(QueryResponses)]
51    pub enum QueryMsg {
52        #[returns(Addr)]
53        GetVariable { key: String },
54        #[returns(BTreeMap<String, Variable>)]
55        GetVariables { keys: Vec<String> },
56        #[returns(Vec<(String, Variable)>)]
57        AllVariables {
58            start_after: Option<String>,
59            limit: Option<u32>,
60        },
61        #[returns(Config)]
62        Config {},
63    }
64
65    #[cw_serde]
66    pub struct MigrateMsg {}
67}
68
69pub mod definitions {
70
71    use std::fmt::Display;
72
73    use cosmwasm_schema::cw_serde;
74    use cosmwasm_std::{from_json, Addr, Binary, Decimal, Deps, StdError, StdResult, Uint128};
75    use serde::de::DeserializeOwned;
76
77    #[cw_serde]
78    pub struct Config {
79        pub owners: Vec<Addr>,
80    }
81
82    impl Config {
83        pub fn validate_owner(&self, address: &Addr) -> StdResult<()> {
84            if !self.owners.contains(address) {
85                return Err(StdError::generic_err(format!(
86                    "{} is not an owner",
87                    address
88                )));
89            }
90
91            Ok(())
92        }
93        pub fn validate(&self) -> StdResult<()> {
94            if self.owners.is_empty() {
95                return Err(StdError::generic_err("Invalid 0 owners. Needed at least 1"));
96            }
97
98            Ok(())
99        }
100    }
101
102    #[cw_serde]
103    pub enum Variable {
104        String(String),
105        Addr(Addr),
106        Uint128(Uint128),
107        U64(u64),
108        Decimal(Decimal),
109        Binary(Binary),
110    }
111
112    impl Variable {
113        pub fn unwrap_string(&self) -> StdResult<String> {
114            if let Variable::String(val) = self {
115                Ok(val.clone())
116            } else {
117                Err(StdError::generic_err(format!(
118                    "Variable is not String, {:?}",
119                    self
120                )))
121            }
122        }
123
124        pub fn unwrap_addr(&self) -> StdResult<Addr> {
125            if let Variable::Addr(val) = self {
126                Ok(val.clone())
127            } else {
128                Err(StdError::generic_err(format!(
129                    "Variable is not Addr, {:?}",
130                    self
131                )))
132            }
133        }
134
135        pub fn unwrap_uint128(&self) -> StdResult<Uint128> {
136            if let Variable::Uint128(val) = self {
137                Ok(*val)
138            } else {
139                Err(StdError::generic_err(format!(
140                    "Variable is not Uint128, {:?}",
141                    self
142                )))
143            }
144        }
145
146        pub fn unwrap_u64(&self) -> StdResult<u64> {
147            if let Variable::U64(val) = self {
148                Ok(*val)
149            } else {
150                Err(StdError::generic_err(format!(
151                    "Variable is not u64, {:?}",
152                    self
153                )))
154            }
155        }
156
157        pub fn unwrap_decimal(&self) -> StdResult<Decimal> {
158            if let Variable::Decimal(val) = self {
159                Ok(*val)
160            } else {
161                Err(StdError::generic_err(format!(
162                    "Variable is not Decimal, {:?}",
163                    self
164                )))
165            }
166        }
167
168        pub fn unwrap_binary<T: DeserializeOwned>(&self) -> StdResult<T> {
169            if let Variable::Binary(val) = self {
170                from_json::<T>(val)
171            } else {
172                Err(StdError::generic_err(format!(
173                    "Variable is not Decimal, {:?}",
174                    self
175                )))
176            }
177        }
178
179        pub fn validate(self, deps: Deps) -> StdResult<Variable> {
180            if let Variable::Addr(val) = &self {
181                deps.api.addr_validate(val.as_ref())?;
182            }
183
184            Ok(self)
185        }
186    }
187
188    impl Display for Variable {
189        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190            match self {
191                Variable::String(val) => write!(f, "String: {val}"),
192                Variable::Addr(val) => write!(f, "Addr: {val}"),
193                Variable::Uint128(val) => write!(f, "Uint128: {val}"),
194                Variable::U64(val) => write!(f, "u64: {val}"),
195                Variable::Decimal(val) => write!(f, "Decimal: {val}"),
196                Variable::Binary(val) => write!(f, "Binary: {val}"),
197            }
198        }
199    }
200}
201
202pub mod helper {
203    use std::collections::BTreeMap;
204
205    use cosmwasm_std::{QuerierWrapper, StdResult};
206
207    use crate::definitions::Variable;
208
209    use super::msgs::QueryMsg;
210
211    pub fn variable_manager_get_variable(
212        querier: &QuerierWrapper,
213        key: impl Into<String>,
214        address_manager_addr: impl Into<String>,
215    ) -> StdResult<Variable> {
216        querier.query_wasm_smart(
217            address_manager_addr,
218            &QueryMsg::GetVariable { key: key.into() },
219        )
220    }
221
222    pub fn variable_manager_get_variables(
223        querier: &QuerierWrapper,
224        keys: Vec<impl Into<String>>,
225        address_manager_addr: impl Into<String>,
226    ) -> StdResult<BTreeMap<String, Variable>> {
227        querier.query_wasm_smart(
228            address_manager_addr,
229            &QueryMsg::GetVariables {
230                keys: keys.into_iter().map(|val| val.into()).collect(),
231            },
232        )
233    }
234}