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 #[deprecated]
424 pub fn query_all_balances(&self, address: impl Into<String>) -> StdResult<Vec<Coin>> {
425 #[allow(deprecated)]
426 let request = BankQuery::AllBalances {
427 address: address.into(),
428 }
429 .into();
430 let res: AllBalanceResponse = self.query(&request)?;
431 Ok(res.amount)
432 }
433
434 #[cfg(feature = "cosmwasm_1_3")]
435 pub fn query_delegator_withdraw_address(
436 &self,
437 delegator: impl Into<String>,
438 ) -> StdResult<Addr> {
439 let request = DistributionQuery::DelegatorWithdrawAddress {
440 delegator_address: delegator.into(),
441 }
442 .into();
443 let res: DelegatorWithdrawAddressResponse = self.query(&request)?;
444 Ok(res.withdraw_address)
445 }
446
447 #[cfg(feature = "cosmwasm_1_3")]
448 pub fn query_denom_metadata(&self, denom: impl Into<String>) -> StdResult<DenomMetadata> {
449 let request = BankQuery::DenomMetadata {
450 denom: denom.into(),
451 }
452 .into();
453 let res: DenomMetadataResponse = self.query(&request)?;
454 Ok(res.metadata)
455 }
456
457 #[cfg(feature = "cosmwasm_1_3")]
458 pub fn query_all_denom_metadata(
459 &self,
460 pagination: PageRequest,
461 ) -> StdResult<AllDenomMetadataResponse> {
462 let request = BankQuery::AllDenomMetadata {
463 pagination: Some(pagination),
464 }
465 .into();
466 self.query(&request)
467 }
468
469 #[cfg(feature = "cosmwasm_1_4")]
470 pub fn query_delegation_rewards(
471 &self,
472 delegator: impl Into<String>,
473 validator: impl Into<String>,
474 ) -> StdResult<Vec<crate::DecCoin>> {
475 use crate::DelegationRewardsResponse;
476
477 let request = DistributionQuery::DelegationRewards {
478 delegator_address: delegator.into(),
479 validator_address: validator.into(),
480 }
481 .into();
482 let DelegationRewardsResponse { rewards } = self.query(&request)?;
483
484 Ok(rewards)
485 }
486
487 #[cfg(feature = "cosmwasm_1_4")]
488 pub fn query_delegation_total_rewards(
489 &self,
490 delegator: impl Into<String>,
491 ) -> StdResult<crate::DelegationTotalRewardsResponse> {
492 let request = DistributionQuery::DelegationTotalRewards {
493 delegator_address: delegator.into(),
494 }
495 .into();
496 self.query(&request)
497 }
498
499 #[cfg(feature = "cosmwasm_1_4")]
500 pub fn query_delegator_validators(
501 &self,
502 delegator: impl Into<String>,
503 ) -> StdResult<Vec<String>> {
504 use crate::DelegatorValidatorsResponse;
505
506 let request = DistributionQuery::DelegatorValidators {
507 delegator_address: delegator.into(),
508 }
509 .into();
510 let res: DelegatorValidatorsResponse = self.query(&request)?;
511 Ok(res.validators)
512 }
513
514 #[cfg(feature = "cosmwasm_2_0")]
516 pub fn query_grpc(&self, path: String, data: Binary) -> StdResult<Binary> {
517 use crate::GrpcQuery;
518 self.query_raw(&QueryRequest::Grpc(GrpcQuery { path, data }))
519 }
520
521 pub fn query_wasm_smart<T: DeserializeOwned>(
524 &self,
525 contract_addr: impl Into<String>,
526 msg: &impl Serialize,
527 ) -> StdResult<T> {
528 let request = WasmQuery::Smart {
529 contract_addr: contract_addr.into(),
530 msg: to_json_binary(msg)?,
531 }
532 .into();
533 self.query(&request)
534 }
535
536 pub fn query_wasm_raw(
545 &self,
546 contract_addr: impl Into<String>,
547 key: impl Into<Binary>,
548 ) -> StdResult<Option<Vec<u8>>> {
549 let request: QueryRequest<Empty> = WasmQuery::Raw {
550 contract_addr: contract_addr.into(),
551 key: key.into(),
552 }
553 .into();
554 let raw = to_json_vec(&request).map_err(|serialize_err| {
557 StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}"))
558 })?;
559 match self.raw_query(&raw) {
560 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
561 "Querier system error: {system_err}"
562 ))),
563 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
564 format!("Querier contract error: {contract_err}"),
565 )),
566 SystemResult::Ok(ContractResult::Ok(value)) => {
567 if value.is_empty() {
568 Ok(None)
569 } else {
570 Ok(Some(value.into()))
571 }
572 }
573 }
574 }
575
576 pub fn query_wasm_contract_info(
578 &self,
579 contract_addr: impl Into<String>,
580 ) -> StdResult<ContractInfoResponse> {
581 let request = WasmQuery::ContractInfo {
582 contract_addr: contract_addr.into(),
583 }
584 .into();
585 self.query(&request)
586 }
587
588 #[cfg(feature = "cosmwasm_1_2")]
590 pub fn query_wasm_code_info(&self, code_id: u64) -> StdResult<CodeInfoResponse> {
591 let request = WasmQuery::CodeInfo { code_id }.into();
592 self.query(&request)
593 }
594
595 #[cfg(feature = "staking")]
596 pub fn query_all_validators(&self) -> StdResult<Vec<Validator>> {
597 let request = StakingQuery::AllValidators {}.into();
598 let res: AllValidatorsResponse = self.query(&request)?;
599 Ok(res.validators)
600 }
601
602 #[cfg(feature = "staking")]
603 pub fn query_validator(&self, address: impl Into<String>) -> StdResult<Option<Validator>> {
604 let request = StakingQuery::Validator {
605 address: address.into(),
606 }
607 .into();
608 let res: ValidatorResponse = self.query(&request)?;
609 Ok(res.validator)
610 }
611
612 #[cfg(feature = "staking")]
613 pub fn query_bonded_denom(&self) -> StdResult<String> {
614 let request = StakingQuery::BondedDenom {}.into();
615 let res: BondedDenomResponse = self.query(&request)?;
616 Ok(res.denom)
617 }
618
619 #[cfg(feature = "staking")]
620 pub fn query_all_delegations(
621 &self,
622 delegator: impl Into<String>,
623 ) -> StdResult<Vec<Delegation>> {
624 let request = StakingQuery::AllDelegations {
625 delegator: delegator.into(),
626 }
627 .into();
628 let res: AllDelegationsResponse = self.query(&request)?;
629 Ok(res.delegations)
630 }
631
632 #[cfg(feature = "staking")]
633 pub fn query_delegation(
634 &self,
635 delegator: impl Into<String>,
636 validator: impl Into<String>,
637 ) -> StdResult<Option<FullDelegation>> {
638 let request = StakingQuery::Delegation {
639 delegator: delegator.into(),
640 validator: validator.into(),
641 }
642 .into();
643 let res: DelegationResponse = self.query(&request)?;
644 Ok(res.delegation)
645 }
646}
647
648#[cfg(test)]
649mod tests {
650 use serde::Deserialize;
651
652 use super::*;
653 use crate::testing::MockQuerier;
654 use crate::{coins, Uint128};
655
656 fn demo_helper(_querier: &dyn Querier) -> u64 {
658 2
659 }
660
661 #[test]
663 fn use_querier_wrapper_as_querier() {
664 let querier: MockQuerier<Empty> = MockQuerier::new(&[]);
665 let wrapper = QuerierWrapper::<Empty>::new(&querier);
666
667 let res = demo_helper(&*wrapper);
669 assert_eq!(2, res);
670
671 let res = demo_helper(wrapper.deref());
673 assert_eq!(2, res);
674 }
675
676 #[test]
677 fn auto_deref_raw_query() {
678 let acct = String::from("foobar");
679 let querier: MockQuerier<Empty> = MockQuerier::new(&[(&acct, &coins(5, "BTC"))]);
680 let wrapper = QuerierWrapper::<Empty>::new(&querier);
681 let query = QueryRequest::<Empty>::Bank(BankQuery::Balance {
682 address: acct,
683 denom: "BTC".to_string(),
684 });
685
686 let raw = wrapper
687 .raw_query(&to_json_vec(&query).unwrap())
688 .unwrap()
689 .unwrap();
690 let balance: BalanceResponse = from_json(raw).unwrap();
691 assert_eq!(balance.amount.amount, Uint128::new(5));
692 }
693
694 #[cfg(feature = "cosmwasm_1_1")]
695 #[test]
696 fn bank_query_helpers_work() {
697 use crate::coin;
698
699 let querier: MockQuerier<Empty> = MockQuerier::new(&[
700 ("foo", &[coin(123, "ELF"), coin(777, "FLY")]),
701 ("bar", &[coin(321, "ELF")]),
702 ]);
703 let wrapper = QuerierWrapper::<Empty>::new(&querier);
704
705 let supply = wrapper.query_supply("ELF").unwrap();
706 assert_eq!(supply, coin(444, "ELF"));
707
708 let balance = wrapper.query_balance("foo", "ELF").unwrap();
709 assert_eq!(balance, coin(123, "ELF"));
710
711 #[allow(deprecated)]
712 let all_balances = wrapper.query_all_balances("foo").unwrap();
713 assert_eq!(all_balances, vec![coin(123, "ELF"), coin(777, "FLY")]);
714 }
715
716 #[test]
717 fn contract_info() {
718 const ACCT: &str = "foobar";
719 fn mock_resp() -> ContractInfoResponse {
720 ContractInfoResponse {
721 code_id: 0,
722 creator: Addr::unchecked("creator"),
723 admin: None,
724 pinned: false,
725 ibc_port: None,
726 }
727 }
728
729 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
730 querier.update_wasm(|q| -> QuerierResult {
731 if q == &(WasmQuery::ContractInfo {
732 contract_addr: ACCT.to_string(),
733 }) {
734 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
735 } else {
736 SystemResult::Err(crate::SystemError::NoSuchContract {
737 addr: ACCT.to_string(),
738 })
739 }
740 });
741 let wrapper = QuerierWrapper::<Empty>::new(&querier);
742
743 let contract_info = wrapper.query_wasm_contract_info(ACCT).unwrap();
744 assert_eq!(contract_info, mock_resp());
745 }
746
747 #[test]
748 fn contract_info_err() {
749 const ACCT: &str = "foobar";
750 fn mock_resp() -> ContractInfoResponse {
751 ContractInfoResponse {
752 code_id: 0,
753 creator: Addr::unchecked("creator"),
754 admin: None,
755 pinned: false,
756 ibc_port: None,
757 }
758 }
759
760 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
761 querier.update_wasm(|q| -> QuerierResult {
762 if q == &(WasmQuery::ContractInfo {
763 contract_addr: ACCT.to_string(),
764 }) {
765 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
766 } else {
767 SystemResult::Err(crate::SystemError::NoSuchContract {
768 addr: ACCT.to_string(),
769 })
770 }
771 });
772 let wrapper = QuerierWrapper::<Empty>::new(&querier);
773
774 let err = wrapper.query_wasm_contract_info("unknown").unwrap_err();
775 assert!(matches!(
776 err,
777 StdError::GenericErr {
778 msg,
779 ..
780 } if msg == "Querier system error: No such contract: foobar"
781 ));
782 }
783
784 #[test]
785 fn querier_into_empty() {
786 #[derive(Clone, Serialize, Deserialize)]
787 struct MyQuery;
788 impl CustomQuery for MyQuery {}
789
790 let querier: MockQuerier<MyQuery> = MockQuerier::new(&[]);
791 let wrapper = QuerierWrapper::<MyQuery>::new(&querier);
792
793 let _: QuerierWrapper<Empty> = wrapper.into_empty();
794 }
795}