1use core::marker::PhantomData;
2use core::ops::Deref;
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::coin::Coin;
6#[cfg(feature = "iterator")]
7use crate::iterator::{Order, Record};
8use crate::prelude::*;
9#[cfg(feature = "cosmwasm_1_2")]
10use crate::query::CodeInfoResponse;
11#[cfg(feature = "cosmwasm_1_1")]
12use crate::query::SupplyResponse;
13use crate::query::{
14 AllBalanceResponse, BalanceResponse, BankQuery, CustomQuery, QueryRequest, WasmQuery,
15};
16#[cfg(feature = "staking")]
17use crate::query::{
18 AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation,
19 DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse,
20};
21#[cfg(feature = "cosmwasm_1_3")]
22use crate::query::{
23 AllDenomMetadataResponse, DelegatorWithdrawAddressResponse, DenomMetadataResponse,
24 DistributionQuery,
25};
26use crate::results::{ContractResult, Empty, SystemResult};
27use crate::ContractInfoResponse;
28use crate::{from_json, to_json_binary, to_json_vec, Binary};
29use crate::{Addr, CanonicalAddr};
30#[cfg(feature = "cosmwasm_1_3")]
31use crate::{DenomMetadata, PageRequest};
32use crate::{RecoverPubkeyError, StdError, StdResult, VerificationError};
33
34#[derive(Clone, Copy, Debug)]
35#[non_exhaustive]
36pub enum HashFunction {
37 Sha256 = 0,
38}
39
40#[cfg(not(target_arch = "wasm32"))]
41impl From<HashFunction> for cosmwasm_crypto::HashFunction {
42 fn from(value: HashFunction) -> Self {
43 match value {
44 HashFunction::Sha256 => cosmwasm_crypto::HashFunction::Sha256,
45 }
46 }
47}
48
49pub trait Storage {
52 fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
58
59 #[cfg(feature = "iterator")]
64 #[allow(unused_variables)]
65 fn range<'a>(
66 &'a self,
67 start: Option<&[u8]>,
68 end: Option<&[u8]>,
69 order: Order,
70 ) -> Box<dyn Iterator<Item = Record> + 'a> {
71 unimplemented!("This storage does not support ranging. Make sure to override the `range` method in your `Storage` implementation.")
74 }
75
76 #[cfg(feature = "iterator")]
84 fn range_keys<'a>(
85 &'a self,
86 start: Option<&[u8]>,
87 end: Option<&[u8]>,
88 order: Order,
89 ) -> Box<dyn Iterator<Item = Vec<u8>> + 'a> {
90 Box::new(self.range(start, end, order).map(|(k, _v)| k))
91 }
92
93 #[cfg(feature = "iterator")]
101 fn range_values<'a>(
102 &'a self,
103 start: Option<&[u8]>,
104 end: Option<&[u8]>,
105 order: Order,
106 ) -> Box<dyn Iterator<Item = Vec<u8>> + 'a> {
107 Box::new(self.range(start, end, order).map(|(_k, v)| v))
108 }
109
110 fn set(&mut self, key: &[u8], value: &[u8]);
111
112 fn remove(&mut self, key: &[u8]);
117}
118
119pub trait Api {
134 fn addr_validate(&self, human: &str) -> StdResult<Addr>;
158
159 fn addr_canonicalize(&self, human: &str) -> StdResult<CanonicalAddr>;
166
167 fn addr_humanize(&self, canonical: &CanonicalAddr) -> StdResult<Addr>;
172
173 fn secp256k1_verify(
174 &self,
175 message_hash: &[u8],
176 signature: &[u8],
177 public_key: &[u8],
178 ) -> Result<bool, VerificationError>;
179
180 fn secp256k1_recover_pubkey(
181 &self,
182 message_hash: &[u8],
183 signature: &[u8],
184 recovery_param: u8,
185 ) -> Result<Vec<u8>, RecoverPubkeyError>;
186
187 #[allow(unused_variables)]
188 fn bls12_381_aggregate_g1(&self, g1s: &[u8]) -> Result<[u8; 48], VerificationError> {
189 unimplemented!()
194 }
195
196 #[allow(unused_variables)]
197 fn bls12_381_aggregate_g2(&self, g2s: &[u8]) -> Result<[u8; 96], VerificationError> {
198 unimplemented!()
203 }
204
205 #[allow(unused_variables)]
232 fn bls12_381_pairing_equality(
233 &self,
234 ps: &[u8],
235 qs: &[u8],
236 r: &[u8],
237 s: &[u8],
238 ) -> Result<bool, VerificationError> {
239 unimplemented!()
244 }
245
246 #[allow(unused_variables)]
247 fn bls12_381_hash_to_g1(
248 &self,
249 hash_function: HashFunction,
250 msg: &[u8],
251 dst: &[u8],
252 ) -> Result<[u8; 48], VerificationError> {
253 unimplemented!()
258 }
259
260 #[allow(unused_variables)]
261 fn bls12_381_hash_to_g2(
262 &self,
263 hash_function: HashFunction,
264 msg: &[u8],
265 dst: &[u8],
266 ) -> Result<[u8; 96], VerificationError> {
267 unimplemented!()
272 }
273
274 #[allow(unused_variables)]
275 fn secp256r1_verify(
276 &self,
277 message_hash: &[u8],
278 signature: &[u8],
279 public_key: &[u8],
280 ) -> Result<bool, VerificationError> {
281 unimplemented!()
286 }
287
288 #[allow(unused_variables)]
289 fn secp256r1_recover_pubkey(
290 &self,
291 message_hash: &[u8],
292 signature: &[u8],
293 recovery_param: u8,
294 ) -> Result<Vec<u8>, RecoverPubkeyError> {
295 unimplemented!()
300 }
301
302 fn ed25519_verify(
303 &self,
304 message: &[u8],
305 signature: &[u8],
306 public_key: &[u8],
307 ) -> Result<bool, VerificationError>;
308
309 fn ed25519_batch_verify(
310 &self,
311 messages: &[&[u8]],
312 signatures: &[&[u8]],
313 public_keys: &[&[u8]],
314 ) -> Result<bool, VerificationError>;
315
316 fn debug(&self, message: &str);
319}
320
321pub type QuerierResult = SystemResult<ContractResult<Binary>>;
323
324pub trait Querier {
325 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult;
331}
332
333#[derive(Clone)]
334pub struct QuerierWrapper<'a, C: CustomQuery = Empty> {
335 querier: &'a dyn Querier,
336 custom_query_type: PhantomData<C>,
337}
338
339impl<'a, C: CustomQuery> Copy for QuerierWrapper<'a, C> {}
344
345impl<'a, C: CustomQuery> Deref for QuerierWrapper<'a, C> {
348 type Target = dyn Querier + 'a;
349
350 fn deref(&self) -> &Self::Target {
351 self.querier
352 }
353}
354
355impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
356 pub fn new(querier: &'a dyn Querier) -> Self {
357 QuerierWrapper {
358 querier,
359 custom_query_type: PhantomData,
360 }
361 }
362
363 pub fn into_empty(self) -> QuerierWrapper<'a, Empty> {
366 QuerierWrapper {
367 querier: self.querier,
368 custom_query_type: PhantomData,
369 }
370 }
371
372 pub fn query<U: DeserializeOwned>(&self, request: &QueryRequest<C>) -> StdResult<U> {
378 self.query_raw(request).and_then(|raw| from_json(raw))
379 }
380
381 fn query_raw(&self, request: &QueryRequest<C>) -> StdResult<Binary> {
385 let raw = to_json_vec(request).map_err(|serialize_err| {
386 StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}"))
387 })?;
388 match self.raw_query(&raw) {
389 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
390 "Querier system error: {system_err}"
391 ))),
392 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
393 format!("Querier contract error: {contract_err}"),
394 )),
395 SystemResult::Ok(ContractResult::Ok(value)) => Ok(value),
396 }
397 }
398
399 #[cfg(feature = "cosmwasm_1_1")]
400 pub fn query_supply(&self, denom: impl Into<String>) -> StdResult<Coin> {
401 let request = BankQuery::Supply {
402 denom: denom.into(),
403 }
404 .into();
405 let res: SupplyResponse = self.query(&request)?;
406 Ok(res.amount)
407 }
408
409 pub fn query_balance(
410 &self,
411 address: impl Into<String>,
412 denom: impl Into<String>,
413 ) -> StdResult<Coin> {
414 let request = BankQuery::Balance {
415 address: address.into(),
416 denom: denom.into(),
417 }
418 .into();
419 let res: BalanceResponse = self.query(&request)?;
420 Ok(res.amount)
421 }
422
423 pub fn query_all_balances(&self, address: impl Into<String>) -> StdResult<Vec<Coin>> {
424 let request = BankQuery::AllBalances {
425 address: address.into(),
426 }
427 .into();
428 let res: AllBalanceResponse = self.query(&request)?;
429 Ok(res.amount)
430 }
431
432 #[cfg(feature = "cosmwasm_1_3")]
433 pub fn query_delegator_withdraw_address(
434 &self,
435 delegator: impl Into<String>,
436 ) -> StdResult<Addr> {
437 let request = DistributionQuery::DelegatorWithdrawAddress {
438 delegator_address: delegator.into(),
439 }
440 .into();
441 let res: DelegatorWithdrawAddressResponse = self.query(&request)?;
442 Ok(res.withdraw_address)
443 }
444
445 #[cfg(feature = "cosmwasm_1_3")]
446 pub fn query_denom_metadata(&self, denom: impl Into<String>) -> StdResult<DenomMetadata> {
447 let request = BankQuery::DenomMetadata {
448 denom: denom.into(),
449 }
450 .into();
451 let res: DenomMetadataResponse = self.query(&request)?;
452 Ok(res.metadata)
453 }
454
455 #[cfg(feature = "cosmwasm_1_3")]
456 pub fn query_all_denom_metadata(
457 &self,
458 pagination: PageRequest,
459 ) -> StdResult<AllDenomMetadataResponse> {
460 let request = BankQuery::AllDenomMetadata {
461 pagination: Some(pagination),
462 }
463 .into();
464 self.query(&request)
465 }
466
467 #[cfg(feature = "cosmwasm_1_4")]
468 pub fn query_delegation_rewards(
469 &self,
470 delegator: impl Into<String>,
471 validator: impl Into<String>,
472 ) -> StdResult<Vec<crate::DecCoin>> {
473 use crate::DelegationRewardsResponse;
474
475 let request = DistributionQuery::DelegationRewards {
476 delegator_address: delegator.into(),
477 validator_address: validator.into(),
478 }
479 .into();
480 let DelegationRewardsResponse { rewards } = self.query(&request)?;
481
482 Ok(rewards)
483 }
484
485 #[cfg(feature = "cosmwasm_1_4")]
486 pub fn query_delegation_total_rewards(
487 &self,
488 delegator: impl Into<String>,
489 ) -> StdResult<crate::DelegationTotalRewardsResponse> {
490 let request = DistributionQuery::DelegationTotalRewards {
491 delegator_address: delegator.into(),
492 }
493 .into();
494 self.query(&request)
495 }
496
497 #[cfg(feature = "cosmwasm_1_4")]
498 pub fn query_delegator_validators(
499 &self,
500 delegator: impl Into<String>,
501 ) -> StdResult<Vec<String>> {
502 use crate::DelegatorValidatorsResponse;
503
504 let request = DistributionQuery::DelegatorValidators {
505 delegator_address: delegator.into(),
506 }
507 .into();
508 let res: DelegatorValidatorsResponse = self.query(&request)?;
509 Ok(res.validators)
510 }
511
512 #[cfg(feature = "cosmwasm_2_0")]
514 pub fn query_grpc(&self, path: String, data: Binary) -> StdResult<Binary> {
515 use crate::GrpcQuery;
516 self.query_raw(&QueryRequest::Grpc(GrpcQuery { path, data }))
517 }
518
519 pub fn query_wasm_smart<T: DeserializeOwned>(
522 &self,
523 contract_addr: impl Into<String>,
524 msg: &impl Serialize,
525 ) -> StdResult<T> {
526 let request = WasmQuery::Smart {
527 contract_addr: contract_addr.into(),
528 msg: to_json_binary(msg)?,
529 }
530 .into();
531 self.query(&request)
532 }
533
534 pub fn query_wasm_raw(
543 &self,
544 contract_addr: impl Into<String>,
545 key: impl Into<Binary>,
546 ) -> StdResult<Option<Vec<u8>>> {
547 let request: QueryRequest<Empty> = WasmQuery::Raw {
548 contract_addr: contract_addr.into(),
549 key: key.into(),
550 }
551 .into();
552 let raw = to_json_vec(&request).map_err(|serialize_err| {
555 StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}"))
556 })?;
557 match self.raw_query(&raw) {
558 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
559 "Querier system error: {system_err}"
560 ))),
561 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
562 format!("Querier contract error: {contract_err}"),
563 )),
564 SystemResult::Ok(ContractResult::Ok(value)) => {
565 if value.is_empty() {
566 Ok(None)
567 } else {
568 Ok(Some(value.into()))
569 }
570 }
571 }
572 }
573
574 pub fn query_wasm_contract_info(
576 &self,
577 contract_addr: impl Into<String>,
578 ) -> StdResult<ContractInfoResponse> {
579 let request = WasmQuery::ContractInfo {
580 contract_addr: contract_addr.into(),
581 }
582 .into();
583 self.query(&request)
584 }
585
586 #[cfg(feature = "cosmwasm_1_2")]
588 pub fn query_wasm_code_info(&self, code_id: u64) -> StdResult<CodeInfoResponse> {
589 let request = WasmQuery::CodeInfo { code_id }.into();
590 self.query(&request)
591 }
592
593 #[cfg(feature = "staking")]
594 pub fn query_all_validators(&self) -> StdResult<Vec<Validator>> {
595 let request = StakingQuery::AllValidators {}.into();
596 let res: AllValidatorsResponse = self.query(&request)?;
597 Ok(res.validators)
598 }
599
600 #[cfg(feature = "staking")]
601 pub fn query_validator(&self, address: impl Into<String>) -> StdResult<Option<Validator>> {
602 let request = StakingQuery::Validator {
603 address: address.into(),
604 }
605 .into();
606 let res: ValidatorResponse = self.query(&request)?;
607 Ok(res.validator)
608 }
609
610 #[cfg(feature = "staking")]
611 pub fn query_bonded_denom(&self) -> StdResult<String> {
612 let request = StakingQuery::BondedDenom {}.into();
613 let res: BondedDenomResponse = self.query(&request)?;
614 Ok(res.denom)
615 }
616
617 #[cfg(feature = "staking")]
618 pub fn query_all_delegations(
619 &self,
620 delegator: impl Into<String>,
621 ) -> StdResult<Vec<Delegation>> {
622 let request = StakingQuery::AllDelegations {
623 delegator: delegator.into(),
624 }
625 .into();
626 let res: AllDelegationsResponse = self.query(&request)?;
627 Ok(res.delegations)
628 }
629
630 #[cfg(feature = "staking")]
631 pub fn query_delegation(
632 &self,
633 delegator: impl Into<String>,
634 validator: impl Into<String>,
635 ) -> StdResult<Option<FullDelegation>> {
636 let request = StakingQuery::Delegation {
637 delegator: delegator.into(),
638 validator: validator.into(),
639 }
640 .into();
641 let res: DelegationResponse = self.query(&request)?;
642 Ok(res.delegation)
643 }
644}
645
646#[cfg(test)]
647mod tests {
648 use serde::Deserialize;
649
650 use super::*;
651 use crate::testing::MockQuerier;
652 use crate::{coins, Uint128};
653
654 fn demo_helper(_querier: &dyn Querier) -> u64 {
656 2
657 }
658
659 #[test]
661 fn use_querier_wrapper_as_querier() {
662 let querier: MockQuerier<Empty> = MockQuerier::new(&[]);
663 let wrapper = QuerierWrapper::<Empty>::new(&querier);
664
665 let res = demo_helper(&*wrapper);
667 assert_eq!(2, res);
668
669 let res = demo_helper(wrapper.deref());
671 assert_eq!(2, res);
672 }
673
674 #[test]
675 fn auto_deref_raw_query() {
676 let acct = String::from("foobar");
677 let querier: MockQuerier<Empty> = MockQuerier::new(&[(&acct, &coins(5, "BTC"))]);
678 let wrapper = QuerierWrapper::<Empty>::new(&querier);
679 let query = QueryRequest::<Empty>::Bank(BankQuery::Balance {
680 address: acct,
681 denom: "BTC".to_string(),
682 });
683
684 let raw = wrapper
685 .raw_query(&to_json_vec(&query).unwrap())
686 .unwrap()
687 .unwrap();
688 let balance: BalanceResponse = from_json(raw).unwrap();
689 assert_eq!(balance.amount.amount, Uint128::new(5));
690 }
691
692 #[cfg(feature = "cosmwasm_1_1")]
693 #[test]
694 fn bank_query_helpers_work() {
695 use crate::coin;
696
697 let querier: MockQuerier<Empty> = MockQuerier::new(&[
698 ("foo", &[coin(123, "ELF"), coin(777, "FLY")]),
699 ("bar", &[coin(321, "ELF")]),
700 ]);
701 let wrapper = QuerierWrapper::<Empty>::new(&querier);
702
703 let supply = wrapper.query_supply("ELF").unwrap();
704 assert_eq!(supply, coin(444, "ELF"));
705
706 let balance = wrapper.query_balance("foo", "ELF").unwrap();
707 assert_eq!(balance, coin(123, "ELF"));
708
709 let all_balances = wrapper.query_all_balances("foo").unwrap();
710 assert_eq!(all_balances, vec![coin(123, "ELF"), coin(777, "FLY")]);
711 }
712
713 #[test]
714 fn contract_info() {
715 const ACCT: &str = "foobar";
716 fn mock_resp() -> ContractInfoResponse {
717 ContractInfoResponse {
718 code_id: 0,
719 creator: Addr::unchecked("creator"),
720 admin: None,
721 pinned: false,
722 ibc_port: None,
723 }
724 }
725
726 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
727 querier.update_wasm(|q| -> QuerierResult {
728 if q == &(WasmQuery::ContractInfo {
729 contract_addr: ACCT.to_string(),
730 }) {
731 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
732 } else {
733 SystemResult::Err(crate::SystemError::NoSuchContract {
734 addr: ACCT.to_string(),
735 })
736 }
737 });
738 let wrapper = QuerierWrapper::<Empty>::new(&querier);
739
740 let contract_info = wrapper.query_wasm_contract_info(ACCT).unwrap();
741 assert_eq!(contract_info, mock_resp());
742 }
743
744 #[test]
745 fn contract_info_err() {
746 const ACCT: &str = "foobar";
747 fn mock_resp() -> ContractInfoResponse {
748 ContractInfoResponse {
749 code_id: 0,
750 creator: Addr::unchecked("creator"),
751 admin: None,
752 pinned: false,
753 ibc_port: None,
754 }
755 }
756
757 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
758 querier.update_wasm(|q| -> QuerierResult {
759 if q == &(WasmQuery::ContractInfo {
760 contract_addr: ACCT.to_string(),
761 }) {
762 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
763 } else {
764 SystemResult::Err(crate::SystemError::NoSuchContract {
765 addr: ACCT.to_string(),
766 })
767 }
768 });
769 let wrapper = QuerierWrapper::<Empty>::new(&querier);
770
771 let err = wrapper.query_wasm_contract_info("unknown").unwrap_err();
772 assert!(matches!(
773 err,
774 StdError::GenericErr {
775 msg,
776 ..
777 } if msg == "Querier system error: No such contract: foobar"
778 ));
779 }
780
781 #[test]
782 fn querier_into_empty() {
783 #[derive(Clone, Serialize, Deserialize)]
784 struct MyQuery;
785 impl CustomQuery for MyQuery {}
786
787 let querier: MockQuerier<MyQuery> = MockQuerier::new(&[]);
788 let wrapper = QuerierWrapper::<MyQuery>::new(&querier);
789
790 let _: QuerierWrapper<Empty> = wrapper.into_empty();
791 }
792}