andromeda_std/os/
aos_querier.rs

1use crate::amp::{ADO_DB_KEY, VFS_KEY};
2use crate::error::ContractError;
3use cosmwasm_schema::cw_serde;
4use cosmwasm_std::{from_json, Addr, QuerierWrapper};
5use cw_storage_plus::Path;
6use lazy_static::__Deref;
7use serde::de::DeserializeOwned;
8use std::str::from_utf8;
9
10use super::adodb::{ADOVersion, ActionFee, QueryMsg as ADODBQueryMsg};
11use super::kernel::ChannelInfo;
12
13#[cw_serde]
14pub struct AOSQuerier();
15
16impl AOSQuerier {
17    // namespace -> storage key
18    // key_name -> item key
19    // Taken from: https://github.com/KompleTeam/komple-framework/blob/387d333af03e794927b8ef8ac536d2a42ae7a1ff/packages/utils/src/storage.rs#L25
20    pub fn get_map_storage_key(
21        namespace: &str,
22        key_bytes: &[&[u8]],
23    ) -> Result<String, ContractError> {
24        let namespace_bytes = namespace.as_bytes();
25        let path: Path<Vec<u32>> = Path::new(namespace_bytes, key_bytes);
26        let path_str = from_utf8(path.deref())?;
27        Ok(path_str.to_string())
28    }
29
30    // To find the key value in storage, we need to construct a path to the key
31    // For Map storage this key is generated with get_map_storage_key
32    // For Item storage this key is the namespace value
33    pub fn query_storage<T>(
34        querier: &QuerierWrapper,
35        addr: &Addr,
36        key: &str,
37    ) -> Result<Option<T>, ContractError>
38    where
39        T: DeserializeOwned,
40    {
41        let data = querier.query_wasm_raw(addr, key.as_bytes())?;
42        match data {
43            Some(data) => {
44                let res = from_utf8(&data)?;
45                let res = from_json(res.as_bytes())?;
46                Ok(Some(res))
47            }
48            None => Ok(None),
49        }
50    }
51
52    pub fn ado_type_getter(
53        querier: &QuerierWrapper,
54        adodb_addr: &Addr,
55        code_id: u64,
56    ) -> Result<Option<String>, ContractError> {
57        let key = AOSQuerier::get_map_storage_key("ado_type", &[code_id.to_string().as_bytes()])?;
58        let ado_type: Option<ADOVersion> = AOSQuerier::query_storage(querier, adodb_addr, &key)?;
59        Ok(ado_type.map(|v| v.get_type()))
60    }
61
62    pub fn ado_type_getter_smart(
63        querier: &QuerierWrapper,
64        adodb_addr: &Addr,
65        code_id: u64,
66    ) -> Result<Option<String>, ContractError> {
67        let query = ADODBQueryMsg::ADOType { code_id };
68        let ado_type: Option<ADOVersion> = querier.query_wasm_smart(adodb_addr, &query)?;
69        Ok(ado_type.map(|v| v.get_type()))
70    }
71
72    pub fn ado_publisher_getter(
73        querier: &QuerierWrapper,
74        adodb_addr: &Addr,
75        ado_type: &str,
76    ) -> Result<String, ContractError> {
77        let key = AOSQuerier::get_map_storage_key("publisher", &[ado_type.as_bytes()])?;
78        let verify: Option<String> = AOSQuerier::query_storage(querier, adodb_addr, &key)?;
79
80        match verify {
81            Some(publisher) => Ok(publisher),
82            None => Err(ContractError::InvalidAddress {}),
83        }
84    }
85
86    /// Checks if the code id exists in the ADODB by querying its raw storage for the code id's ado type
87    pub fn verify_code_id(
88        querier: &QuerierWrapper,
89        adodb_addr: &Addr,
90        code_id: u64,
91    ) -> Result<(), ContractError> {
92        let key = AOSQuerier::get_map_storage_key("ado_type", &[code_id.to_string().as_bytes()])?;
93        let verify: Option<String> = AOSQuerier::query_storage(querier, adodb_addr, &key)?;
94
95        if verify.is_some() {
96            Ok(())
97        } else {
98            Err(ContractError::Unauthorized {})
99        }
100    }
101
102    pub fn code_id_getter_raw(
103        querier: &QuerierWrapper,
104        adodb_addr: &Addr,
105        ado_type: &str,
106    ) -> Result<u64, ContractError> {
107        let key = AOSQuerier::get_map_storage_key("code_id", &[ado_type.as_bytes()])?;
108        let verify: Option<u64> = AOSQuerier::query_storage(querier, adodb_addr, &key)?;
109
110        match verify {
111            Some(code_id) => Ok(code_id),
112            None => Err(ContractError::InvalidAddress {}),
113        }
114    }
115
116    pub fn code_id_getter(
117        querier: &QuerierWrapper,
118        adodb_addr: &Addr,
119        ado_type: &str,
120    ) -> Result<u64, ContractError> {
121        let query = ADODBQueryMsg::CodeId {
122            key: ado_type.to_string(),
123        };
124        let code_id: u64 = querier.query_wasm_smart(adodb_addr, &query)?;
125        Ok(code_id)
126    }
127
128    /// Queries the kernel's raw storage for the VFS's address
129    pub fn vfs_address_getter(
130        querier: &QuerierWrapper,
131        kernel_addr: &Addr,
132    ) -> Result<Addr, ContractError> {
133        AOSQuerier::kernel_address_getter(querier, kernel_addr, VFS_KEY)
134    }
135
136    /// Queries the kernel's raw storage for the ADODB's address
137    pub fn adodb_address_getter(
138        querier: &QuerierWrapper,
139        kernel_addr: &Addr,
140    ) -> Result<Addr, ContractError> {
141        AOSQuerier::kernel_address_getter(querier, kernel_addr, ADO_DB_KEY)
142    }
143
144    /// Queries the kernel's raw storage for the VFS's address
145    pub fn kernel_address_getter(
146        querier: &QuerierWrapper,
147        kernel_addr: &Addr,
148        key: &str,
149    ) -> Result<Addr, ContractError> {
150        let key = AOSQuerier::get_map_storage_key("kernel_addresses", &[key.as_bytes()])?;
151        let verify: Option<Addr> = AOSQuerier::query_storage(querier, kernel_addr, &key)?;
152        match verify {
153            Some(address) => Ok(address),
154            None => Err(ContractError::InvalidAddress {}),
155        }
156    }
157
158    pub fn action_fee_getter(
159        querier: &QuerierWrapper,
160        adodb_addr: &Addr,
161        ado_type: &str,
162        action: &str,
163    ) -> Result<Option<ActionFee>, ContractError> {
164        let key = AOSQuerier::get_map_storage_key(
165            "action_fees",
166            &[ado_type.as_bytes(), action.as_bytes()],
167        )?;
168        let fee: Option<ActionFee> = AOSQuerier::query_storage(querier, adodb_addr, &key)?;
169
170        Ok(fee)
171    }
172
173    /// Queries the kernel's raw storage for the VFS's address
174    pub fn ado_owner_getter(
175        querier: &QuerierWrapper,
176        ado_addr: &Addr,
177    ) -> Result<Addr, ContractError> {
178        let verify: Option<Addr> = AOSQuerier::query_storage(querier, ado_addr, "owner")?;
179        match verify {
180            Some(address) => Ok(address),
181            None => Err(ContractError::InvalidAddress {}),
182        }
183    }
184
185    /// Queries the current chain name from the kernel
186    pub fn get_current_chain(
187        querier: &QuerierWrapper,
188        kernel_addr: &Addr,
189    ) -> Result<String, ContractError> {
190        let verify: Option<String> =
191            AOSQuerier::query_storage(querier, kernel_addr, "kernel_curr_chain")?;
192        match verify {
193            Some(chain) => Ok(chain),
194            None => Err(ContractError::InvalidAddress {}),
195        }
196    }
197
198    /// Queries the current chain name from the kernel
199    pub fn get_chain_info(
200        querier: &QuerierWrapper,
201        kernel_addr: &Addr,
202        chain_name: &str,
203    ) -> Result<ChannelInfo, ContractError> {
204        let key = AOSQuerier::get_map_storage_key("kernel_channels", &[chain_name.as_bytes()])?;
205        let verify: Option<ChannelInfo> =
206            AOSQuerier::query_storage(querier, kernel_addr, key.as_str())?;
207        match verify {
208            Some(chain) => Ok(chain),
209            None => Err(ContractError::InvalidAddress {}),
210        }
211    }
212}