1use crate::core_types::{Coin, MsgInternal};
2use crate::terra_u64_format;
3use std::path::Path;
4
5use crate::errors::TerraRustAPIError;
6use crate::messages::Message;
7use serde::Serialize;
8
9#[derive(Serialize, Debug)]
10pub struct MsgExecuteContract {
12 pub coins: Vec<Coin>,
13 pub contract: String,
14 pub execute_msg: serde_json::Value,
15 pub sender: String,
16}
17
18impl MsgInternal for MsgExecuteContract {}
19impl MsgExecuteContract {
20 pub fn create_from_value(
22 sender: &str,
23 contract: &str,
24 execute_msg: &serde_json::Value,
25 coins: &[Coin],
26 ) -> Result<Message, TerraRustAPIError> {
27 let internal = MsgExecuteContract {
28 sender: sender.into(),
29 contract: contract.into(),
30 execute_msg: execute_msg.clone(),
31 coins: coins.to_vec(),
32 };
33 Ok(Message {
34 s_type: "wasm/MsgExecuteContract".into(),
35 value: serde_json::to_value(internal)?,
36 })
37 }
38 pub fn create_from_json(
40 sender: &str,
41 contract: &str,
42 execute_msg_json: &str,
43 coins: &[Coin],
44 ) -> Result<Message, TerraRustAPIError> {
45 let exec_b64: serde_json::Value = serde_json::from_str(execute_msg_json)?;
46 MsgExecuteContract::create_from_value(sender, contract, &exec_b64, coins)
47 }
48}
49
50#[derive(Serialize, Debug)]
51pub struct MsgStoreCode {
53 pub sender: String,
54 pub wasm_byte_code: String,
55}
56
57impl MsgInternal for MsgStoreCode {}
58impl MsgStoreCode {
59 pub fn create_from_b64(
61 sender: &str,
62 wasm_byte_code: &str,
63 ) -> Result<Message, TerraRustAPIError> {
64 let internal = MsgStoreCode {
65 sender: sender.into(),
66 wasm_byte_code: wasm_byte_code.into(),
67 };
68 Ok(Message {
69 s_type: "wasm/MsgStoreCode".into(),
70 value: serde_json::to_value(internal)?,
71 })
72 }
73 pub fn create_from_file(sender: &str, file_name: &Path) -> Result<Message, TerraRustAPIError> {
75 let file_contents = std::fs::read(file_name)?;
76 let exec_b64 = base64::encode(file_contents);
77 MsgStoreCode::create_from_b64(sender, &exec_b64)
78 }
79}
80
81#[derive(Serialize, Debug)]
82pub struct MsgInstantiateContract {
84 pub admin: Option<String>,
85 #[serde(with = "terra_u64_format")]
86 pub code_id: u64,
87 pub sender: String,
88 pub init_coins: Vec<Coin>,
89 pub init_msg: serde_json::Value,
90}
91
92impl MsgInternal for MsgInstantiateContract {}
93impl MsgInstantiateContract {
94 pub fn create_from_json(
119 sender: &str,
120 admin: Option<String>,
121 code_id: u64,
122 init_msg: &str,
123 init_coins: Vec<Coin>,
124 ) -> Result<Message, TerraRustAPIError> {
125 let contents: serde_json::Value = serde_json::from_str(init_msg)?;
128 let internal = MsgInstantiateContract {
131 admin, code_id,
133 sender: sender.into(),
134 init_coins,
135 init_msg: contents,
136 };
137 Ok(Message {
138 s_type: "wasm/MsgInstantiateContract".into(),
139 value: serde_json::to_value(internal)?,
140 })
141 }
142 pub fn create_from_file(
145 sender: &str,
146 admin: Option<String>,
147 code_id: u64,
148 init_file: &Path,
149 init_coins: Vec<Coin>,
150 ) -> Result<Message, TerraRustAPIError> {
151 let contents = std::fs::read_to_string(init_file)?;
152 let new_contents = Self::replace_parameters(sender, admin.clone(), code_id, &contents);
153 Self::create_from_json(sender, admin, code_id, &new_contents, init_coins)
154 }
155 pub fn replace_parameters(
157 sender: &str,
158 admin: Option<String>,
159 code_id: u64,
160 instantiate_str: &str,
161 ) -> String {
162 let part_1 = instantiate_str
163 .replace("##SENDER##", sender)
164 .replace("##CODE_ID##", &format!("{}", code_id));
165 match admin {
166 Some(admin_str) => part_1.replace("##ADMIN##", &admin_str),
167 None => part_1.replace("##ADMIN##", ""),
168 }
169 }
170}
171
172#[derive(Serialize, Debug)]
173pub struct MsgMigrateContract {
175 pub admin: String,
176 pub contract: String,
177 #[serde(with = "terra_u64_format")]
178 pub new_code_id: u64,
179 pub migrate_msg: serde_json::Value,
180}
181
182impl MsgInternal for MsgMigrateContract {}
183impl MsgMigrateContract {
184 pub fn create_from_json(
186 admin: &str,
187 contract: &str,
188 new_code_id: u64,
189 migrate_msg: &str,
190 ) -> Result<Message, TerraRustAPIError> {
191 let contents: serde_json::Value = serde_json::from_str(migrate_msg)?;
192
193 let internal = MsgMigrateContract {
194 admin: String::from(admin),
195 contract: String::from(contract),
196 new_code_id,
197 migrate_msg: contents,
198 };
199 Ok(Message {
200 s_type: "wasm/MsgMigrateContract".into(),
201 value: serde_json::to_value(internal)?,
202 })
203 }
204 pub fn create_from_file(
207 admin: &str,
208 contract: &str,
209 new_code_id: u64,
210 migrate_file: &Path,
211 ) -> Result<Message, TerraRustAPIError> {
212 let contents = std::fs::read_to_string(migrate_file)?;
213 let new_contents = Self::replace_parameters(admin, contract, new_code_id, &contents);
214
215 Self::create_from_json(admin, contract, new_code_id, &new_contents)
216 }
217 pub fn replace_parameters(
219 admin: &str,
220 contract: &str,
221 new_code_id: u64,
222 migrate_str: &str,
223 ) -> String {
224 migrate_str
225 .replace("##ADMIN##", admin)
226 .replace("##CONTRACT##", contract)
227 .replace("##NEW_CODE_ID##", &format!("{}", new_code_id))
228 }
229}
230
231#[cfg(test)]
232mod tst {
233 use super::*;
234 #[test]
261 pub fn test_file_conversion() -> anyhow::Result<()> {
262 let token_file = Path::new("./resources/terraswap_pair.wasm");
263 let output = Path::new("./resources/terraswap_pair.output");
264 let out_json = std::fs::read_to_string(output)?;
265 let msg = MsgStoreCode::create_from_file(
266 "terra1vr0e7kylhu9am44v0s3gwkccmz7k3naxysrwew",
267 token_file,
268 )?;
269
270 let js = serde_json::to_string(&msg)?;
271 log::debug!("Test file conversion: {} - {}", out_json.len(), js.len());
272 assert_eq!(out_json.trim(), js);
273 Ok(())
274 }
275}