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");