layer_climb_core/querier/
contract.rs1use crate::{contract_helpers::contract_msg_to_vec, prelude::*};
2use serde::{de::DeserializeOwned, Serialize};
3use tracing::instrument;
4
5impl QueryClient {
6 #[instrument]
7 pub async fn contract_smart<
8 D: DeserializeOwned + Send + std::fmt::Debug + Sync,
9 S: Serialize + std::fmt::Debug,
10 >(
11 &self,
12 address: &Address,
13 msg: &S,
14 ) -> Result<D> {
15 self.run_with_middleware(ContractSmartReq {
16 address: address.clone(),
17 msg: contract_msg_to_vec(&msg)?,
18 _phantom: std::marker::PhantomData,
19 })
20 .await
21 }
22 #[instrument]
23 pub async fn contract_smart_raw<S: Serialize + std::fmt::Debug>(
24 &self,
25 address: &Address,
26 msg: &S,
27 ) -> Result<Vec<u8>> {
28 self.run_with_middleware(ContractSmartRawReq {
29 address: address.clone(),
30 msg: contract_msg_to_vec(&msg)?,
31 })
32 .await
33 }
34
35 #[instrument]
36 pub async fn contract_code_info(
37 &self,
38 code_id: u64,
39 ) -> Result<layer_climb_proto::wasm::CodeInfoResponse> {
40 self.run_with_middleware(ContractCodeInfoReq { code_id })
41 .await
42 }
43
44 #[instrument]
45 pub async fn contract_info(
46 &self,
47 address: &Address,
48 ) -> Result<layer_climb_proto::wasm::QueryContractInfoResponse> {
49 self.run_with_middleware(ContractInfoReq {
50 address: address.clone(),
51 })
52 .await
53 }
54}
55
56#[derive(Debug)]
57struct ContractSmartReq<D> {
58 pub address: Address,
59 pub msg: Vec<u8>,
60 _phantom: std::marker::PhantomData<D>,
61}
62
63impl<D> Clone for ContractSmartReq<D> {
64 fn clone(&self) -> Self {
65 Self {
66 address: self.address.clone(),
67 msg: self.msg.clone(),
68 _phantom: std::marker::PhantomData,
69 }
70 }
71}
72
73impl<D: DeserializeOwned + Send + std::fmt::Debug + Sync> QueryRequest for ContractSmartReq<D> {
74 type QueryResponse = D;
75
76 async fn request(&self, client: QueryClient) -> Result<D> {
77 let res = ContractSmartRawReq {
78 address: self.address.clone(),
79 msg: self.msg.clone(),
80 }
81 .request(client)
82 .await?;
83
84 let res = cosmwasm_std::from_json(res)
85 .map_err(|e| anyhow::anyhow!("couldn't deserialize response {}", e))?;
86
87 Ok(res)
88 }
89}
90
91#[derive(Clone, Debug)]
92struct ContractSmartRawReq {
93 pub address: Address,
94 pub msg: Vec<u8>,
95}
96
97impl QueryRequest for ContractSmartRawReq {
98 type QueryResponse = Vec<u8>;
99
100 async fn request(&self, client: QueryClient) -> Result<Vec<u8>> {
101 let req = layer_climb_proto::wasm::QuerySmartContractStateRequest {
102 address: self.address.to_string(),
103 query_data: self.msg.clone(),
104 };
105
106 let res = match client.get_connection_mode() {
107 ConnectionMode::Grpc => {
108 let mut query_client = layer_climb_proto::wasm::query_client::QueryClient::new(
109 client.clone_grpc_channel()?,
110 );
111
112 query_client
113 .smart_contract_state(req)
114 .await
115 .map(|res| res.into_inner())?
116 }
117 ConnectionMode::Rpc => {
118 client
119 .rpc_client()?
120 .abci_protobuf_query("/cosmwasm.wasm.v1.Query/SmartContractState", req, None)
121 .await?
122 }
123 };
124
125 Ok(res.data)
126 }
127}
128
129#[derive(Clone, Debug)]
130struct ContractCodeInfoReq {
131 pub code_id: u64,
132}
133
134impl QueryRequest for ContractCodeInfoReq {
135 type QueryResponse = layer_climb_proto::wasm::CodeInfoResponse;
136
137 async fn request(
138 &self,
139 client: QueryClient,
140 ) -> Result<layer_climb_proto::wasm::CodeInfoResponse> {
141 let req = layer_climb_proto::wasm::QueryCodeRequest {
142 code_id: self.code_id,
143 };
144
145 let res = match client.get_connection_mode() {
146 ConnectionMode::Grpc => {
147 let mut query_client = layer_climb_proto::wasm::query_client::QueryClient::new(
148 client.clone_grpc_channel()?,
149 );
150
151 query_client.code(req).await.map(|res| res.into_inner())?
152 }
153 ConnectionMode::Rpc => {
154 client
155 .rpc_client()?
156 .abci_protobuf_query("/cosmwasm.wasm.v1.Query/Code", req, None)
157 .await?
158 }
159 };
160
161 res.code_info.context("no code info found")
162 }
163}
164
165#[derive(Clone, Debug)]
166pub struct ContractInfoReq {
167 pub address: Address,
168}
169
170impl QueryRequest for ContractInfoReq {
171 type QueryResponse = layer_climb_proto::wasm::QueryContractInfoResponse;
172
173 async fn request(
174 &self,
175 client: QueryClient,
176 ) -> Result<layer_climb_proto::wasm::QueryContractInfoResponse> {
177 let req = layer_climb_proto::wasm::QueryContractInfoRequest {
178 address: self.address.to_string(),
179 };
180
181 match client.get_connection_mode() {
182 ConnectionMode::Grpc => {
183 let mut query_client = layer_climb_proto::wasm::query_client::QueryClient::new(
184 client.clone_grpc_channel()?,
185 );
186
187 let resp = query_client
188 .contract_info(req)
189 .await
190 .map(|res| res.into_inner())?;
191
192 Ok(resp)
193 }
194 ConnectionMode::Rpc => {
195 let resp = client
196 .rpc_client()?
197 .abci_protobuf_query::<_, layer_climb_proto::wasm::QueryContractInfoResponse>(
198 "/cosmwasm.wasm.v1.Query/ContractInfo",
199 req,
200 None,
201 )
202 .await?;
203
204 Ok(resp)
205 }
206 }
207 }
208}