Skip to main content

casper_rust_wasm_sdk/sdk/contract/
install_deploy.rs

1#![allow(deprecated)]
2
3#[cfg(all(feature = "js", target_arch = "wasm32"))]
4use crate::deploy::deploy::PutDeployResult;
5use crate::types::deploy_params::{
6    deploy_str_params::{deploy_str_params_to_casper_client, DeployStrParams},
7    payment_str_params::{payment_str_params_to_casper_client, PaymentStrParams},
8    session_str_params::{session_str_params_to_casper_client, SessionStrParams},
9};
10use crate::{types::sdk_error::SdkError, SDK};
11use casper_client::{
12    cli::deploy::make_deploy, rpcs::results::PutDeployResult as _PutDeployResult, SuccessResponse,
13};
14#[cfg(all(feature = "js", target_arch = "wasm32"))]
15use wasm_bindgen::prelude::*;
16
17/// A set of functions for installing smart contracts on the blockchain.
18#[cfg(all(feature = "js", target_arch = "wasm32"))]
19#[cfg_attr(feature = "js", wasm_bindgen)]
20impl SDK {
21    /// Installs a smart contract with the specified parameters and returns the result.
22    ///
23    /// # Arguments
24    ///
25    /// * `deploy_params` - The deploy parameters.
26    /// * `session_params` - The session parameters.
27    /// * `payment_amount` - The payment amount as a string.
28    /// * `rpc_address` - An optional rpc address to send the request to.
29    ///
30    /// # Returns
31    ///
32    /// A `Result` containing either a `PutDeployResult` or a `JsError` in case of an error.
33    ///
34    /// # Errors
35    ///
36    /// Returns a `JsError` if there is an error during the installation.
37    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "install_deploy"))]
38    #[deprecated(note = "prefer 'install' with transaction")]
39    #[allow(deprecated)]
40    #[cfg(feature = "js")]
41    pub async fn install_deploy_js_alias(
42        &self,
43        deploy_params: DeployStrParams,
44        session_params: SessionStrParams,
45        payment_amount: &str,
46        rpc_address: Option<String>,
47    ) -> Result<PutDeployResult, JsError> {
48        let result = self
49            .install_deploy(deploy_params, session_params, payment_amount, rpc_address)
50            .await;
51        match result {
52            Ok(data) => Ok(data.result.into()),
53            Err(err) => {
54                let err = &format!("Error occurred with {err:?}");
55
56                Err(JsError::new(err))
57            }
58        }
59    }
60}
61
62/// A set of functions for installing smart contracts on the blockchain.
63/// Alias of sdk.deploy
64impl SDK {
65    /// Installs a smart contract with the specified parameters and returns the result.
66    ///
67    /// # Arguments
68    ///
69    /// * `deploy_params` - The deploy parameters.
70    /// * `session_params` - The session parameters.
71    /// * `payment_amount` - The payment amount as a string.
72    /// * `rpc_address` - An optional rpc address to send the request to.
73    ///
74    /// # Returns
75    ///
76    /// A `Result` containing either a `_PutDeployResult` or a `SdkError` in case of an error.
77    ///
78    /// # Errors
79    ///
80    /// Returns a `SdkError` if there is an error during the installation.
81    #[deprecated(note = "prefer 'install' with transaction")]
82    #[allow(deprecated)]
83    pub async fn install_deploy(
84        &self,
85        deploy_params: DeployStrParams,
86        session_params: SessionStrParams,
87        payment_amount: &str,
88        rpc_address: Option<String>,
89    ) -> Result<SuccessResponse<_PutDeployResult>, SdkError> {
90        //log("install!");
91        let payment_params = PaymentStrParams::default();
92        payment_params.set_payment_amount(payment_amount);
93
94        let deploy = make_deploy(
95            "",
96            deploy_str_params_to_casper_client(&deploy_params),
97            session_str_params_to_casper_client(&session_params),
98            payment_str_params_to_casper_client(&payment_params),
99            false,
100        );
101        if let Err(err) = deploy {
102            return Err(SdkError::from(err));
103        }
104        self.put_deploy(deploy.unwrap().into(), None, rpc_address)
105            .await
106    }
107}
108
109#[cfg(test)]
110#[allow(deprecated)]
111mod tests {
112    use super::*;
113    use crate::helpers::public_key_from_secret_key;
114    use sdk_tests::{
115        config::{ARGS_SIMPLE, HELLO_CONTRACT, PAYMENT_AMOUNT, TTL, WASM_PATH},
116        tests::helpers::{get_network_constants, get_user_secret_key, read_wasm_file},
117    };
118    use tokio;
119
120    #[tokio::test]
121    async fn test_install_deploy_with_none_values() {
122        // Arrange
123        let sdk = SDK::new(None, None, None);
124        let deploy_params = DeployStrParams::new("", "", None, None, None, None);
125        let session_params = SessionStrParams::default();
126
127        let error_message =
128            "Invalid argument 'is_session_transfer': requires --session-arg to be present";
129
130        // Act
131        let result = sdk
132            .install_deploy(deploy_params, session_params, "", None)
133            .await;
134
135        // Assert
136        assert!(result.is_err());
137        let err_string = result.err().unwrap().to_string();
138        assert!(err_string.contains(error_message));
139    }
140
141    #[tokio::test]
142    async fn test_install_deploy_with_valid_input() {
143        // Arrange
144        let sdk = SDK::new(None, None, None);
145        let (rpc_address, _, _, _, chain_name) = get_network_constants();
146        let secret_key = get_user_secret_key(None).unwrap();
147        let account = public_key_from_secret_key(&secret_key).unwrap();
148
149        let deploy_params =
150            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
151        let mut session_params = SessionStrParams::default();
152
153        let module_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
154            Ok(module_bytes) => module_bytes,
155            Err(err) => {
156                eprintln!("Error reading file: {err:?}");
157                return;
158            }
159        };
160        session_params.set_session_bytes(module_bytes.into());
161        let args_simple: Vec<String> = ARGS_SIMPLE.iter().map(|s| s.to_string()).collect();
162        session_params.set_session_args_simple(args_simple);
163
164        // Act
165        let result = sdk
166            .install_deploy(
167                deploy_params,
168                session_params,
169                PAYMENT_AMOUNT,
170                Some(rpc_address),
171            )
172            .await;
173
174        // Assert
175
176        assert!(result.is_ok());
177        let deploy_hash = result.unwrap().result.deploy_hash;
178        assert!(!deploy_hash.to_string().is_empty());
179    }
180
181    #[tokio::test]
182    async fn test_install_deploy_with_invalid_input() {
183        // Arrange
184        let sdk = SDK::new(None, None, None);
185        let (rpc_address, _, _, _, chain_name) = get_network_constants();
186        let secret_key = get_user_secret_key(None).unwrap();
187        let account = public_key_from_secret_key(&secret_key).unwrap();
188
189        let error_message =
190            "Missing a required arg - exactly one of the following must be provided";
191
192        let deploy_params = DeployStrParams::new(
193            &chain_name,
194            &account,
195            Some(secret_key.clone()),
196            None,
197            Some(TTL.to_string()),
198            None,
199        );
200        let mut session_params = SessionStrParams::default();
201
202        let module_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
203            Ok(module_bytes) => module_bytes,
204            Err(err) => {
205                eprintln!("Error reading file: {err:?}");
206                return;
207            }
208        };
209        session_params.set_session_bytes(module_bytes.into());
210        let args_simple: Vec<String> = ARGS_SIMPLE.iter().map(|s| s.to_string()).collect();
211        session_params.set_session_args_simple(args_simple);
212
213        // Act
214        let result = sdk
215            .install_deploy(
216                deploy_params,
217                session_params,
218                "", // This is not valid payment amount
219                Some(rpc_address),
220            )
221            .await;
222
223        // Assert
224        assert!(result.is_err());
225        let err_string = result.err().unwrap().to_string();
226        assert!(err_string.contains(error_message));
227    }
228
229    #[tokio::test]
230    async fn test_install_deploy_without_secret_key() {
231        // Arrange
232        let sdk = SDK::new(None, None, None);
233        let (rpc_address, _, _, _, chain_name) = get_network_constants();
234        let secret_key = get_user_secret_key(None).unwrap();
235        let account = public_key_from_secret_key(&secret_key).unwrap();
236
237        let error_message = "the deploy was invalid: invalid associated keys";
238
239        let deploy_params = DeployStrParams::new(
240            &chain_name,
241            &account,
242            None,
243            None,
244            Some(TTL.to_string()),
245            None,
246        );
247        let mut session_params = SessionStrParams::default();
248
249        let module_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
250            Ok(module_bytes) => module_bytes,
251            Err(err) => {
252                eprintln!("Error reading file: {err:?}");
253                return;
254            }
255        };
256        session_params.set_session_bytes(module_bytes.into());
257        let args_simple: Vec<String> = ARGS_SIMPLE.iter().map(|s| s.to_string()).collect();
258        session_params.set_session_args_simple(args_simple);
259
260        // Act
261        let result = sdk
262            .install_deploy(
263                deploy_params,
264                session_params,
265                PAYMENT_AMOUNT,
266                Some(rpc_address),
267            )
268            .await;
269
270        // Assert
271        assert!(result.is_err());
272        let err_string = result.err().unwrap().to_string();
273        assert!(err_string.contains(error_message));
274    }
275
276    #[tokio::test]
277    async fn test_install_deploy_with_error() {
278        // Arrange
279        let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
280        let (_, _, _, _, chain_name) = get_network_constants();
281        let secret_key = get_user_secret_key(None).unwrap();
282        let account = public_key_from_secret_key(&secret_key).unwrap();
283
284        let deploy_params = DeployStrParams::new(
285            &chain_name,
286            &account,
287            Some(secret_key.clone()),
288            None,
289            None,
290            None,
291        );
292
293        let error_message = "error sending request";
294
295        let mut session_params = SessionStrParams::default();
296
297        let module_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
298            Ok(module_bytes) => module_bytes,
299            Err(err) => {
300                eprintln!("Error reading file: {err:?}");
301                return;
302            }
303        };
304        session_params.set_session_bytes(module_bytes.into());
305        let args_simple: Vec<String> = ARGS_SIMPLE.iter().map(|s| s.to_string()).collect();
306        session_params.set_session_args_simple(args_simple);
307
308        // Act
309        let result = sdk
310            .install_deploy(deploy_params, session_params, PAYMENT_AMOUNT, None)
311            .await;
312
313        // Assert
314        assert!(result.is_err());
315        let err_string = result.err().unwrap().to_string();
316        assert!(err_string.contains(error_message));
317    }
318}