casper_rust_wasm_sdk/sdk/contract/
install.rs

1#[cfg(target_arch = "wasm32")]
2use crate::transaction::transaction::PutTransactionResult;
3use crate::{
4    types::{
5        cl::bytes::Bytes,
6        sdk_error::SdkError,
7        transaction_params::{
8            transaction_builder_params::TransactionBuilderParams,
9            transaction_str_params::TransactionStrParams,
10        },
11    },
12    SDK,
13};
14use casper_client::{
15    rpcs::results::PutTransactionResult as _PutTransactionResult, SuccessResponse,
16};
17#[cfg(target_arch = "wasm32")]
18use wasm_bindgen::prelude::*;
19
20/// A set of functions for installing smart contracts on the blockchain.
21#[cfg(target_arch = "wasm32")]
22#[wasm_bindgen]
23impl SDK {
24    /// Installs a smart contract with the specified parameters and returns the result.
25    ///
26    /// # Arguments
27    ///.
28    /// * `transaction_params` - Transaction parameters.
29    /// * `transaction_bytes` - Transaction Bytes to install
30    /// * `rpc_address` - An optional rpc address to send the request to.
31    ///
32    /// # Returns
33    ///
34    /// A `Result` containing either a `PutTransactionResult` or a `JsError` in case of an error.
35    ///
36    /// # Errors
37    ///
38    /// Returns a `JsError` if there is an error during the installation.
39    #[wasm_bindgen(js_name = "install")]
40    pub async fn install_js_alias(
41        &self,
42        transaction_params: TransactionStrParams,
43        transaction_bytes: Bytes,
44        rpc_address: Option<String>,
45    ) -> Result<PutTransactionResult, JsError> {
46        let result = self
47            .install(transaction_params, transaction_bytes, rpc_address)
48            .await;
49        match result {
50            Ok(data) => Ok(data.result.into()),
51            Err(err) => {
52                let err = &format!("Error occurred with {:?}", err);
53                Err(JsError::new(err))
54            }
55        }
56    }
57}
58
59/// A set of functions for installing smart contracts on the blockchain.
60/// Alias of sdk.transaction
61impl SDK {
62    /// Installs a smart contract with the specified parameters and returns the result.
63    ///
64    /// # Arguments
65    ///
66    /// * `transaction_params` - Transaction parameters.
67    /// * `transaction_bytes` - Transaction Bytes to install
68    /// * `rpc_address` - An optional rpc address to send the request to.
69    ///
70    /// # Returns
71    ///
72    /// A `Result` containing either a `_PutTransactionResult` or a `SdkError` in case of an error.
73    ///
74    /// # Errors
75    ///
76    /// Returns a `SdkError` if there is an error during the installation.
77    pub async fn install(
78        &self,
79        transaction_params: TransactionStrParams,
80        transaction_bytes: Bytes,
81        rpc_address: Option<String>,
82    ) -> Result<SuccessResponse<_PutTransactionResult>, SdkError> {
83        //log("install!");
84        let is_install_upgrade = Some(true);
85        let builder_params =
86            TransactionBuilderParams::new_session(Some(transaction_bytes), is_install_upgrade);
87        self.transaction(builder_params, transaction_params, None, rpc_address)
88            .await
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95    use crate::helpers::public_key_from_secret_key;
96    use once_cell::sync::Lazy;
97    use sdk_tests::{
98        config::{ARGS_SIMPLE, HELLO_CONTRACT, PAYMENT_AMOUNT, WASM_PATH},
99        tests::helpers::{get_network_constants, get_user_secret_key, read_wasm_file},
100    };
101    use tokio;
102
103    static ARGS: Lazy<Vec<String>> =
104        Lazy::new(|| ARGS_SIMPLE.iter().map(|s| s.to_string()).collect());
105
106    #[tokio::test]
107    async fn test_install_with_none_values() {
108        // Arrange
109        let sdk = SDK::new(None, None, None);
110        let transaction_params = TransactionStrParams::default();
111        transaction_params.set_payment_amount(PAYMENT_AMOUNT);
112        let transaction_bytes = Bytes::default();
113
114        let error_message =
115            "transaction requires account - use `with_account` or `with_secret_key`";
116
117        // Act
118        let result = sdk
119            .install(transaction_params, transaction_bytes, None)
120            .await;
121
122        // Assert
123        assert!(result.is_err());
124        let err_string = result.err().unwrap().to_string();
125
126        assert!(err_string.contains(error_message));
127    }
128
129    #[tokio::test]
130    async fn test_install_with_valid_input() {
131        // Arrange
132        let sdk = SDK::new(None, None, None);
133        let (rpc_address, _, _, _, chain_name) = get_network_constants();
134        let secret_key = get_user_secret_key(None).unwrap();
135
136        let mut transaction_params = TransactionStrParams::default();
137        transaction_params.set_secret_key(&secret_key);
138        transaction_params.set_chain_name(&chain_name);
139        transaction_params.set_payment_amount(PAYMENT_AMOUNT);
140        transaction_params.set_session_args_simple(ARGS.to_vec());
141
142        let transaction_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
143            Ok(transaction_bytes) => transaction_bytes,
144            Err(err) => {
145                eprintln!("Error reading file: {:?}", err);
146                return;
147            }
148        };
149
150        // Act
151        let result = sdk
152            .install(
153                transaction_params,
154                transaction_bytes.into(),
155                Some(rpc_address),
156            )
157            .await;
158
159        // Assert
160        assert!(result.is_ok());
161        let transaction_hash = result.unwrap().result.transaction_hash;
162        assert!(!transaction_hash.to_string().is_empty());
163    }
164
165    #[tokio::test]
166    async fn test_install_with_invalid_input() {
167        // Arrange
168        let sdk = SDK::new(None, None, None);
169        let (rpc_address, _, _, _, _) = get_network_constants();
170        let secret_key = get_user_secret_key(None).unwrap();
171
172        let error_message = "The transaction sent to the network had an invalid chain name";
173
174        let mut transaction_params = TransactionStrParams::default();
175        transaction_params.set_secret_key(&secret_key);
176        transaction_params.set_chain_name("test");
177        transaction_params.set_session_args_simple(ARGS.to_vec());
178        transaction_params.set_payment_amount(PAYMENT_AMOUNT);
179
180        let transaction_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
181            Ok(transaction_bytes) => transaction_bytes,
182            Err(err) => {
183                eprintln!("Error reading file: {:?}", err);
184                return;
185            }
186        };
187
188        // Act
189        let result = sdk
190            .install(
191                transaction_params,
192                transaction_bytes.into(),
193                Some(rpc_address),
194            )
195            .await;
196
197        // Assert
198        assert!(result.is_err());
199        let err_string = result.err().unwrap().to_string();
200        assert!(err_string.contains(error_message));
201    }
202
203    #[tokio::test]
204    async fn test_install_without_secret_key() {
205        // Arrange
206        let sdk = SDK::new(None, None, None);
207        let (rpc_address, _, _, _, chain_name) = get_network_constants();
208        let secret_key = get_user_secret_key(None).unwrap();
209        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
210
211        let error_message = "the transaction was invalid: invalid associated keys";
212
213        let mut transaction_params = TransactionStrParams::default();
214        transaction_params.set_initiator_addr(&initiator_addr);
215        transaction_params.set_chain_name(&chain_name);
216        transaction_params.set_payment_amount(PAYMENT_AMOUNT);
217        transaction_params.set_session_args_simple(ARGS.to_vec());
218
219        let transaction_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
220            Ok(transaction_bytes) => transaction_bytes,
221            Err(err) => {
222                eprintln!("Error reading file: {:?}", err);
223                return;
224            }
225        };
226
227        // Act
228        let result = sdk
229            .install(
230                transaction_params,
231                transaction_bytes.into(),
232                Some(rpc_address),
233            )
234            .await;
235
236        // Assert
237        assert!(result.is_err());
238        let err_string = result.err().unwrap().to_string();
239        assert!(err_string.contains(error_message));
240    }
241
242    #[tokio::test]
243    async fn test_install_with_error() {
244        // Arrange
245        let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
246        let (_, _, _, _, chain_name) = get_network_constants();
247        let secret_key = get_user_secret_key(None).unwrap();
248
249        let error_message = "error sending request for url (http://localhost/rpc)";
250
251        let mut transaction_params = TransactionStrParams::default();
252        transaction_params.set_secret_key(&secret_key);
253        transaction_params.set_chain_name(&chain_name);
254        transaction_params.set_payment_amount(PAYMENT_AMOUNT);
255        transaction_params.set_session_args_simple(ARGS.to_vec());
256
257        let transaction_bytes = match read_wasm_file(&format!("{WASM_PATH}{HELLO_CONTRACT}")) {
258            Ok(transaction_bytes) => transaction_bytes,
259            Err(err) => {
260                eprintln!("Error reading file: {:?}", err);
261                return;
262            }
263        };
264        // Act
265        let result = sdk
266            .install(transaction_params, transaction_bytes.into(), None)
267            .await;
268
269        // Assert
270        assert!(result.is_err());
271        let err_string = result.err().unwrap().to_string();
272        assert!(err_string.contains(error_message));
273    }
274}