cosm_tome_wasm_deploy_fork/modules/cosmwasm/
api.rs

1use serde::Serialize;
2
3use crate::chain::request::TxOptions;
4use crate::clients::client::CosmTome;
5use cosmrs::proto::cosmwasm::wasm::v1::{
6    QuerySmartContractStateRequest, QuerySmartContractStateResponse,
7};
8
9use crate::modules::auth::model::Address;
10use crate::{clients::client::CosmosClient, signing_key::key::SigningKey};
11
12use super::model::{
13    ExecRequest, ExecResponse, InstantiateBatchResponse, InstantiateRequest, MigrateRequest,
14    MigrateResponse, QueryResponse, StoreCodeBatchResponse, StoreCodeRequest,
15};
16use super::{
17    error::CosmwasmError,
18    model::{InstantiateResponse, StoreCodeResponse},
19};
20
21impl<T: CosmosClient> CosmTome<T> {
22    pub async fn wasm_store(
23        &self,
24        req: StoreCodeRequest,
25        key: &SigningKey,
26        tx_options: &TxOptions,
27    ) -> Result<StoreCodeResponse, CosmwasmError> {
28        let mut res = self.wasm_store_batch(vec![req], key, tx_options).await?;
29
30        Ok(StoreCodeResponse {
31            code_id: res.code_ids.remove(0),
32            res: res.res,
33        })
34    }
35
36    pub async fn wasm_store_batch<I>(
37        &self,
38        reqs: I,
39        key: &SigningKey,
40        tx_options: &TxOptions,
41    ) -> Result<StoreCodeBatchResponse, CosmwasmError>
42    where
43        I: IntoIterator<Item = StoreCodeRequest>,
44    {
45        let sender_addr = key.to_addr(&self.cfg.prefix)?;
46
47        let protos = reqs
48            .into_iter()
49            .map(|r| r.to_proto(sender_addr.clone()))
50            .collect::<Result<Vec<_>, _>>()?;
51
52        let msgs = protos
53            .into_iter()
54            .map(TryInto::try_into)
55            .collect::<Result<Vec<_>, _>>()?;
56
57        let tx_raw = self.tx_sign(msgs, key, tx_options).await?;
58
59        let res = self.tx_broadcast_block(&tx_raw).await?;
60
61        let code_ids = res
62            .find_event_tags("store_code".to_string(), "code_id".to_string())
63            .into_iter()
64            .map(|x| x.value.parse::<u64>())
65            .collect::<Result<Vec<_>, _>>()
66            .map_err(|_| CosmwasmError::MissingEvent)?;
67
68        Ok(StoreCodeBatchResponse { code_ids, res })
69    }
70
71    pub async fn wasm_instantiate<S>(
72        &self,
73        req: InstantiateRequest<S>,
74        key: &SigningKey,
75        tx_options: &TxOptions,
76    ) -> Result<InstantiateResponse, CosmwasmError>
77    where
78        S: Serialize,
79    {
80        let mut res = self
81            .wasm_instantiate_batch(vec![req], key, tx_options)
82            .await?;
83
84        Ok(InstantiateResponse {
85            address: res.addresses.remove(0),
86            res: res.res,
87        })
88    }
89
90    pub async fn wasm_instantiate_batch<S, I>(
91        &self,
92        reqs: I,
93        key: &SigningKey,
94        tx_options: &TxOptions,
95    ) -> Result<InstantiateBatchResponse, CosmwasmError>
96    where
97        S: Serialize,
98        I: IntoIterator<Item = InstantiateRequest<S>>,
99    {
100        let sender_addr = key.to_addr(&self.cfg.prefix)?;
101
102        let protos = reqs
103            .into_iter()
104            .map(|r| r.to_proto(sender_addr.clone()))
105            .collect::<Result<Vec<_>, _>>()?;
106
107        let msgs = protos
108            .into_iter()
109            .map(TryInto::try_into)
110            .collect::<Result<Vec<_>, _>>()?;
111
112        let tx_raw = self.tx_sign(msgs, key, tx_options).await?;
113
114        let res = self.tx_broadcast_block(&tx_raw).await?;
115
116        let events =
117            res.find_event_tags("instantiate".to_string(), "_contract_address".to_string());
118
119        if events.is_empty() {
120            return Err(CosmwasmError::MissingEvent);
121        }
122
123        let addrs = events
124            .into_iter()
125            .map(|e| e.value.parse())
126            .collect::<Result<Vec<_>, _>>()?;
127
128        Ok(InstantiateBatchResponse {
129            addresses: addrs,
130            res,
131        })
132    }
133
134    pub async fn wasm_execute<S>(
135        &self,
136        req: ExecRequest<S>,
137        key: &SigningKey,
138        tx_options: &TxOptions,
139    ) -> Result<ExecResponse, CosmwasmError>
140    where
141        S: Serialize,
142    {
143        self.wasm_execute_batch(vec![req], key, tx_options).await
144    }
145
146    pub async fn wasm_execute_batch<S, I>(
147        &self,
148        reqs: I,
149        key: &SigningKey,
150        tx_options: &TxOptions,
151    ) -> Result<ExecResponse, CosmwasmError>
152    where
153        S: Serialize,
154        I: IntoIterator<Item = ExecRequest<S>>,
155    {
156        let sender_addr = key.to_addr(&self.cfg.prefix)?;
157
158        let protos = reqs
159            .into_iter()
160            .map(|r| r.to_proto(sender_addr.clone()))
161            .collect::<Result<Vec<_>, _>>()?;
162
163        let msgs = protos
164            .into_iter()
165            .map(TryInto::try_into)
166            .collect::<Result<Vec<_>, _>>()?;
167
168        let tx_raw = self.tx_sign(msgs, key, tx_options).await?;
169
170        let res = self.tx_broadcast_block(&tx_raw).await?;
171
172        Ok(ExecResponse { res })
173    }
174
175    pub async fn wasm_query<S: Serialize>(
176        &self,
177        address: Address,
178        msg: &S,
179    ) -> Result<QueryResponse, CosmwasmError> {
180        let payload = serde_json::to_vec(msg).map_err(CosmwasmError::json)?;
181
182        let req = QuerySmartContractStateRequest {
183            address: address.into(),
184            query_data: payload,
185        };
186
187        let res = self
188            .client
189            .query::<_, QuerySmartContractStateResponse>(
190                req,
191                "/cosmwasm.wasm.v1.Query/SmartContractState",
192            )
193            .await?;
194
195        Ok(QueryResponse { res: res.into() })
196    }
197
198    pub async fn wasm_migrate<S>(
199        &self,
200        req: MigrateRequest<S>,
201        key: &SigningKey,
202        tx_options: &TxOptions,
203    ) -> Result<MigrateResponse, CosmwasmError>
204    where
205        S: Serialize,
206    {
207        self.wasm_migrate_batch(vec![req], key, tx_options).await
208    }
209
210    pub async fn wasm_migrate_batch<S, I>(
211        &self,
212        reqs: I,
213        key: &SigningKey,
214        tx_options: &TxOptions,
215    ) -> Result<MigrateResponse, CosmwasmError>
216    where
217        S: Serialize,
218        I: IntoIterator<Item = MigrateRequest<S>>,
219    {
220        let sender_addr = key.to_addr(&self.cfg.prefix)?;
221
222        let protos = reqs
223            .into_iter()
224            .map(|r| r.to_proto(sender_addr.clone()))
225            .collect::<Result<Vec<_>, _>>()?;
226
227        let msgs = protos
228            .into_iter()
229            .map(TryInto::try_into)
230            .collect::<Result<Vec<_>, _>>()?;
231
232        let tx_raw = self.tx_sign(msgs, key, tx_options).await?;
233
234        let res = self.tx_broadcast_block(&tx_raw).await?;
235
236        Ok(MigrateResponse { res })
237    }
238
239    // TODO: Finish
240}