cw1_subkeys/state.rs
1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5use cosmwasm_std::Addr;
6use cw_storage_plus::Map;
7use cw_utils::{Expiration, NativeBalance};
8
9// Permissions struct defines users message execution permissions.
10// Could have implemented permissions for each cosmos module(StakingPermissions, GovPermissions etc...)
11// But that meant a lot of code for each module. Keeping the permissions inside one struct is more
12// optimal. Define other modules permissions here.
13#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default, Copy)]
14pub struct Permissions {
15 pub delegate: bool,
16 pub redelegate: bool,
17 pub undelegate: bool,
18 pub withdraw: bool,
19}
20
21impl fmt::Display for Permissions {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 write!(
24 f,
25 "staking: {{ delegate: {}, redelegate: {}, undelegate: {}, withdraw: {} }}",
26 self.delegate, self.redelegate, self.undelegate, self.withdraw
27 )
28 }
29}
30
31#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)]
32pub struct Allowance {
33 pub balance: NativeBalance,
34 pub expires: Expiration,
35}
36
37#[cfg(test)]
38impl Allowance {
39 /// Utility function for converting message to its canonical form, so two messages with
40 /// different representation but same semantic meaning can be easily compared.
41 ///
42 /// It could be encapsulated in custom `PartialEq` implementation, but `PartialEq` is expected
43 /// to be fast, so it seems to be reasonable to keep it as representation-equality, and
44 /// canonicalize message only when it is needed
45 ///
46 /// Example:
47 ///
48 /// ```
49 /// # use cw_utils::{Expiration, NativeBalance};
50 /// # use cw1_subkeys::state::Allowance;
51 /// # use cosmwasm_std::coin;
52 ///
53 /// let allow1 = Allowance {
54 /// balance: NativeBalance(vec![coin(1, "token1"), coin(0, "token2"), coin(2, "token1"), coin(3, "token3")]),
55 /// expires: Expiration::Never {},
56 /// };
57 ///
58 /// let allow2 = Allowance {
59 /// balance: NativeBalance(vec![coin(3, "token3"), coin(3, "token1")]),
60 /// expires: Expiration::Never {},
61 /// };
62 ///
63 /// assert_eq!(allow1.canonical(), allow2.canonical());
64 /// ```
65 pub fn canonical(mut self) -> Self {
66 self.balance.normalize();
67 self
68 }
69}
70
71pub const PERMISSIONS: Map<&Addr, Permissions> = Map::new("permissions");
72pub const ALLOWANCES: Map<&Addr, Allowance> = Map::new("allowances");