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, ValidatorMetadata,
18 ValidatorResponse,
19};
20#[cfg(feature = "cosmwasm_1_3")]
21use crate::query::{
22 AllDenomMetadataResponse, DelegatorWithdrawAddressResponse, DenomMetadataResponse,
23 DistributionQuery,
24};
25use crate::query::{BalanceResponse, BankQuery, CustomQuery, QueryRequest, WasmQuery};
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: Any {
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)]
191 fn bls12_381_aggregate_g1(&self, g1s: &[u8]) -> Result<[u8; 48], VerificationError> {
192 unimplemented!()
197 }
198
199 #[allow(unused_variables)]
203 fn bls12_381_aggregate_g2(&self, g2s: &[u8]) -> Result<[u8; 96], VerificationError> {
204 unimplemented!()
209 }
210
211 #[allow(unused_variables)]
238 fn bls12_381_pairing_equality(
239 &self,
240 ps: &[u8],
241 qs: &[u8],
242 r: &[u8],
243 s: &[u8],
244 ) -> Result<bool, VerificationError> {
245 unimplemented!()
250 }
251
252 #[allow(unused_variables)]
256 fn bls12_381_hash_to_g1(
257 &self,
258 hash_function: HashFunction,
259 msg: &[u8],
260 dst: &[u8],
261 ) -> Result<[u8; 48], VerificationError> {
262 unimplemented!()
267 }
268
269 #[allow(unused_variables)]
273 fn bls12_381_hash_to_g2(
274 &self,
275 hash_function: HashFunction,
276 msg: &[u8],
277 dst: &[u8],
278 ) -> Result<[u8; 96], VerificationError> {
279 unimplemented!()
284 }
285
286 #[allow(unused_variables)]
287 fn secp256r1_verify(
288 &self,
289 message_hash: &[u8],
290 signature: &[u8],
291 public_key: &[u8],
292 ) -> Result<bool, VerificationError> {
293 unimplemented!()
298 }
299
300 #[allow(unused_variables)]
301 fn secp256r1_recover_pubkey(
302 &self,
303 message_hash: &[u8],
304 signature: &[u8],
305 recovery_param: u8,
306 ) -> Result<Vec<u8>, RecoverPubkeyError> {
307 unimplemented!()
312 }
313
314 fn ed25519_verify(
315 &self,
316 message: &[u8],
317 signature: &[u8],
318 public_key: &[u8],
319 ) -> Result<bool, VerificationError>;
320
321 fn ed25519_batch_verify(
322 &self,
323 messages: &[&[u8]],
324 signatures: &[&[u8]],
325 public_keys: &[&[u8]],
326 ) -> Result<bool, VerificationError>;
327
328 fn debug(&self, message: &str);
331}
332
333pub type QuerierResult = SystemResult<ContractResult<Binary>>;
335
336pub trait Querier {
337 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult;
343}
344
345#[derive(Clone)]
346pub struct QuerierWrapper<'a, C: CustomQuery = Empty> {
347 querier: &'a dyn Querier,
348 custom_query_type: PhantomData<C>,
349}
350
351impl<C: CustomQuery> Copy for QuerierWrapper<'_, C> {}
356
357impl<'a, C: CustomQuery> Deref for QuerierWrapper<'a, C> {
360 type Target = dyn Querier + 'a;
361
362 fn deref(&self) -> &Self::Target {
363 self.querier
364 }
365}
366
367impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
368 pub fn new(querier: &'a dyn Querier) -> Self {
369 QuerierWrapper {
370 querier,
371 custom_query_type: PhantomData,
372 }
373 }
374
375 pub fn into_empty(self) -> QuerierWrapper<'a, Empty> {
378 QuerierWrapper {
379 querier: self.querier,
380 custom_query_type: PhantomData,
381 }
382 }
383
384 pub fn query<U: DeserializeOwned>(&self, request: &QueryRequest<C>) -> StdResult<U> {
390 self.query_raw(request).and_then(|raw| from_json(raw))
391 }
392
393 fn query_raw(&self, request: &QueryRequest<C>) -> StdResult<Binary> {
397 let raw = to_json_vec(request)?;
398 match self.raw_query(&raw) {
399 SystemResult::Err(system_err) => Err(StdError::msg(format_args!(
400 "Querier system error: {system_err}"
401 ))),
402 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::msg(
403 format_args!("Querier contract error: {contract_err}"),
404 )),
405 SystemResult::Ok(ContractResult::Ok(value)) => Ok(value),
406 }
407 }
408
409 #[cfg(feature = "cosmwasm_1_1")]
410 pub fn query_supply(&self, denom: impl Into<String>) -> StdResult<Coin> {
411 let request = BankQuery::Supply {
412 denom: denom.into(),
413 }
414 .into();
415 let res: SupplyResponse = self.query(&request)?;
416 Ok(res.amount)
417 }
418
419 pub fn query_balance(
420 &self,
421 address: impl Into<String>,
422 denom: impl Into<String>,
423 ) -> StdResult<Coin> {
424 let request = BankQuery::Balance {
425 address: address.into(),
426 denom: denom.into(),
427 }
428 .into();
429 let res: BalanceResponse = self.query(&request)?;
430 Ok(res.amount)
431 }
432
433 #[cfg(feature = "cosmwasm_1_3")]
434 pub fn query_delegator_withdraw_address(
435 &self,
436 delegator: impl Into<String>,
437 ) -> StdResult<Addr> {
438 let request = DistributionQuery::DelegatorWithdrawAddress {
439 delegator_address: delegator.into(),
440 }
441 .into();
442 let res: DelegatorWithdrawAddressResponse = self.query(&request)?;
443 Ok(res.withdraw_address)
444 }
445
446 #[cfg(feature = "cosmwasm_1_3")]
447 pub fn query_denom_metadata(&self, denom: impl Into<String>) -> StdResult<DenomMetadata> {
448 let request = BankQuery::DenomMetadata {
449 denom: denom.into(),
450 }
451 .into();
452 let res: DenomMetadataResponse = self.query(&request)?;
453 Ok(res.metadata)
454 }
455
456 #[cfg(feature = "cosmwasm_1_3")]
457 pub fn query_all_denom_metadata(
458 &self,
459 pagination: PageRequest,
460 ) -> StdResult<AllDenomMetadataResponse> {
461 let request = BankQuery::AllDenomMetadata {
462 pagination: Some(pagination),
463 }
464 .into();
465 self.query(&request)
466 }
467
468 #[cfg(feature = "cosmwasm_1_4")]
469 pub fn query_delegation_rewards(
470 &self,
471 delegator: impl Into<String>,
472 validator: impl Into<String>,
473 ) -> StdResult<Vec<crate::DecCoin>> {
474 use crate::DelegationRewardsResponse;
475
476 let request = DistributionQuery::DelegationRewards {
477 delegator_address: delegator.into(),
478 validator_address: validator.into(),
479 }
480 .into();
481 let DelegationRewardsResponse { rewards } = self.query(&request)?;
482
483 Ok(rewards)
484 }
485
486 #[cfg(feature = "cosmwasm_1_4")]
487 pub fn query_delegation_total_rewards(
488 &self,
489 delegator: impl Into<String>,
490 ) -> StdResult<crate::DelegationTotalRewardsResponse> {
491 let request = DistributionQuery::DelegationTotalRewards {
492 delegator_address: delegator.into(),
493 }
494 .into();
495 self.query(&request)
496 }
497
498 #[cfg(feature = "cosmwasm_1_4")]
499 pub fn query_delegator_validators(
500 &self,
501 delegator: impl Into<String>,
502 ) -> StdResult<Vec<String>> {
503 use crate::DelegatorValidatorsResponse;
504
505 let request = DistributionQuery::DelegatorValidators {
506 delegator_address: delegator.into(),
507 }
508 .into();
509 let res: DelegatorValidatorsResponse = self.query(&request)?;
510 Ok(res.validators)
511 }
512
513 #[cfg(feature = "cosmwasm_2_0")]
515 pub fn query_grpc(&self, path: String, data: Binary) -> StdResult<Binary> {
516 use crate::GrpcQuery;
517 self.query_raw(&QueryRequest::Grpc(GrpcQuery { path, data }))
518 }
519
520 pub fn query_wasm_smart<T: DeserializeOwned>(
523 &self,
524 contract_addr: impl Into<String>,
525 msg: &impl Serialize,
526 ) -> StdResult<T> {
527 let request = WasmQuery::Smart {
528 contract_addr: contract_addr.into(),
529 msg: to_json_binary(msg)?,
530 }
531 .into();
532 self.query(&request)
533 }
534
535 pub fn query_wasm_raw(
544 &self,
545 contract_addr: impl Into<String>,
546 key: impl Into<Binary>,
547 ) -> StdResult<Option<Vec<u8>>> {
548 let request: QueryRequest<Empty> = WasmQuery::Raw {
549 contract_addr: contract_addr.into(),
550 key: key.into(),
551 }
552 .into();
553 let raw = to_json_vec(&request)?;
556 match self.raw_query(&raw) {
557 SystemResult::Err(system_err) => Err(StdError::msg(format_args!(
558 "Querier system error: {system_err}"
559 ))),
560 SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::msg(
561 format_args!("Querier contract error: {contract_err}"),
562 )),
563 SystemResult::Ok(ContractResult::Ok(value)) => {
564 if value.is_empty() {
565 Ok(None)
566 } else {
567 Ok(Some(value.into()))
568 }
569 }
570 }
571 }
572
573 pub fn query_wasm_contract_info(
575 &self,
576 contract_addr: impl Into<String>,
577 ) -> StdResult<ContractInfoResponse> {
578 let request = WasmQuery::ContractInfo {
579 contract_addr: contract_addr.into(),
580 }
581 .into();
582 self.query(&request)
583 }
584
585 #[cfg(feature = "cosmwasm_1_2")]
587 pub fn query_wasm_code_info(&self, code_id: u64) -> StdResult<CodeInfoResponse> {
588 let request = WasmQuery::CodeInfo { code_id }.into();
589 self.query(&request)
590 }
591
592 #[cfg(feature = "staking")]
593 pub fn query_all_validators(&self) -> StdResult<Vec<ValidatorMetadata>> {
594 let request = StakingQuery::AllValidators {}.into();
595 let res: AllValidatorsResponse = self.query(&request)?;
596 Ok(res.validators)
597 }
598
599 #[cfg(feature = "staking")]
600 pub fn query_validator(&self, address: impl Into<String>) -> StdResult<Option<Validator>> {
601 let request = StakingQuery::Validator {
602 address: address.into(),
603 }
604 .into();
605 let res: ValidatorResponse = self.query(&request)?;
606 Ok(res.validator)
607 }
608
609 #[cfg(feature = "staking")]
610 pub fn query_bonded_denom(&self) -> StdResult<String> {
611 let request = StakingQuery::BondedDenom {}.into();
612 let res: BondedDenomResponse = self.query(&request)?;
613 Ok(res.denom)
614 }
615
616 #[cfg(feature = "staking")]
617 pub fn query_all_delegations(
618 &self,
619 delegator: impl Into<String>,
620 ) -> StdResult<Vec<Delegation>> {
621 let request = StakingQuery::AllDelegations {
622 delegator: delegator.into(),
623 }
624 .into();
625 let res: AllDelegationsResponse = self.query(&request)?;
626 Ok(res.delegations)
627 }
628
629 #[cfg(feature = "staking")]
630 pub fn query_delegation(
631 &self,
632 delegator: impl Into<String>,
633 validator: impl Into<String>,
634 ) -> StdResult<Option<FullDelegation>> {
635 let request = StakingQuery::Delegation {
636 delegator: delegator.into(),
637 validator: validator.into(),
638 }
639 .into();
640 let res: DelegationResponse = self.query(&request)?;
641 Ok(res.delegation)
642 }
643}
644
645#[cfg(test)]
646mod tests {
647 use serde::Deserialize;
648
649 use super::*;
650 use crate::testing::MockQuerier;
651 use crate::{coins, Uint256};
652
653 fn demo_helper(_querier: &dyn Querier) -> u64 {
655 2
656 }
657
658 #[test]
660 fn use_querier_wrapper_as_querier() {
661 let querier: MockQuerier<Empty> = MockQuerier::new(&[]);
662 let wrapper = QuerierWrapper::<Empty>::new(&querier);
663
664 let res = demo_helper(&*wrapper);
666 assert_eq!(2, res);
667
668 let res = demo_helper(wrapper.deref());
670 assert_eq!(2, res);
671 }
672
673 #[test]
674 fn auto_deref_raw_query() {
675 let acct = String::from("foobar");
676 let querier: MockQuerier<Empty> = MockQuerier::new(&[(&acct, &coins(5, "BTC"))]);
677 let wrapper = QuerierWrapper::<Empty>::new(&querier);
678 let query = QueryRequest::<Empty>::Bank(BankQuery::Balance {
679 address: acct,
680 denom: "BTC".to_string(),
681 });
682
683 let raw = wrapper
684 .raw_query(&to_json_vec(&query).unwrap())
685 .unwrap()
686 .unwrap();
687 let balance: BalanceResponse = from_json(raw).unwrap();
688 assert_eq!(balance.amount.amount, Uint256::new(5));
689 }
690
691 #[cfg(feature = "cosmwasm_1_1")]
692 #[test]
693 fn bank_query_helpers_work() {
694 use crate::coin;
695
696 let querier: MockQuerier<Empty> = MockQuerier::new(&[
697 ("foo", &[coin(123, "ELF"), coin(777, "FLY")]),
698 ("bar", &[coin(321, "ELF")]),
699 ]);
700 let wrapper = QuerierWrapper::<Empty>::new(&querier);
701
702 let supply = wrapper.query_supply("ELF").unwrap();
703 assert_eq!(supply, coin(444, "ELF"));
704
705 let balance = wrapper.query_balance("foo", "ELF").unwrap();
706 assert_eq!(balance, coin(123, "ELF"));
707 }
708
709 #[test]
710 fn contract_info() {
711 const ACCT: &str = "foobar";
712 fn mock_resp() -> ContractInfoResponse {
713 ContractInfoResponse {
714 code_id: 0,
715 creator: Addr::unchecked("creator"),
716 admin: None,
717 pinned: false,
718 ibc_port: None,
719 ibc2_port: None,
720 }
721 }
722
723 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
724 querier.update_wasm(|q| -> QuerierResult {
725 if q == &(WasmQuery::ContractInfo {
726 contract_addr: ACCT.to_string(),
727 }) {
728 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
729 } else {
730 SystemResult::Err(crate::SystemError::NoSuchContract {
731 addr: ACCT.to_string(),
732 })
733 }
734 });
735 let wrapper = QuerierWrapper::<Empty>::new(&querier);
736
737 let contract_info = wrapper.query_wasm_contract_info(ACCT).unwrap();
738 assert_eq!(contract_info, mock_resp());
739 }
740
741 #[test]
742 fn contract_info_err() {
743 const ACCT: &str = "foobar";
744 fn mock_resp() -> ContractInfoResponse {
745 ContractInfoResponse {
746 code_id: 0,
747 creator: Addr::unchecked("creator"),
748 admin: None,
749 pinned: false,
750 ibc_port: None,
751 ibc2_port: None,
752 }
753 }
754
755 let mut querier: MockQuerier<Empty> = MockQuerier::new(&[(ACCT, &coins(5, "BTC"))]);
756 querier.update_wasm(|q| -> QuerierResult {
757 if q == &(WasmQuery::ContractInfo {
758 contract_addr: ACCT.to_string(),
759 }) {
760 SystemResult::Ok(ContractResult::Ok(to_json_binary(&mock_resp()).unwrap()))
761 } else {
762 SystemResult::Err(crate::SystemError::NoSuchContract {
763 addr: ACCT.to_string(),
764 })
765 }
766 });
767 let wrapper = QuerierWrapper::<Empty>::new(&querier);
768
769 let err = wrapper.query_wasm_contract_info("unknown").unwrap_err();
770 assert!(err
771 .to_string()
772 .ends_with("Querier system error: No such contract: foobar"));
773 }
774
775 #[test]
776 fn querier_into_empty() {
777 #[derive(Clone, Serialize, Deserialize)]
778 struct MyQuery;
779 impl CustomQuery for MyQuery {}
780
781 let querier: MockQuerier<MyQuery> = MockQuerier::new(&[]);
782 let wrapper = QuerierWrapper::<MyQuery>::new(&querier);
783
784 let _: QuerierWrapper<Empty> = wrapper.into_empty();
785 }
786}