cosmos_client/client/
wasm.rs

1use crate::error::CosmosClient;
2use crate::error::CosmosClient::{ProstDecodeError, RpcError};
3use cosmos_sdk_proto::cosmos::base::query::v1beta1::PageRequest;
4use cosmos_sdk_proto::cosmwasm::wasm::v1::{
5    QueryAllContractStateRequest, QueryAllContractStateResponse, QueryCodeRequest,
6    QueryCodeResponse, QueryCodesRequest, QueryCodesResponse, QueryContractHistoryRequest,
7    QueryContractHistoryResponse, QueryContractInfoRequest, QueryContractInfoResponse,
8    QueryContractsByCodeRequest, QueryContractsByCodeResponse, QueryPinnedCodesRequest,
9    QueryPinnedCodesResponse, QueryRawContractStateRequest, QueryRawContractStateResponse,
10    QuerySmartContractStateRequest,
11};
12use prost::Message;
13use serde::de::DeserializeOwned;
14use serde::Serialize;
15use std::rc::Rc;
16use tendermint::abci::Code;
17use tendermint_rpc::{Client, HttpClient};
18
19pub struct Module {
20    rpc: Rc<HttpClient>,
21}
22
23impl Module {
24    pub fn new(rpc: Rc<HttpClient>) -> Self {
25        Module { rpc }
26    }
27
28    /// # Errors
29    ///
30    /// Will return `Err` if :
31    /// - a prost encode / decode fail
32    /// - the json-rpc return an error code
33    /// - if there is some network error
34    pub async fn contract_info(
35        &self,
36        address: &str,
37    ) -> Result<QueryContractInfoResponse, CosmosClient> {
38        let query = QueryContractInfoRequest {
39            address: address.to_string(),
40        };
41        let query = self
42            .rpc
43            .abci_query(
44                Some("/cosmwasm.wasm.v1.Query/ContractInfo".to_string()),
45                query.encode_to_vec(),
46                None,
47                false,
48            )
49            .await?;
50
51        if query.code != Code::Ok {
52            return Err(RpcError(query.log));
53        }
54        QueryContractInfoResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
55    }
56
57    /// # Errors
58    ///
59    /// Will return `Err` if :
60    /// - a prost encode / decode fail
61    /// - the json-rpc return an error code
62    /// - if there is some network error
63    pub async fn contract_history(
64        &self,
65        address: &str,
66        pagination: Option<PageRequest>,
67    ) -> Result<QueryContractHistoryResponse, CosmosClient> {
68        let query = QueryContractHistoryRequest {
69            address: address.to_string(),
70            pagination,
71        };
72        let query = self
73            .rpc
74            .abci_query(
75                Some("/cosmwasm.wasm.v1.Query/ContractHistory".to_string()),
76                query.encode_to_vec(),
77                None,
78                false,
79            )
80            .await?;
81
82        if query.code != Code::Ok {
83            return Err(RpcError(query.log));
84        }
85        QueryContractHistoryResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
86    }
87
88    /// # Errors
89    ///
90    /// Will return `Err` if :
91    /// - a prost encode / decode fail
92    /// - the json-rpc return an error code
93    /// - if there is some network error
94    pub async fn contracts_by_code(
95        &self,
96        code_id: u64,
97        pagination: Option<PageRequest>,
98    ) -> Result<QueryContractsByCodeResponse, CosmosClient> {
99        let query = QueryContractsByCodeRequest {
100            code_id,
101            pagination,
102        };
103        let query = self
104            .rpc
105            .abci_query(
106                Some("/cosmwasm.wasm.v1.Query/ContractsByCode".to_string()),
107                query.encode_to_vec(),
108                None,
109                false,
110            )
111            .await?;
112
113        if query.code != Code::Ok {
114            return Err(RpcError(query.log));
115        }
116        QueryContractsByCodeResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
117    }
118
119    /// # Errors
120    ///
121    /// Will return `Err` if :
122    /// - a prost encode / decode fail
123    /// - the json-rpc return an error code
124    /// - if there is some network error
125    pub async fn all_contract_state(
126        &self,
127        address: &str,
128        pagination: Option<PageRequest>,
129    ) -> Result<QueryAllContractStateResponse, CosmosClient> {
130        let query = QueryAllContractStateRequest {
131            address: address.to_string(),
132            pagination,
133        };
134        let query = self
135            .rpc
136            .abci_query(
137                Some("/cosmwasm.wasm.v1.Query/AllContractState".to_string()),
138                query.encode_to_vec(),
139                None,
140                false,
141            )
142            .await?;
143
144        if query.code != Code::Ok {
145            return Err(RpcError(query.log));
146        }
147        QueryAllContractStateResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
148    }
149
150    /// # Errors
151    ///
152    /// Will return `Err` if :
153    /// - a prost encode / decode fail
154    /// - the json-rpc return an error code
155    /// - if there is some network error
156    pub async fn raw_contract_state(
157        &self,
158        address: &str,
159        query_data: Vec<u8>,
160    ) -> Result<QueryRawContractStateResponse, CosmosClient> {
161        let query = QueryRawContractStateRequest {
162            address: address.to_string(),
163            query_data,
164        };
165        let query = self
166            .rpc
167            .abci_query(
168                Some("/cosmwasm.wasm.v1.Query/RawContractState".to_string()),
169                query.encode_to_vec(),
170                None,
171                false,
172            )
173            .await?;
174
175        if query.code != Code::Ok {
176            return Err(RpcError(query.log));
177        }
178        QueryRawContractStateResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
179    }
180
181    /// # Errors
182    ///
183    /// Will return `Err` if :
184    /// - a prost encode / decode fail
185    /// - the json-rpc return an error code
186    /// - if there is some network error
187    /// - a Json Serialize Deserialize error
188    pub async fn smart_contract_state<T: Serialize + Clone, U: DeserializeOwned>(
189        &self,
190        address: &str,
191        msg: T,
192    ) -> Result<U, CosmosClient> {
193        let query = QuerySmartContractStateRequest {
194            address: address.to_string(),
195            query_data: serde_json::to_vec(&msg)?,
196        };
197        let ret = self
198            .rpc
199            .abci_query(
200                Some("/cosmwasm.wasm.v1.Query/SmartContractState".to_string()),
201                query.encode_to_vec(),
202                None,
203                false,
204            )
205            .await?;
206
207        if ret.code != Code::Ok {
208            return Err(RpcError(ret.log));
209        }
210        let resp: QueryRawContractStateResponse =
211            QueryRawContractStateResponse::decode(ret.value.as_slice())?;
212
213        serde_json::from_slice::<U>(resp.data.as_slice()).map_err(CosmosClient::JsonError)
214    }
215
216    /// # Errors
217    ///
218    /// Will return `Err` if :
219    /// - a prost encode / decode fail
220    /// - the json-rpc return an error code
221    /// - if there is some network error
222    pub async fn code(&self, code_id: u64) -> Result<QueryCodeResponse, CosmosClient> {
223        let query = QueryCodeRequest { code_id };
224        let query = self
225            .rpc
226            .abci_query(
227                Some("/cosmwasm.wasm.v1.Query/Code".to_string()),
228                query.encode_to_vec(),
229                None,
230                false,
231            )
232            .await?;
233
234        if query.code != Code::Ok {
235            return Err(RpcError(query.log));
236        }
237        QueryCodeResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
238    }
239
240    /// # Errors
241    ///
242    /// Will return `Err` if :
243    /// - a prost encode / decode fail
244    /// - the json-rpc return an error code
245    /// - if there is some network error
246    pub async fn codes(
247        &self,
248        pagination: Option<PageRequest>,
249    ) -> Result<QueryCodesResponse, CosmosClient> {
250        let query = QueryCodesRequest { pagination };
251        let query = self
252            .rpc
253            .abci_query(
254                Some("/cosmwasm.wasm.v1.Query/Codes".to_string()),
255                query.encode_to_vec(),
256                None,
257                false,
258            )
259            .await?;
260
261        if query.code != Code::Ok {
262            return Err(RpcError(query.log));
263        }
264        QueryCodesResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
265    }
266
267    /// # Errors
268    ///
269    /// Will return `Err` if :
270    /// - a prost encode / decode fail
271    /// - the json-rpc return an error code
272    /// - if there is some network error
273    pub async fn pinned_codes(
274        &self,
275        pagination: Option<PageRequest>,
276    ) -> Result<QueryPinnedCodesResponse, CosmosClient> {
277        let query = QueryPinnedCodesRequest { pagination };
278        let query = self
279            .rpc
280            .abci_query(
281                Some("/cosmwasm.wasm.v1.Query/PinnedCodes".to_string()),
282                query.encode_to_vec(),
283                None,
284                false,
285            )
286            .await?;
287
288        if query.code != Code::Ok {
289            return Err(RpcError(query.log));
290        }
291        QueryPinnedCodesResponse::decode(query.value.as_slice()).map_err(ProstDecodeError)
292    }
293}