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::msg::Msg;
10use crate::{
11 chain::{
12 coin::Coin,
13 response::{ChainResponse, Code},
14 },
15 modules::auth::model::Address,
16};
17
18use super::error::CosmwasmError;
19
20#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
21pub struct StoreCodeRequest {
22 pub wasm_data: Vec<u8>,
23 pub instantiate_perms: Option<AccessConfig>,
24}
25
26impl StoreCodeRequest {
27 pub fn to_proto(self, signer_addr: Address) -> Result<StoreCodeProto, CosmwasmError> {
28 Ok(StoreCodeProto {
29 signer_addr,
30 wasm_data: self.wasm_data,
31 instantiate_perms: self.instantiate_perms,
32 })
33 }
34}
35
36#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
37pub struct StoreCodeProto {
38 pub signer_addr: Address,
39 pub wasm_data: Vec<u8>,
40 pub instantiate_perms: Option<AccessConfig>,
41}
42
43impl Msg for StoreCodeProto {
44 type Proto = MsgStoreCode;
45 type Err = CosmwasmError;
46}
47
48impl TryFrom<MsgStoreCode> for StoreCodeProto {
49 type Error = CosmwasmError;
50
51 fn try_from(msg: MsgStoreCode) -> Result<Self, Self::Error> {
52 Ok(Self {
53 signer_addr: msg.sender.parse()?,
54 wasm_data: msg.wasm_byte_code,
55 instantiate_perms: msg
56 .instantiate_permission
57 .map(TryFrom::try_from)
58 .transpose()?,
59 })
60 }
61}
62
63impl TryFrom<StoreCodeProto> for MsgStoreCode {
64 type Error = CosmwasmError;
65
66 fn try_from(req: StoreCodeProto) -> Result<Self, Self::Error> {
67 Ok(Self {
68 sender: req.signer_addr.into(),
69 wasm_byte_code: req.wasm_data,
70 instantiate_permission: req.instantiate_perms.map(Into::into),
71 })
72 }
73}
74
75#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
76pub struct StoreCodeResponse<T> {
77 pub code_id: u64,
78 pub res: T,
79}
80
81#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
94pub struct StoreCodeBatchResponse<T> {
95 pub code_ids: Vec<u64>,
96 pub res: T,
97}
98
99#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
112pub struct InstantiateRequest<S: Serialize> {
113 pub code_id: u64,
114 pub msg: S,
115 pub label: String,
116 pub admin: Option<Address>,
117 pub funds: Vec<Coin>,
118}
119
120impl<S: Serialize> InstantiateRequest<S> {
121 pub fn to_proto(self, signer_addr: Address) -> Result<InstantiateRequestProto, CosmwasmError> {
122 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
123
124 Ok(InstantiateRequestProto {
125 signer_addr,
126 code_id: self.code_id,
127 msg: payload,
128 label: self.label,
129 admin: self.admin,
130 funds: self.funds,
131 })
132 }
133}
134
135#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
136pub struct InstantiateRequestProto {
137 pub signer_addr: Address,
138 pub code_id: u64,
139 pub msg: Vec<u8>,
140 pub label: String,
141 pub admin: Option<Address>,
142 pub funds: Vec<Coin>,
143}
144
145impl Msg for InstantiateRequestProto {
146 type Proto = MsgInstantiateContract;
147 type Err = CosmwasmError;
148}
149
150impl TryFrom<MsgInstantiateContract> for InstantiateRequestProto {
151 type Error = CosmwasmError;
152
153 fn try_from(msg: MsgInstantiateContract) -> Result<Self, Self::Error> {
154 let admin = if msg.admin.is_empty() {
155 None
156 } else {
157 Some(msg.admin.parse()?)
158 };
159
160 Ok(Self {
161 signer_addr: msg.sender.parse()?,
162 code_id: msg.code_id,
163 msg: msg.msg,
164 label: msg.label,
165 admin,
166 funds: msg
167 .funds
168 .into_iter()
169 .map(TryInto::try_into)
170 .collect::<Result<Vec<_>, _>>()?,
171 })
172 }
173}
174
175impl TryFrom<InstantiateRequestProto> for MsgInstantiateContract {
176 type Error = CosmwasmError;
177
178 fn try_from(req: InstantiateRequestProto) -> Result<Self, Self::Error> {
179 Ok(Self {
180 sender: req.signer_addr.into(),
181 admin: req.admin.map(Into::into).unwrap_or_default(),
182 code_id: req.code_id,
183 label: req.label,
184 msg: req.msg,
185 funds: req.funds.into_iter().map(Into::into).collect(),
186 })
187 }
188}
189
190#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
191pub struct InstantiateResponse<T> {
192 pub address: Address,
193 pub res: T,
194}
195
196#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
209pub struct InstantiateBatchResponse<T> {
210 pub addresses: Vec<Address>,
211 pub res: T,
212}
213
214#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
227pub struct ExecRequest<S: Serialize> {
228 pub address: Address,
229 pub msg: S,
230 pub funds: Vec<Coin>,
231}
232
233impl<S: Serialize> ExecRequest<S> {
234 pub fn to_proto(self, signer_addr: Address) -> Result<ExecRequestProto, CosmwasmError> {
235 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
236
237 Ok(ExecRequestProto {
238 signer_addr,
239 contract_addr: self.address,
240 msg: payload,
241 funds: self.funds,
242 })
243 }
244}
245
246#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
247pub struct ExecRequestProto {
248 pub signer_addr: Address,
249 pub contract_addr: Address,
250 pub msg: Vec<u8>,
251 pub funds: Vec<Coin>,
252}
253
254impl Msg for ExecRequestProto {
255 type Proto = MsgExecuteContract;
256 type Err = CosmwasmError;
257}
258
259impl TryFrom<MsgExecuteContract> for ExecRequestProto {
260 type Error = CosmwasmError;
261
262 fn try_from(msg: MsgExecuteContract) -> Result<Self, Self::Error> {
263 Ok(Self {
264 signer_addr: msg.sender.parse()?,
265 contract_addr: msg.contract.parse()?,
266 msg: msg.msg,
267 funds: msg
268 .funds
269 .into_iter()
270 .map(TryInto::try_into)
271 .collect::<Result<Vec<_>, _>>()?,
272 })
273 }
274}
275
276impl TryFrom<ExecRequestProto> for MsgExecuteContract {
277 type Error = CosmwasmError;
278
279 fn try_from(req: ExecRequestProto) -> Result<Self, Self::Error> {
280 Ok(Self {
281 sender: req.signer_addr.into(),
282 contract: req.contract_addr.into(),
283 msg: req.msg,
284 funds: req.funds.into_iter().map(Into::into).collect(),
285 })
286 }
287}
288
289#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
324pub struct MigrateRequest<S: Serialize> {
325 pub address: Address,
326 pub new_code_id: u64,
327 pub msg: S,
328}
329
330impl<S: Serialize> MigrateRequest<S> {
331 pub fn to_proto(self, signer_addr: Address) -> Result<MigrateRequestProto, CosmwasmError> {
332 let payload = serde_json::to_vec(&self.msg).map_err(CosmwasmError::json)?;
333
334 Ok(MigrateRequestProto {
335 signer_addr,
336 contract_addr: self.address,
337 new_code_id: self.new_code_id,
338 msg: payload,
339 })
340 }
341}
342
343#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
344pub struct MigrateRequestProto {
345 pub signer_addr: Address,
346 pub contract_addr: Address,
347 pub new_code_id: u64,
348 pub msg: Vec<u8>,
349}
350
351impl Msg for MigrateRequestProto {
352 type Proto = MsgMigrateContract;
353 type Err = CosmwasmError;
354}
355
356impl TryFrom<MsgMigrateContract> for MigrateRequestProto {
357 type Error = CosmwasmError;
358
359 fn try_from(msg: MsgMigrateContract) -> Result<Self, Self::Error> {
360 Ok(Self {
361 signer_addr: msg.sender.parse()?,
362 contract_addr: msg.contract.parse()?,
363 new_code_id: msg.code_id,
364 msg: msg.msg,
365 })
366 }
367}
368
369impl TryFrom<MigrateRequestProto> for MsgMigrateContract {
370 type Error = CosmwasmError;
371
372 fn try_from(req: MigrateRequestProto) -> Result<Self, Self::Error> {
373 Ok(Self {
374 sender: req.signer_addr.into(),
375 contract: req.contract_addr.into(),
376 code_id: req.new_code_id,
377 msg: req.msg,
378 })
379 }
380}
381
382impl From<QuerySmartContractStateResponse> for ChainResponse {
400 fn from(res: QuerySmartContractStateResponse) -> ChainResponse {
401 ChainResponse {
402 code: Code::Ok,
403 data: Some(res.data),
404 ..Default::default()
405 }
406 }
407}
408
409#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
410pub struct AccessConfig {
411 pub permission: AccessType,
412 pub addresses: Vec<Address>,
413}
414
415impl From<AccessConfig> for cosmrs::cosmwasm::AccessConfig {
416 fn from(config: AccessConfig) -> Self {
417 Self {
418 permission: config.permission.into(),
419 addresses: config.addresses.into_iter().map(Into::into).collect(),
420 }
421 }
422}
423
424impl From<cosmrs::cosmwasm::AccessConfig> for AccessConfig {
425 fn from(config: cosmrs::cosmwasm::AccessConfig) -> Self {
426 Self {
427 permission: config.permission.into(),
428 addresses: config.addresses.into_iter().map(Into::into).collect(),
429 }
430 }
431}
432
433impl From<AccessConfig> for ProtoAccessConfig {
434 fn from(config: AccessConfig) -> Self {
435 Self {
436 permission: config.permission as i32,
437 address: "".to_string(),
438 addresses: config.addresses.into_iter().map(Into::into).collect(),
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 addresses: config
450 .addresses
451 .into_iter()
452 .map(|s| s.parse())
453 .collect::<Result<Vec<_>, _>>()?,
454 })
455 }
456}
457
458#[derive(
459 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq, Hash, PartialOrd, Ord,
460)]
461#[repr(i32)]
462pub enum AccessType {
463 Unspecified = 0,
465 Nobody = 1,
467 OnlyAddress = 2,
469 Everybody = 3,
471 AnyOfAddresses = 4,
473}
474
475impl AsRef<str> for AccessType {
476 fn as_ref(&self) -> &str {
477 match self {
478 AccessType::Unspecified => "ACCESS_TYPE_UNSPECIFIED",
479 AccessType::Nobody => "ACCESS_TYPE_NOBODY",
480 AccessType::OnlyAddress => "ACCESS_TYPE_ONLY_ADDRESS",
481 AccessType::Everybody => "ACCESS_TYPE_EVERYBODY",
482 AccessType::AnyOfAddresses => "ACCESS_TYPE_ANY_OF_ADDRESSES",
483 }
484 }
485}
486
487impl TryFrom<i32> for AccessType {
488 type Error = CosmwasmError;
489
490 fn try_from(v: i32) -> Result<Self, Self::Error> {
491 match v {
492 x if x == AccessType::Unspecified as i32 => Ok(AccessType::Unspecified),
493 x if x == AccessType::Nobody as i32 => Ok(AccessType::Nobody),
494 x if x == AccessType::OnlyAddress as i32 => Ok(AccessType::OnlyAddress),
495 x if x == AccessType::Everybody as i32 => Ok(AccessType::Everybody),
496 _ => Err(CosmwasmError::AccessType { i: v }),
497 }
498 }
499}
500
501impl From<AccessType> for ProtoAccessType {
502 fn from(perm: AccessType) -> Self {
503 match perm {
504 AccessType::Unspecified => ProtoAccessType::Unspecified,
505 AccessType::Nobody => ProtoAccessType::Nobody,
506 AccessType::OnlyAddress => ProtoAccessType::OnlyAddress,
507 AccessType::Everybody => ProtoAccessType::Everybody,
508 AccessType::AnyOfAddresses => ProtoAccessType::AnyOfAddresses,
509 }
510 }
511}
512
513impl From<ProtoAccessType> for AccessType {
514 fn from(perm: ProtoAccessType) -> Self {
515 match perm {
516 ProtoAccessType::Unspecified => AccessType::Unspecified,
517 ProtoAccessType::Nobody => AccessType::Nobody,
518 ProtoAccessType::OnlyAddress => AccessType::OnlyAddress,
519 ProtoAccessType::Everybody => AccessType::Everybody,
520 ProtoAccessType::AnyOfAddresses => AccessType::AnyOfAddresses,
521 }
522 }
523}