1use serde::{de::DeserializeOwned, Serialize};
2use std::ops::Deref;
3
4use crate::addresses::{Addr, CanonicalAddr};
5use crate::binary::Binary;
6use crate::coins::Coin;
7use crate::errors::{RecoverPubkeyError, StdError, StdResult, VerificationError};
8#[cfg(feature = "iterator")]
9use crate::iterator::{Order, Pair};
10use crate::query::{
11 AllBalanceResponse, BalanceResponse, BankQuery, CustomQuery, QueryRequest, WasmQuery,
12};
13#[cfg(feature = "staking")]
14use crate::query::{
15 AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation,
16 DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse,
17};
18use crate::results::{ContractResult, Empty, SystemResult};
19use crate::serde::{from_binary, to_binary, to_vec};
20
21pub trait Storage {
24 fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
30
31 #[cfg(feature = "iterator")]
32 fn range<'a>(
38 &'a self,
39 start: Option<&[u8]>,
40 end: Option<&[u8]>,
41 order: Order,
42 ) -> Box<dyn Iterator<Item = Pair> + 'a>;
43
44 fn set(&mut self, key: &[u8], value: &[u8]);
45 fn remove(&mut self, key: &[u8]);
50}
51
52pub trait Api {
67 fn addr_validate(&self, human: &str) -> StdResult<Addr>;
81
82 fn addr_canonicalize(&self, human: &str) -> StdResult<CanonicalAddr>;
85
86 fn addr_humanize(&self, canonical: &CanonicalAddr) -> StdResult<Addr>;
91
92 fn secp256k1_verify(
93 &self,
94 message_hash: &[u8],
95 signature: &[u8],
96 public_key: &[u8],
97 ) -> Result<bool, VerificationError>;
98
99 fn secp256k1_recover_pubkey(
100 &self,
101 message_hash: &[u8],
102 signature: &[u8],
103 recovery_param: u8,
104 ) -> Result<Vec<u8>, RecoverPubkeyError>;
105
106 fn ed25519_verify(
107 &self,
108 message: &[u8],
109 signature: &[u8],
110 public_key: &[u8],
111 ) -> Result<bool, VerificationError>;
112
113 fn ed25519_batch_verify(
114 &self,
115 messages: &[&[u8]],
116 signatures: &[&[u8]],
117 public_keys: &[&[u8]],
118 ) -> Result<bool, VerificationError>;
119
120 fn debug(&self, message: &str);
123}
124
125pub type QuerierResult = SystemResult<ContractResult<Binary>>;
127
128pub trait Querier {
129 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult;
135}
136
137#[derive(Copy, Clone)]
138pub struct QuerierWrapper<'a>(&'a dyn Querier);
139
140impl<'a> Deref for QuerierWrapper<'a> {
143 type Target = dyn Querier + 'a;
144
145 fn deref(&self) -> &Self::Target {
146 self.0
147 }
148}
149
150impl<'a> QuerierWrapper<'a> {
151 pub fn new(querier: &'a dyn Querier) -> Self {
152 QuerierWrapper(querier)
153 }
154
155 pub fn query<T: DeserializeOwned>(&self, request: &QueryRequest<Empty>) -> StdResult<T> {
158 self.custom_query(request)
159 }
160
161 pub fn custom_query<C: CustomQuery, U: DeserializeOwned>(
169 &self,
170 request: &QueryRequest<C>,
171 ) -> StdResult<U> {
172 let raw = to_vec(request).map_err(|serialize_err| {
173 StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err))
174 })?;
175 match self.raw_query(&raw) {
176 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
177 "Querier system error: {}",
178 system_err
179 ))),
180 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
181 format!("Querier contract error: {}", contract_err),
182 )),
183 SystemResult::Ok(ContractResult::Ok(value)) => from_binary(&value),
184 }
185 }
186
187 pub fn query_balance(
188 &self,
189 address: impl Into<String>,
190 denom: impl Into<String>,
191 ) -> StdResult<Coin> {
192 let request = BankQuery::Balance {
193 address: address.into(),
194 denom: denom.into(),
195 }
196 .into();
197 let res: BalanceResponse = self.query(&request)?;
198 Ok(res.amount)
199 }
200
201 pub fn query_all_balances(&self, address: impl Into<String>) -> StdResult<Vec<Coin>> {
202 let request = BankQuery::AllBalances {
203 address: address.into(),
204 }
205 .into();
206 let res: AllBalanceResponse = self.query(&request)?;
207 Ok(res.amount)
208 }
209
210 pub fn query_wasm_smart<T: DeserializeOwned>(
213 &self,
214 contract_addr: impl Into<String>,
215 msg: &impl Serialize,
216 ) -> StdResult<T> {
217 let request = WasmQuery::Smart {
218 contract_addr: contract_addr.into(),
219 msg: to_binary(msg)?,
220 }
221 .into();
222 self.query(&request)
223 }
224
225 pub fn query_wasm_raw(
233 &self,
234 contract_addr: impl Into<String>,
235 key: impl Into<Binary>,
236 ) -> StdResult<Option<Vec<u8>>> {
237 let request: QueryRequest<Empty> = WasmQuery::Raw {
238 contract_addr: contract_addr.into(),
239 key: key.into(),
240 }
241 .into();
242 let raw = to_vec(&request).map_err(|serialize_err| {
245 StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err))
246 })?;
247 match self.raw_query(&raw) {
248 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
249 "Querier system error: {}",
250 system_err
251 ))),
252 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
253 format!("Querier contract error: {}", contract_err),
254 )),
255 SystemResult::Ok(ContractResult::Ok(value)) => {
256 if value.is_empty() {
257 Ok(None)
258 } else {
259 Ok(Some(value.into()))
260 }
261 }
262 }
263 }
264
265 #[cfg(feature = "staking")]
266 pub fn query_all_validators(&self) -> StdResult<Vec<Validator>> {
267 let request = StakingQuery::AllValidators {}.into();
268 let res: AllValidatorsResponse = self.query(&request)?;
269 Ok(res.validators)
270 }
271
272 #[cfg(feature = "staking")]
273 pub fn query_validator(&self, address: impl Into<String>) -> StdResult<Option<Validator>> {
274 let request = StakingQuery::Validator {
275 address: address.into(),
276 }
277 .into();
278 let res: ValidatorResponse = self.query(&request)?;
279 Ok(res.validator)
280 }
281
282 #[cfg(feature = "staking")]
283 pub fn query_bonded_denom(&self) -> StdResult<String> {
284 let request = StakingQuery::BondedDenom {}.into();
285 let res: BondedDenomResponse = self.query(&request)?;
286 Ok(res.denom)
287 }
288
289 #[cfg(feature = "staking")]
290 pub fn query_all_delegations(
291 &self,
292 delegator: impl Into<String>,
293 ) -> StdResult<Vec<Delegation>> {
294 let request = StakingQuery::AllDelegations {
295 delegator: delegator.into(),
296 }
297 .into();
298 let res: AllDelegationsResponse = self.query(&request)?;
299 Ok(res.delegations)
300 }
301
302 #[cfg(feature = "staking")]
303 pub fn query_delegation(
304 &self,
305 delegator: impl Into<String>,
306 validator: impl Into<String>,
307 ) -> StdResult<Option<FullDelegation>> {
308 let request = StakingQuery::Delegation {
309 delegator: delegator.into(),
310 validator: validator.into(),
311 }
312 .into();
313 let res: DelegationResponse = self.query(&request)?;
314 Ok(res.delegation)
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321 use crate::mock::MockQuerier;
322 use crate::{coins, from_slice, Uint128};
323
324 fn demo_helper(_querier: &dyn Querier) -> u64 {
326 2
327 }
328
329 #[test]
331 fn use_querier_wrapper_as_querier() {
332 let querier: MockQuerier<Empty> = MockQuerier::new(&[]);
333 let wrapper = QuerierWrapper::new(&querier);
334
335 let res = demo_helper(&*wrapper);
337 assert_eq!(2, res);
338
339 let res = demo_helper(wrapper.deref());
341 assert_eq!(2, res);
342 }
343
344 #[test]
345 fn auto_deref_raw_query() {
346 let acct = String::from("foobar");
347 let querier: MockQuerier<Empty> = MockQuerier::new(&[(&acct, &coins(5, "BTC"))]);
348 let wrapper = QuerierWrapper::new(&querier);
349 let query = QueryRequest::<Empty>::Bank(BankQuery::Balance {
350 address: acct,
351 denom: "BTC".to_string(),
352 });
353
354 let raw = wrapper
355 .raw_query(&to_vec(&query).unwrap())
356 .unwrap()
357 .unwrap();
358 let balance: BalanceResponse = from_slice(&raw).unwrap();
359 assert_eq!(balance.amount.amount, Uint128::new(5));
360 }
361}