cw_orch_daemon/queriers/
bank.rs1use crate::{cosmos_modules, error::DaemonError, senders::query::QuerySender, DaemonBase};
2use cosmrs::proto::cosmos::base::query::v1beta1::PageRequest;
3use cosmwasm_std::{Addr, Coin, StdError};
4use cw_orch_core::environment::{BankQuerier, Querier, QuerierGetter};
5use tokio::runtime::Handle;
6use tonic::transport::Channel;
7
8pub struct Bank {
11 pub channel: Channel,
12 pub rt_handle: Option<Handle>,
13}
14
15impl Bank {
16 pub fn new<Sender: QuerySender>(daemon: &DaemonBase<Sender>) -> Self {
17 Self {
18 channel: daemon.channel(),
19 rt_handle: Some(daemon.rt_handle.clone()),
20 }
21 }
22 pub fn new_async(channel: Channel) -> Self {
23 Self {
24 channel,
25 rt_handle: None,
26 }
27 }
28}
29
30impl Querier for Bank {
31 type Error = DaemonError;
32}
33
34impl<Sender: QuerySender> QuerierGetter<Bank> for DaemonBase<Sender> {
35 fn querier(&self) -> Bank {
36 Bank::new(self)
37 }
38}
39
40impl Bank {
41 pub async fn _balance(
44 &self,
45 address: &Addr,
46 denom: Option<String>,
47 ) -> Result<Vec<Coin>, DaemonError> {
48 use cosmos_modules::bank::query_client::QueryClient;
49 match denom {
50 Some(denom) => {
51 let mut client: QueryClient<Channel> = QueryClient::new(self.channel.clone());
52 let request = cosmos_modules::bank::QueryBalanceRequest {
53 address: address.to_string(),
54 denom,
55 };
56 let resp = client.balance(request).await?.into_inner();
57 let coin = resp.balance.unwrap();
58 Ok(vec![cosmrs_to_cosmwasm_coin(coin)?])
59 }
60 None => {
61 let mut client: QueryClient<Channel> = QueryClient::new(self.channel.clone());
62 let request = cosmos_modules::bank::QueryAllBalancesRequest {
63 address: address.to_string(),
64 ..Default::default()
65 };
66 let resp = client.all_balances(request).await?.into_inner();
67 Ok(cosmrs_to_cosmwasm_coins(resp.balances)?)
68 }
69 }
70 }
71
72 pub async fn _spendable_balances(&self, address: &Addr) -> Result<Vec<Coin>, DaemonError> {
74 let spendable_balances: cosmos_modules::bank::QuerySpendableBalancesResponse = cosmos_query!(
75 self,
76 bank,
77 spendable_balances,
78 QuerySpendableBalancesRequest {
79 address: address.to_string(),
80 pagination: None,
81 }
82 );
83 Ok(cosmrs_to_cosmwasm_coins(spendable_balances.balances)?)
84 }
85
86 pub async fn _total_supply(&self) -> Result<Vec<Coin>, DaemonError> {
88 let total_supply: cosmos_modules::bank::QueryTotalSupplyResponse = cosmos_query!(
89 self,
90 bank,
91 total_supply,
92 QueryTotalSupplyRequest { pagination: None }
93 );
94 Ok(cosmrs_to_cosmwasm_coins(total_supply.supply)?)
95 }
96
97 pub async fn _supply_of(&self, denom: impl Into<String>) -> Result<Coin, DaemonError> {
99 let supply_of: cosmos_modules::bank::QuerySupplyOfResponse = cosmos_query!(
100 self,
101 bank,
102 supply_of,
103 QuerySupplyOfRequest {
104 denom: denom.into()
105 }
106 );
107 Ok(cosmrs_to_cosmwasm_coin(supply_of.amount.unwrap())?)
108 }
109
110 pub async fn _params(&self) -> Result<cosmos_modules::bank::Params, DaemonError> {
112 let params: cosmos_modules::bank::QueryParamsResponse =
113 cosmos_query!(self, bank, params, QueryParamsRequest {});
114 Ok(params.params.unwrap())
115 }
116
117 pub async fn _denom_metadata(
119 &self,
120 denom: impl Into<String>,
121 ) -> Result<cosmos_modules::bank::Metadata, DaemonError> {
122 let denom_metadata: cosmos_modules::bank::QueryDenomMetadataResponse = cosmos_query!(
123 self,
124 bank,
125 denom_metadata,
126 QueryDenomMetadataRequest {
127 denom: denom.into()
128 }
129 );
130 Ok(denom_metadata.metadata.unwrap())
131 }
132
133 pub async fn _denoms_metadata(
137 &self,
138 pagination: Option<PageRequest>,
139 ) -> Result<Vec<cosmos_modules::bank::Metadata>, DaemonError> {
140 let denoms_metadata: cosmos_modules::bank::QueryDenomsMetadataResponse = cosmos_query!(
141 self,
142 bank,
143 denoms_metadata,
144 QueryDenomsMetadataRequest {
145 pagination: pagination
146 }
147 );
148 Ok(denoms_metadata.metadatas)
149 }
150}
151
152pub fn cosmrs_to_cosmwasm_coin(
153 c: cosmrs::proto::cosmos::base::v1beta1::Coin,
154) -> Result<Coin, StdError> {
155 Ok(Coin {
156 amount: c.amount.parse()?,
157 denom: c.denom,
158 })
159}
160
161pub fn cosmrs_to_cosmwasm_coins(
162 c: Vec<cosmrs::proto::cosmos::base::v1beta1::Coin>,
163) -> Result<Vec<Coin>, StdError> {
164 c.into_iter().map(cosmrs_to_cosmwasm_coin).collect()
165}
166impl BankQuerier for Bank {
167 fn balance(
168 &self,
169 address: &Addr,
170 denom: Option<String>,
171 ) -> Result<Vec<cosmwasm_std::Coin>, Self::Error> {
172 self.rt_handle
173 .as_ref()
174 .ok_or(DaemonError::QuerierNeedRuntime)?
175 .block_on(self._balance(address, denom))
176 }
177
178 fn total_supply(&self) -> Result<Vec<cosmwasm_std::Coin>, Self::Error> {
179 self.rt_handle
180 .as_ref()
181 .ok_or(DaemonError::QuerierNeedRuntime)?
182 .block_on(self._total_supply())
183 }
184
185 fn supply_of(&self, denom: impl Into<String>) -> Result<cosmwasm_std::Coin, Self::Error> {
186 self.rt_handle
187 .as_ref()
188 .ok_or(DaemonError::QuerierNeedRuntime)?
189 .block_on(self._supply_of(denom))
190 }
191}