1use crate::client::wasm_types::{
2 WasmCodeResult, WasmContractInfoResult, WasmParameterResult, WasmQueryRawResult,
3};
4use crate::{Message, PrivateKey, Terra};
5use secp256k1::{Secp256k1, Signing};
6use std::path::Path;
7
8use crate::client::tx_types::TXResultSync;
9use crate::core_types::Coin;
10use crate::errors::TerraRustAPIError;
11use crate::messages::wasm::{MsgInstantiateContract, MsgMigrateContract, MsgStoreCode};
12use serde::Deserialize;
13
14pub struct Wasm<'a> {
15 terra: &'a Terra,
16}
17
18impl Wasm<'_> {
19 pub fn create(terra: &'_ Terra) -> Wasm<'_> {
20 Wasm { terra }
21 }
22 pub async fn codes(&self, code_id: u64) -> Result<WasmCodeResult, TerraRustAPIError> {
23 let code = self
24 .terra
25 .send_cmd::<WasmCodeResult>(&format!("/wasm/codes/{}", code_id), None)
26 .await?;
27 Ok(code)
28 }
29 pub async fn info(
30 &self,
31 contract_address: &str,
32 ) -> Result<WasmContractInfoResult, TerraRustAPIError> {
33 let code = self
34 .terra
35 .send_cmd::<WasmContractInfoResult>(
36 &format!("/wasm/contracts/{}", contract_address),
37 None,
38 )
39 .await?;
40 Ok(code)
41 }
42 pub async fn parameters(&self) -> Result<WasmParameterResult, TerraRustAPIError> {
43 let code = self
44 .terra
45 .send_cmd::<WasmParameterResult>("/wasm/parameters", None)
46 .await?;
47 Ok(code)
48 }
49 pub async fn query<T: for<'de> Deserialize<'de>>(
50 &self,
51 contract_address: &str,
52 json_query: &str,
53 ) -> Result<T, TerraRustAPIError> {
54 let code = self
55 .terra
56 .send_cmd::<T>(
57 &format!("/wasm/contracts/{}/store?", contract_address),
58 Some(&format!("query_msg={}", json_query)),
59 )
60 .await?;
61 Ok(code)
62 }
63 pub async fn query_raw(
64 &self,
65 contract_address: &str,
66 key: &str,
67 sub_key: &Option<String>,
68 ) -> Result<(String, String), TerraRustAPIError> {
69 let json_query = match sub_key {
70 Some(sub_key_str) => format!("key={}&subkey={}", key, &sub_key_str),
71 None => format!("key={}", key),
72 };
73
74 let code = self
75 .terra
76 .send_cmd::<WasmQueryRawResult>(
77 &format!("/wasm/contracts/{}/store/raw?", contract_address),
78 Some(&json_query),
79 )
80 .await?;
81 let key_vec = subtle_encoding::base64::decode(code.result.key.as_bytes())?;
82 let key = String::from_utf8(key_vec)?;
83 eprintln!("{}", code.result.key);
84 let value_vec = subtle_encoding::base64::decode(code.result.value)?;
85 let value = String::from_utf8(value_vec)?;
86
87 Ok((key, value))
88 }
89 pub async fn store<C: Signing + Signing>(
91 &self,
92 secp: &Secp256k1<C>,
93 from: &PrivateKey,
94 wasm: &str,
95 memo: Option<String>,
96 ) -> Result<TXResultSync, TerraRustAPIError> {
97 let from_public_key = from.public_key(secp);
98
99 let wasm_path = Path::new(wasm);
100
101 let store_message = MsgStoreCode::create_from_file(&from_public_key.account()?, wasm_path)?;
102 let messages: Vec<Message> = vec![store_message];
103
104 let resp = self
105 .terra
106 .submit_transaction_sync(secp, from, messages, memo)
107 .await;
108 resp
109 }
110 #[allow(clippy::too_many_arguments)]
112 pub async fn instantiate<C: Signing + Signing>(
113 &self,
114 secp: &Secp256k1<C>,
115 from: &PrivateKey,
116 code_id: u64,
117 json: String,
118 coins: Vec<Coin>,
119 admin: Option<String>,
120 memo: Option<String>,
121 ) -> Result<TXResultSync, TerraRustAPIError> {
122 let from_public_key = from.public_key(secp);
123 let init_message = MsgInstantiateContract::create_from_json(
124 &from_public_key.account()?,
125 admin,
126 code_id,
127 &json,
128 coins,
129 )?;
130 let messages: Vec<Message> = vec![init_message];
131
132 let resp = self
133 .terra
134 .submit_transaction_sync(secp, from, messages, memo)
135 .await;
136
137 resp
138 }
139
140 pub async fn migrate<C: Signing + Signing>(
142 &self,
143 secp: &Secp256k1<C>,
144 from: &PrivateKey,
145 contract: &str,
146 new_code_id: u64,
147 migrate: Option<String>,
148 memo: Option<String>,
149 ) -> Result<TXResultSync, TerraRustAPIError> {
150 let from_public_key = from.public_key(secp);
151
152 let migrate_message = if let Some(migrate_string) = migrate {
153 MsgMigrateContract::create_from_json(
154 &from_public_key.account()?,
155 contract,
156 new_code_id,
157 &migrate_string,
158 )?
159 } else {
160 MsgMigrateContract::create_from_json(
161 &from_public_key.account()?,
162 contract,
163 new_code_id,
164 "{}",
165 )?
166 };
167
168 let messages: Vec<Message> = vec![migrate_message];
169
170 let resp = self
171 .terra
172 .submit_transaction_sync(secp, from, messages, memo)
173 .await;
174 resp
175 }
176}