use cosmrs::proto::cosmwasm::wasm::v1::{
QuerySmartContractStateRequest, QuerySmartContractStateResponse,
};
use prost::Message;
use serde::{Deserialize, Serialize};
use tendermint_rpc::Client;
use super::error::CosmosClientError;
use super::{CosmosClient, QueryResponse};
impl CosmosClient {
pub async fn query_contract<QUERY, RESPONSE>(
&self,
contract_address: String,
query: &QUERY,
height: Option<u64>,
) -> Result<QueryContractResponse<RESPONSE>, CosmosClientError>
where
QUERY: Serialize,
for<'de> RESPONSE: Deserialize<'de>,
{
let query_data = serde_json::to_vec(&query).map_err(CosmosClientError::SerdeJson)?;
let res: QueryResponse<QuerySmartContractStateResponse> = self
.client
.abci_query(
Some("/cosmwasm.wasm.v1.Query/SmartContractState".to_string()),
QuerySmartContractStateRequest {
address: contract_address,
query_data,
}
.encode_to_vec(),
height
.map(TryInto::try_into)
.transpose()
.map_err(CosmosClientError::Cosmrs)?,
false,
)
.await?
.into();
if res.value.data.is_empty() {
return Err(CosmosClientError::NoDataFromContractQuery(res.log));
}
Ok(QueryContractResponse {
data: serde_json::from_slice(&res.value.data)?,
height: res.height.value(),
})
}
pub async fn query_bank<QUERY, RESPONSE>(
&self,
query: &QUERY,
height: Option<u64>,
) -> Result<RESPONSE, CosmosClientError>
where
QUERY: Message,
RESPONSE: Message + Default,
{
let res: QueryResponse<RESPONSE> = self
.client
.abci_query(
Some("cosmos.bank.v1beta1.Query/DenomMetadata".to_string()),
query.encode_to_vec(),
height
.map(TryInto::try_into)
.transpose()
.map_err(CosmosClientError::Cosmrs)?,
false,
)
.await?
.into();
Ok(res.value)
}
}
pub struct QueryContractResponse<RESPONSE> {
pub data: RESPONSE,
pub height: u64,
}