1use core::any::Any;
2use core::marker::PhantomData;
3use core::ops::Deref;
4use serde::{de::DeserializeOwned, Serialize};
5
6use crate::coin::Coin;
7#[cfg(feature = "iterator")]
8use crate::iterator::{Order, Record};
9use crate::prelude::*;
10#[cfg(feature = "cosmwasm_1_2")]
11use crate::query::CodeInfoResponse;
12#[cfg(feature = "cosmwasm_1_1")]
13use crate::query::SupplyResponse;
14#[cfg(feature = "staking")]
15use crate::query::{
16 AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation,
17 DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse,
18};
19#[cfg(feature = "cosmwasm_1_3")]
20use crate::query::{
21 AllDenomMetadataResponse, DelegatorWithdrawAddressResponse, DenomMetadataResponse,
22 DistributionQuery,
23};
24use crate::query::{BalanceResponse, BankQuery, CustomQuery, QueryRequest, WasmQuery};
25use crate::results::{ContractResult, Empty, SystemResult};
26use crate::ContractInfoResponse;
27use crate::{from_json, to_json_binary, to_json_vec, Binary};
28use crate::{Addr, CanonicalAddr};
29#[cfg(feature = "cosmwasm_1_3")]
30use crate::{DenomMetadata, PageRequest};
31use crate::{RecoverPubkeyError, StdError, StdResult, VerificationError};
32
33#[derive(Clone, Copy, Debug)]
34#[non_exhaustive]
35pub enum HashFunction {
36 Sha256 = 0,
37}
38
39#[cfg(not(target_arch = "wasm32"))]
40impl From<HashFunction> for cosmwasm_crypto::HashFunction {
41 fn from(value: HashFunction) -> Self {
42 match value {
43 HashFunction::Sha256 => cosmwasm_crypto::HashFunction::Sha256,
44 }
45 }
46}
47
48pub trait Storage {
51 fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
57
58 #[cfg(feature = "iterator")]
63 #[allow(unused_variables)]
64 fn range<'a>(
65 &'a self,
66 start: Option<&[u8]>,
67 end: Option<&[u8]>,
68 order: Order,
69 ) -> Box<dyn Iterator<Item = Record> + 'a> {
70 unimplemented!("This storage does not support ranging. Make sure to override the `range` method in your `Storage` implementation.")
73 }
74
75 #[cfg(feature = "iterator")]
83 fn range_keys<'a>(
84 &'a self,
85 start: Option<&[u8]>,
86 end: Option<&[u8]>,
87 order: Order,
88 ) -> Box<dyn Iterator<Item = Vec<u8>> + 'a> {
89 Box::new(self.range(start, end, order).map(|(k, _v)| k))
90 }
91
92 #[cfg(feature = "iterator")]
100 fn range_values<'a>(
101 &'a self,
102 start: Option<&[u8]>,
103 end: Option<&[u8]>,
104 order: Order,
105 ) -> Box<dyn Iterator<Item = Vec<u8>> + 'a> {
106 Box::new(self.range(start, end, order).map(|(_k, v)| v))
107 }
108
109 fn set(&mut self, key: &[u8], value: &[u8]);
110
111 fn remove(&mut self, key: &[u8]);
116}
117
118pub trait Api: Any {
133 fn addr_validate(&self, human: &str) -> StdResult<Addr>;
157
158 fn addr_canonicalize(&self, human: &str) -> StdResult<CanonicalAddr>;
165
166 fn addr_humanize(&self, canonical: &CanonicalAddr) -> StdResult<Addr>;
171
172 fn secp256k1_verify(
173 &self,
174 message_hash: &[u8],
175 signature: &[u8],
176 public_key: &[u8],
177 ) -> Result<bool, VerificationError>;
178
179 fn secp256k1_recover_pubkey(
180 &self,
181 message_hash: &[u8],
182 signature: &[u8],
183 recovery_param: u8,
184 ) -> Result<Vec<u8>, RecoverPubkeyError>;
185
186 #[allow(unused_variables)]
190 fn bls12_381_aggregate_g1(&self, g1s: &[u8]) -> Result<[u8; 48], VerificationError> {
191 unimplemented!()
196 }
197
198 #[allow(unused_variables)]
202 fn bls12_381_aggregate_g2(&self, g2s: &[u8]) -> Result<[u8; 96], VerificationError> {
203 unimplemented!()
208 }
209
210 #[allow(unused_variables)]
237 fn bls12_381_pairing_equality(
238 &self,
239 ps: &[u8],
240 qs: &[u8],
241 r: &[u8],
242 s: &[u8],
243 ) -> Result<bool, VerificationError> {
244 unimplemented!()
249 }
250
251 #[allow(unused_variables)]
255 fn bls12_381_hash_to_g1(
256 &self,
257 hash_function: HashFunction,
258 msg: &[u8],
259 dst: &[u8],
260 ) -> Result<[u8; 48], VerificationError> {
261 unimplemented!()
266 }
267
268 #[allow(unused_variables)]
272 fn bls12_381_hash_to_g2(
273 &self,
274 hash_function: HashFunction,
275 msg: &[u8],
276 dst: &[u8],
277 ) -> Result<[u8; 96], VerificationError> {
278 unimplemented!()
283 }
284
285 #[allow(unused_variables)]
286 fn secp256r1_verify(
287 &self,
288 message_hash: &[u8],
289 signature: &[u8],
290 public_key: &[u8],
291 ) -> Result<bool, VerificationError> {
292 unimplemented!()
297 }
298
299 #[allow(unused_variables)]
300 fn secp256r1_recover_pubkey(
301 &self,
302 message_hash: &[u8],
303 signature: &[u8],
304 recovery_param: u8,
305 ) -> Result<Vec<u8>, RecoverPubkeyError> {
306 unimplemented!()
311 }
312
313 fn ed25519_verify(
314 &self,
315 message: &[u8],
316 signature: &[u8],
317 public_key: &[u8],
318 ) -> Result<bool, VerificationError>;
319
320 fn ed25519_batch_verify(
321 &self,
322 messages: &[&[u8]],
323 signatures: &[&[u8]],
324 public_keys: &[&[u8]],
325 ) -> Result<bool, VerificationError>;
326
327 fn debug(&self, message: &str);
330}
331
332pub type QuerierResult = SystemResult<ContractResult<Binary>>;
334
335pub trait Querier {
336 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult;
342}
343
344#[derive(Clone)]
345pub struct QuerierWrapper<'a, C: CustomQuery = Empty> {
346 querier: &'a dyn Querier,
347 custom_query_type: PhantomData<C>,
348}
349
350impl<C: CustomQuery> Copy for QuerierWrapper<'_, C> {}
355
356impl<'a, C: CustomQuery> Deref for QuerierWrapper<'a, C> {
359 type Target = dyn Querier + 'a;
360
361 fn deref(&self) -> &Self::Target {
362 self.querier
363 }
364}
365
366impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
367 pub fn new(querier: &'a dyn Querier) -> Self {
368 QuerierWrapper {
369 querier,
370 custom_query_type: PhantomData,
371 }
372 }
373
374 pub fn into_empty(self) -> QuerierWrapper<'a, Empty> {
377 QuerierWrapper {
378 querier: self.querier,
379 custom_query_type: PhantomData,
380 }
381 }
382
383 pub fn query<U: DeserializeOwned>(&self, request: &QueryRequest<C>) -> StdResult<U> {
389 self.query_raw(request).and_then(|raw| from_json(raw))
390 }
391
392 fn query_raw(&self, request: &QueryRequest<C>) -> StdResult<Binary> {
396 let raw = to_json_vec(request).map_err(|serialize_err| {
397 StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}"))
398 })?;
399 match self.raw_query(&raw) {
400 SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
401 "Querier system error: {system_err}"
402 ))),
403 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
404 format!("Querier contract error: {contract_err}"),
405 )),
406 SystemResult::Ok(ContractResult::Ok(value)) => Ok(value),
407 }
408 }
409
410 #[cfg(feature = "cosmwasm_1_1")]
411 pub fn query_supply(&self, denom: impl Into<String>) -> StdResult<Coin> {
412 let request = BankQuery::Supply {
413 denom: denom.into(),
414 }
415 .into();
416 let res: SupplyResponse = self.query(&request)?;
417 Ok(res.amount)
418 }
419
420 pub fn query_balance(
421 &self,
422 address: impl Into<String>,
423 denom: impl Into<String>,
424 ) -> StdResult<Coin> {
425 let request = BankQuery::Balance {
426 address: address.into(),
427 denom: denom.into(),
428 }
429 .into();
430 let res: BalanceResponse = 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, Uint256};
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, Uint256::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
712 #[test]
713 fn contract_info() {
714 const ACCT: &str = "foobar";
715 fn mock_resp() -> ContractInfoResponse {
716 ContractInfoResponse {
717 code_id: 0,
718 creator: Addr::unchecked("creator"),
719 admin: None,
720 pinned: false,
721 ibc_port: None,
722 ibc2_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 ibc2_port: None,
755 }
756 }
757
758 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
759 querier.update_wasm(|q| -> QuerierResult {
760 if q == &(WasmQuery::ContractInfo {
761 contract_addr: ACCT.to_string(),
762 }) {
763 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
764 } else {
765 SystemResult::Err(crate::SystemError::NoSuchContract {
766 addr: ACCT.to_string(),
767 })
768 }
769 });
770 let wrapper = QuerierWrapper::<Empty>::new(&querier);
771
772 let err = wrapper.query_wasm_contract_info("unknown").unwrap_err();
773 assert!(matches!(
774 err,
775 StdError::GenericErr {
776 msg,
777 ..
778 } if msg == "Querier system error: No such contract: foobar"
779 ));
780 }
781
782 #[test]
783 fn querier_into_empty() {
784 #[derive(Clone, Serialize, Deserialize)]
785 struct MyQuery;
786 impl CustomQuery for MyQuery {}
787
788 let querier: MockQuerier<MyQuery> = MockQuerier::new(&[]);
789 let wrapper = QuerierWrapper::<MyQuery>::new(&querier);
790
791 let _: QuerierWrapper<Empty> = wrapper.into_empty();
792 }
793}