1use cosmrs::proto::cosmwasm::wasm::v1::MsgStoreCode;
2use cosmrs::proto::cosmwasm::wasm::v1::{
3 AccessConfig as ProtoAccessConfig, AccessType as ProtoAccessType, MsgExecuteContract,
4 MsgInstantiateContract, MsgMigrateContract, QuerySmartContractStateResponse,
5};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9use crate::chain::error::DeserializeError;
10use crate::chain::msg::Msg;
11use crate::{
12 chain::{
13 coin::Coin,
14 response::{ChainResponse, ChainTxResponse, Code},
15 },
16 modules::auth::model::Address,
17};
18
19use super::error::CosmwasmError;
20
21#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
22pub struct StoreCodeRequest {
23 pub wasm_data: Vec<u8>,
24 pub instantiate_perms: Option<AccessConfig>,
25}
26
27impl StoreCodeRequest {
28 pub fn to_proto(self, signer_addr: Address) -> Result<StoreCodeProto, CosmwasmError> {
29 Ok(StoreCodeProto {
30 signer_addr,
31 wasm_data: self.wasm_data,
32 instantiate_perms: self.instantiate_perms,
33 })
34 }
35}
36
37#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
38pub struct StoreCodeProto {
39 pub signer_addr: Address,
40 pub wasm_data: Vec<u8>,
41 pub instantiate_perms: Option<AccessConfig>,
42}
43
44impl Msg for StoreCodeProto {
45 type Proto = MsgStoreCode;
46 type Err = CosmwasmError;
47}
48
49impl TryFrom<MsgStoreCode> for StoreCodeProto {
50 type Error = CosmwasmError;
51
52 fn try_from(msg: MsgStoreCode) -> Result<Self, Self::Error> {
53 Ok(Self {
54 signer_addr: msg.sender.parse()?,
55 wasm_data: msg.wasm_byte_code,
56 instantiate_perms: msg
57 .instantiate_permission
58 .map(TryFrom::try_from)
59 .transpose()?,
60 })
61 }
62}
63
64impl TryFrom<StoreCodeProto> for MsgStoreCode {
65 type Error = CosmwasmError;
66
67 fn try_from(req: StoreCodeProto) -> Result<Self, Self::Error> {
68 Ok(Self {
69 sender: req.signer_addr.into(),
70 wasm_byte_code: req.wasm_data,
71 instantiate_permission: req.instantiate_perms.map(Into::into),
72 })
73 }
74}
75
76#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
77pub struct StoreCodeResponse {
78 pub code_id: u64,
79 pub res: ChainTxResponse,
80}
81
82impl StoreCodeResponse {
83 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
84 self.res.res.data()
85 }
86}
87
88impl AsRef<ChainTxResponse> for StoreCodeResponse {
89 fn as_ref(&self) -> &ChainTxResponse {
90 &self.res
91 }
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
95pub struct StoreCodeBatchResponse {
96 pub code_ids: Vec<u64>,
97 pub res: ChainTxResponse,
98}
99
100impl StoreCodeBatchResponse {
101 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
102 self.res.res.data()
103 }
104}
105
106impl AsRef<ChainTxResponse> for StoreCodeBatchResponse {
107 fn as_ref(&self) -> &ChainTxResponse {
108 &self.res
109 }
110}
111
112#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
113pub struct InstantiateRequest<S: Serialize> {
114 pub code_id: u64,
115 pub msg: S,
116 pub label: String,
117 pub admin: Option<Address>,
118 pub funds: Vec<Coin>,
119}
120
121impl<S: Serialize> InstantiateRequest<S> {
122 pub fn to_proto(self, signer_addr: Address) -> Result<InstantiateRequestProto, CosmwasmError> {
123 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
124
125 Ok(InstantiateRequestProto {
126 signer_addr,
127 code_id: self.code_id,
128 msg: payload,
129 label: self.label,
130 admin: self.admin,
131 funds: self.funds,
132 })
133 }
134}
135
136#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
137pub struct InstantiateRequestProto {
138 pub signer_addr: Address,
139 pub code_id: u64,
140 pub msg: Vec<u8>,
141 pub label: String,
142 pub admin: Option<Address>,
143 pub funds: Vec<Coin>,
144}
145
146impl Msg for InstantiateRequestProto {
147 type Proto = MsgInstantiateContract;
148 type Err = CosmwasmError;
149}
150
151impl TryFrom<MsgInstantiateContract> for InstantiateRequestProto {
152 type Error = CosmwasmError;
153
154 fn try_from(msg: MsgInstantiateContract) -> Result<Self, Self::Error> {
155 let admin = if msg.admin.is_empty() {
156 None
157 } else {
158 Some(msg.admin.parse()?)
159 };
160
161 Ok(Self {
162 signer_addr: msg.sender.parse()?,
163 code_id: msg.code_id,
164 msg: msg.msg,
165 label: msg.label,
166 admin,
167 funds: msg
168 .funds
169 .into_iter()
170 .map(TryInto::try_into)
171 .collect::<Result<Vec<_>, _>>()?,
172 })
173 }
174}
175
176impl TryFrom<InstantiateRequestProto> for MsgInstantiateContract {
177 type Error = CosmwasmError;
178
179 fn try_from(req: InstantiateRequestProto) -> Result<Self, Self::Error> {
180 Ok(Self {
181 sender: req.signer_addr.into(),
182 admin: req.admin.map(Into::into).unwrap_or_default(),
183 code_id: req.code_id,
184 label: req.label,
185 msg: req.msg,
186 funds: req.funds.into_iter().map(Into::into).collect(),
187 })
188 }
189}
190
191#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
192pub struct InstantiateResponse {
193 pub address: Address,
194 pub res: ChainTxResponse,
195}
196
197impl InstantiateResponse {
198 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
199 self.res.res.data()
200 }
201}
202
203impl AsRef<ChainTxResponse> for InstantiateResponse {
204 fn as_ref(&self) -> &ChainTxResponse {
205 &self.res
206 }
207}
208
209#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
210pub struct InstantiateBatchResponse {
211 pub addresses: Vec<Address>,
212 pub res: ChainTxResponse,
213}
214
215impl InstantiateBatchResponse {
216 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
217 self.res.res.data()
218 }
219}
220
221impl AsRef<ChainTxResponse> for InstantiateBatchResponse {
222 fn as_ref(&self) -> &ChainTxResponse {
223 &self.res
224 }
225}
226
227#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
228pub struct ExecRequest<S: Serialize> {
229 pub address: Address,
230 pub msg: S,
231 pub funds: Vec<Coin>,
232}
233
234impl<S: Serialize> ExecRequest<S> {
235 pub fn to_proto(self, signer_addr: Address) -> Result<ExecRequestProto, CosmwasmError> {
236 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
237
238 Ok(ExecRequestProto {
239 signer_addr,
240 contract_addr: self.address,
241 msg: payload,
242 funds: self.funds,
243 })
244 }
245}
246
247#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
248pub struct ExecRequestProto {
249 pub signer_addr: Address,
250 pub contract_addr: Address,
251 pub msg: Vec<u8>,
252 pub funds: Vec<Coin>,
253}
254
255impl Msg for ExecRequestProto {
256 type Proto = MsgExecuteContract;
257 type Err = CosmwasmError;
258}
259
260impl TryFrom<MsgExecuteContract> for ExecRequestProto {
261 type Error = CosmwasmError;
262
263 fn try_from(msg: MsgExecuteContract) -> Result<Self, Self::Error> {
264 Ok(Self {
265 signer_addr: msg.sender.parse()?,
266 contract_addr: msg.contract.parse()?,
267 msg: msg.msg,
268 funds: msg
269 .funds
270 .into_iter()
271 .map(TryInto::try_into)
272 .collect::<Result<Vec<_>, _>>()?,
273 })
274 }
275}
276
277impl TryFrom<ExecRequestProto> for MsgExecuteContract {
278 type Error = CosmwasmError;
279
280 fn try_from(req: ExecRequestProto) -> Result<Self, Self::Error> {
281 Ok(Self {
282 sender: req.signer_addr.into(),
283 contract: req.contract_addr.into(),
284 msg: req.msg,
285 funds: req.funds.into_iter().map(Into::into).collect(),
286 })
287 }
288}
289
290#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
291pub struct ExecResponse {
292 pub res: ChainTxResponse,
293}
294
295impl ExecResponse {
296 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
297 self.res.res.data()
298 }
299}
300
301impl AsRef<ChainTxResponse> for ExecResponse {
302 fn as_ref(&self) -> &ChainTxResponse {
303 &self.res
304 }
305}
306
307#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
308pub struct QueryResponse {
309 pub res: ChainResponse,
310}
311
312impl QueryResponse {
313 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
314 self.res.data()
315 }
316}
317
318impl AsRef<ChainResponse> for QueryResponse {
319 fn as_ref(&self) -> &ChainResponse {
320 &self.res
321 }
322}
323
324#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
325pub struct MigrateRequest<S: Serialize> {
326 pub address: Address,
327 pub new_code_id: u64,
328 pub msg: S,
329}
330
331impl<S: Serialize> MigrateRequest<S> {
332 pub fn to_proto(self, signer_addr: Address) -> Result<MigrateRequestProto, CosmwasmError> {
333 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
334
335 Ok(MigrateRequestProto {
336 signer_addr,
337 contract_addr: self.address,
338 new_code_id: self.new_code_id,
339 msg: payload,
340 })
341 }
342}
343
344#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
345pub struct MigrateRequestProto {
346 pub signer_addr: Address,
347 pub contract_addr: Address,
348 pub new_code_id: u64,
349 pub msg: Vec<u8>,
350}
351
352impl Msg for MigrateRequestProto {
353 type Proto = MsgMigrateContract;
354 type Err = CosmwasmError;
355}
356
357impl TryFrom<MsgMigrateContract> for MigrateRequestProto {
358 type Error = CosmwasmError;
359
360 fn try_from(msg: MsgMigrateContract) -> Result<Self, Self::Error> {
361 Ok(Self {
362 signer_addr: msg.sender.parse()?,
363 contract_addr: msg.contract.parse()?,
364 new_code_id: msg.code_id,
365 msg: msg.msg,
366 })
367 }
368}
369
370impl TryFrom<MigrateRequestProto> for MsgMigrateContract {
371 type Error = CosmwasmError;
372
373 fn try_from(req: MigrateRequestProto) -> Result<Self, Self::Error> {
374 Ok(Self {
375 sender: req.signer_addr.into(),
376 contract: req.contract_addr.into(),
377 code_id: req.new_code_id,
378 msg: req.msg,
379 })
380 }
381}
382
383#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
384pub struct MigrateResponse {
385 pub res: ChainTxResponse,
386}
387
388impl MigrateResponse {
389 pub fn data<'a, T: Deserialize<'a>>(&'a self) -> Result<T, DeserializeError> {
390 self.res.res.data()
391 }
392}
393
394impl AsRef<ChainTxResponse> for MigrateResponse {
395 fn as_ref(&self) -> &ChainTxResponse {
396 &self.res
397 }
398}
399
400impl From<QuerySmartContractStateResponse> for ChainResponse {
401 fn from(res: QuerySmartContractStateResponse) -> ChainResponse {
402 ChainResponse {
403 code: Code::Ok,
404 data: Some(res.data),
405 ..Default::default()
406 }
407 }
408}
409
410#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
411pub struct AccessConfig {
412 pub permission: AccessType,
413 pub account: Address,
414}
415
416impl From<AccessConfig> for cosmrs::cosmwasm::AccessConfig {
417 fn from(config: AccessConfig) -> Self {
418 Self {
419 permission: config.permission.into(),
420 address: config.account.into(),
421 }
422 }
423}
424
425impl From<cosmrs::cosmwasm::AccessConfig> for AccessConfig {
426 fn from(config: cosmrs::cosmwasm::AccessConfig) -> Self {
427 Self {
428 permission: config.permission.into(),
429 account: config.address.into(),
430 }
431 }
432}
433
434impl From<AccessConfig> for ProtoAccessConfig {
435 fn from(config: AccessConfig) -> Self {
436 Self {
437 permission: config.permission as i32,
438 address: config.account.into(),
439 }
440 }
441}
442
443impl TryFrom<ProtoAccessConfig> for AccessConfig {
444 type Error = CosmwasmError;
445
446 fn try_from(config: ProtoAccessConfig) -> Result<Self, Self::Error> {
447 Ok(Self {
448 permission: config.permission.try_into()?,
449 account: config.address.parse()?,
450 })
451 }
452}
453
454#[derive(
455 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq, Hash, PartialOrd, Ord,
456)]
457#[repr(i32)]
458pub enum AccessType {
459 Unspecified = 0,
461 Nobody = 1,
463 OnlyAddress = 2,
465 Everybody = 3,
467}
468
469impl AsRef<str> for AccessType {
470 fn as_ref(&self) -> &str {
471 match self {
472 AccessType::Unspecified => "ACCESS_TYPE_UNSPECIFIED",
473 AccessType::Nobody => "ACCESS_TYPE_NOBODY",
474 AccessType::OnlyAddress => "ACCESS_TYPE_ONLY_ADDRESS",
475 AccessType::Everybody => "ACCESS_TYPE_EVERYBODY",
476 }
477 }
478}
479
480impl TryFrom<i32> for AccessType {
481 type Error = CosmwasmError;
482
483 fn try_from(v: i32) -> Result<Self, Self::Error> {
484 match v {
485 x if x == AccessType::Unspecified as i32 => Ok(AccessType::Unspecified),
486 x if x == AccessType::Nobody as i32 => Ok(AccessType::Nobody),
487 x if x == AccessType::OnlyAddress as i32 => Ok(AccessType::OnlyAddress),
488 x if x == AccessType::Everybody as i32 => Ok(AccessType::Everybody),
489 _ => Err(CosmwasmError::AccessType { i: v }),
490 }
491 }
492}
493
494impl From<AccessType> for ProtoAccessType {
495 fn from(perm: AccessType) -> Self {
496 match perm {
497 AccessType::Unspecified => ProtoAccessType::Unspecified,
498 AccessType::Nobody => ProtoAccessType::Nobody,
499 AccessType::OnlyAddress => ProtoAccessType::OnlyAddress,
500 AccessType::Everybody => ProtoAccessType::Everybody,
501 }
502 }
503}
504
505impl From<ProtoAccessType> for AccessType {
506 fn from(perm: ProtoAccessType) -> Self {
507 match perm {
508 ProtoAccessType::Unspecified => AccessType::Unspecified,
509 ProtoAccessType::Nobody => AccessType::Nobody,
510 ProtoAccessType::OnlyAddress => AccessType::OnlyAddress,
511 ProtoAccessType::Everybody => AccessType::Everybody,
512 }
513 }
514}