komple_framework_utils/
storage.rs

1use cosmwasm_std::{from_slice, Addr, Empty, QuerierWrapper, StdError, StdResult};
2use cw721_base::state::TokenInfo;
3use cw_storage_plus::Path;
4use komple_framework_types::modules::fee::{
5    FixedPayment, PercentagePayment, FIXED_FEES_NAMESPACE, PERCENTAGE_FEES_NAMESPACE,
6};
7use komple_framework_types::modules::mint::{
8    COLLECTION_ADDRS_NAMESPACE, LINKED_COLLECTIONS_NAMESPACE,
9};
10use komple_framework_types::modules::token::{
11    Locks, SubModules, LOCKS_NAMESPACE, SUB_MODULES_NAMESPACE, TOKENS_NAMESPACE,
12    TOKEN_LOCKS_NAMESPACE,
13};
14use komple_framework_types::modules::MODULES_NAMESPACE;
15use schemars::JsonSchema;
16use serde::{de::DeserializeOwned, Deserialize, Serialize};
17use std::{ops::Deref, str::from_utf8};
18
19#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
20pub struct StorageHelper();
21
22impl StorageHelper {
23    // namespace -> storage key
24    // key_name -> item key
25    pub fn get_map_storage_key(namepspace: &str, key_bytes: &[&[u8]]) -> StdResult<String> {
26        let namespace_bytes = namepspace.as_bytes();
27        let path: Path<Vec<u32>> = Path::new(namespace_bytes, key_bytes);
28        let path_str = from_utf8(path.deref())?;
29        Ok(path_str.to_string())
30    }
31
32    // To find the key value in storage, we need to construct a path to the key
33    // For Map storage this key is generated with get_map_storage_key
34    // For Item storage this key is the namespace value
35    pub fn query_storage<T>(
36        querier: &QuerierWrapper,
37        addr: &Addr,
38        key: &str,
39    ) -> StdResult<Option<T>>
40    where
41        T: DeserializeOwned,
42    {
43        let data = querier.query_wasm_raw(addr, key.as_bytes())?;
44        match data {
45            Some(data) => {
46                let res = from_utf8(&data)?;
47                let res = from_slice(res.as_bytes())?;
48                Ok(Some(res))
49            }
50            None => Ok(None),
51        }
52    }
53
54    pub fn query_module_address(
55        querier: &QuerierWrapper,
56        hub_addr: &Addr,
57        module: String,
58    ) -> StdResult<Addr> {
59        let key = Self::get_map_storage_key(MODULES_NAMESPACE, &[module.as_bytes()])?;
60        let res = Self::query_storage::<Addr>(querier, hub_addr, &key)?;
61        match res {
62            Some(res) => Ok(res),
63            None => Err(StdError::NotFound {
64                kind: "Module".to_string(),
65            }),
66        }
67    }
68
69    pub fn query_collection_address(
70        querier: &QuerierWrapper,
71        mint_module_address: &Addr,
72        collection_id: &u32,
73    ) -> StdResult<Addr> {
74        let key =
75            Self::get_map_storage_key(COLLECTION_ADDRS_NAMESPACE, &[&collection_id.to_be_bytes()])?;
76        let res = Self::query_storage::<Addr>(querier, mint_module_address, &key)?;
77        match res {
78            Some(res) => Ok(res),
79            None => Err(StdError::NotFound {
80                kind: "Collection".to_string(),
81            }),
82        }
83    }
84
85    pub fn query_linked_collections(
86        querier: &QuerierWrapper,
87        mint_module_address: &Addr,
88        collection_id: u32,
89    ) -> StdResult<Vec<u32>> {
90        let key = Self::get_map_storage_key(
91            LINKED_COLLECTIONS_NAMESPACE,
92            &[&collection_id.to_be_bytes()],
93        )?;
94        let res = Self::query_storage::<Vec<u32>>(querier, mint_module_address, &key)?;
95        match res {
96            Some(res) => Ok(res),
97            None => Ok(vec![]),
98        }
99    }
100
101    pub fn query_token_owner(
102        querier: &QuerierWrapper,
103        collection_addr: &Addr,
104        token_id: &u32,
105    ) -> StdResult<Addr> {
106        let key = Self::get_map_storage_key(TOKENS_NAMESPACE, &[token_id.to_string().as_bytes()])?;
107        let res = Self::query_storage::<TokenInfo<Empty>>(querier, collection_addr, &key)?;
108        match res {
109            Some(res) => Ok(Addr::unchecked(res.owner)),
110            None => Err(StdError::NotFound {
111                kind: "Token".to_string(),
112            }),
113        }
114    }
115
116    pub fn query_collection_locks(
117        querier: &QuerierWrapper,
118        collection_addr: &Addr,
119    ) -> StdResult<Locks> {
120        let res = Self::query_storage::<Locks>(querier, collection_addr, LOCKS_NAMESPACE)?;
121        match res {
122            Some(res) => Ok(res),
123            None => Err(StdError::NotFound {
124                kind: "Locks".to_string(),
125            }),
126        }
127    }
128
129    pub fn query_token_locks(
130        querier: &QuerierWrapper,
131        collection_addr: &Addr,
132        token_id: &u32,
133    ) -> StdResult<Locks> {
134        let key =
135            Self::get_map_storage_key(TOKEN_LOCKS_NAMESPACE, &[token_id.to_string().as_bytes()])?;
136        let res = Self::query_storage::<Locks>(querier, collection_addr, &key)?;
137        match res {
138            Some(res) => Ok(res),
139            None => Ok(Locks {
140                mint_lock: false,
141                burn_lock: false,
142                transfer_lock: false,
143                send_lock: false,
144            }),
145        }
146    }
147
148    pub fn query_fixed_fee(
149        querier: &QuerierWrapper,
150        fee_module_addr: &Addr,
151        module_name: String,
152        fee_name: String,
153    ) -> StdResult<FixedPayment> {
154        let key = Self::get_map_storage_key(
155            FIXED_FEES_NAMESPACE,
156            &[module_name.as_bytes(), fee_name.as_bytes()],
157        )?;
158        let res = Self::query_storage::<FixedPayment>(querier, fee_module_addr, &key)?;
159        match res {
160            Some(res) => Ok(res),
161            None => Err(StdError::NotFound {
162                kind: "Fixed payment".to_string(),
163            }),
164        }
165    }
166
167    pub fn query_percentage_fee(
168        querier: &QuerierWrapper,
169        fee_module_addr: &Addr,
170        module_name: String,
171        fee_name: String,
172    ) -> StdResult<PercentagePayment> {
173        let key = Self::get_map_storage_key(
174            PERCENTAGE_FEES_NAMESPACE,
175            &[module_name.as_bytes(), fee_name.as_bytes()],
176        )?;
177        let res = Self::query_storage::<PercentagePayment>(querier, fee_module_addr, &key)?;
178        match res {
179            Some(res) => Ok(res),
180            None => Err(StdError::NotFound {
181                kind: "Percentage payment".to_string(),
182            }),
183        }
184    }
185
186    pub fn query_token_sub_modules(
187        querier: &QuerierWrapper,
188        token_module_addr: &Addr,
189    ) -> StdResult<SubModules> {
190        let res =
191            Self::query_storage::<SubModules>(querier, token_module_addr, SUB_MODULES_NAMESPACE)?;
192        match res {
193            Some(res) => Ok(res),
194            None => Err(StdError::NotFound {
195                kind: "Sub modules".to_string(),
196            }),
197        }
198    }
199}