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 'a,
9 D: DeserializeOwned + Send + std::fmt::Debug + Sync,
10 S: Serialize + std::fmt::Debug,
11 >(
12 &self,
13 address: &Address,
14 msg: &S,
15 ) -> Result<D> {
16 self.run_with_middleware(ContractSmartReq {
17 address: address.clone(),
18 msg: contract_msg_to_vec(&msg)?,
19 _phantom: std::marker::PhantomData,
20 })
21 .await
22 }
23 #[instrument]
24 pub async fn contract_smart_raw<'a, S: Serialize + std::fmt::Debug>(
25 &self,
26 address: &Address,
27 msg: &S,
28 ) -> Result<Vec<u8>> {
29 self.run_with_middleware(ContractSmartRawReq {
30 address: address.clone(),
31 msg: contract_msg_to_vec(&msg)?,
32 })
33 .await
34 }
35
36 #[instrument]
37 pub async fn contract_code_info(
38 &self,
39 code_id: u64,
40 ) -> Result<layer_climb_proto::wasm::CodeInfoResponse> {
41 self.run_with_middleware(ContractCodeInfoReq { code_id })
42 .await
43 }
44
45 #[instrument]
46 pub async fn contract_info(
47 &self,
48 address: &Address,
49 ) -> Result<layer_climb_proto::wasm::QueryContractInfoResponse> {
50 self.run_with_middleware(ContractInfoReq {
51 address: address.clone(),
52 })
53 .await
54 }
55}
56
57#[derive(Debug)]
58struct ContractSmartReq<D> {
59 pub address: Address,
60 pub msg: Vec<u8>,
61 _phantom: std::marker::PhantomData<D>,
62}
63
64impl<D> Clone for ContractSmartReq<D> {
65 fn clone(&self) -> Self {
66 Self {
67 address: self.address.clone(),
68 msg: self.msg.clone(),
69 _phantom: std::marker::PhantomData,
70 }
71 }
72}
73
74impl<D: DeserializeOwned + Send + std::fmt::Debug + Sync> QueryRequest for ContractSmartReq<D> {
75 type QueryResponse = D;
76
77 async fn request(&self, client: QueryClient) -> Result<D> {
78 let res = ContractSmartRawReq {
79 address: self.address.clone(),
80 msg: self.msg.clone(),
81 }
82 .request(client)
83 .await?;
84
85 let res = cosmwasm_std::from_json(res).context("couldn't deserialize response")?;
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}