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