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 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 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}