Skip to main content

casper_rust_wasm_sdk/sdk/deploy/
speculative_deploy.rs

1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::rpcs::speculative_exec_deploy::SpeculativeExecResult;
3use crate::{
4    types::{
5        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        },
10        sdk_error::SdkError,
11        verbosity::Verbosity,
12    },
13    SDK,
14};
15use casper_client::{
16    cli::deploy::make_deploy, rpcs::results::SpeculativeExecResult as _SpeculativeExecResult,
17    SuccessResponse,
18};
19#[cfg(all(feature = "js", target_arch = "wasm32"))]
20use wasm_bindgen::prelude::*;
21
22#[cfg(all(feature = "js", target_arch = "wasm32"))]
23#[cfg_attr(feature = "js", wasm_bindgen)]
24impl SDK {
25    /// This function allows executing a deploy speculatively.
26    ///
27    /// # Arguments
28    ///
29    /// * `deploy_params` - Deployment parameters for the deploy.
30    /// * `session_params` - Session parameters for the deploy.
31    /// * `payment_params` - Payment parameters for the deploy.
32    /// * `verbosity` - Optional verbosity level.
33    /// * `rpc_address` - Optional rpc address.
34    ///
35    /// # Returns
36    ///
37    /// A `Result` containing either a `SpeculativeExecResult` or a `JsError` in case of an error.
38    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "speculative_deploy"))]
39    #[allow(clippy::too_many_arguments, deprecated)]
40    #[deprecated(note = "prefer speculative_transaction")]
41    #[cfg(feature = "js")]
42    pub async fn speculative_deploy_js_alias(
43        &self,
44        deploy_params: DeployStrParams,
45        session_params: SessionStrParams,
46        payment_params: PaymentStrParams,
47        verbosity: Option<Verbosity>,
48        rpc_address: Option<String>,
49    ) -> Result<SpeculativeExecResult, JsError> {
50        let result = self
51            .speculative_deploy(
52                deploy_params,
53                session_params,
54                payment_params,
55                verbosity,
56                rpc_address,
57            )
58            .await;
59        match result {
60            Ok(data) => Ok(data.result.into()),
61            Err(err) => {
62                let err = &format!("Error occurred with {err:?}");
63                Err(JsError::new(err))
64            }
65        }
66    }
67}
68
69impl SDK {
70    /// This function allows executing a deploy speculatively.
71    ///
72    /// # Arguments
73    ///
74    /// * `deploy_params` - Deployment parameters for the deploy.
75    /// * `session_params` - Session parameters for the deploy.
76    /// * `payment_params` - Payment parameters for the deploy.
77    /// * `verbosity` - Optional verbosity level.
78    /// * `rpc_address` - Optional rpc address.
79    ///
80    /// # Returns
81    ///
82    /// A `Result` containing either a `SuccessResponse<_SpeculativeExecResult>` or a `SdkError` in case of an error.
83    #[allow(clippy::too_many_arguments, deprecated)]
84    #[deprecated(note = "prefer speculative_transaction")]
85    pub async fn speculative_deploy(
86        &self,
87        deploy_params: DeployStrParams,
88        session_params: SessionStrParams,
89        payment_params: PaymentStrParams,
90        verbosity: Option<Verbosity>,
91        rpc_address: Option<String>,
92    ) -> Result<SuccessResponse<_SpeculativeExecResult>, SdkError> {
93        // log("speculative_deploy!");
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
102        if let Err(err) = deploy {
103            return Err(SdkError::from(err));
104        }
105
106        self.speculative_exec_deploy(deploy.unwrap().into(), verbosity, rpc_address)
107            .await
108    }
109}
110
111#[cfg(test)]
112#[allow(deprecated)]
113mod tests {
114    use super::*;
115    use crate::helpers::public_key_from_secret_key;
116    use once_cell::sync::Lazy;
117    use sdk_tests::{
118        config::{ARGS_SIMPLE, HELLO_CONTRACT, PAYMENT_AMOUNT, WASM_PATH},
119        tests::helpers::{get_network_constants, get_user_secret_key, read_wasm_file},
120    };
121    use std::sync::Mutex;
122
123    static SESSION_PARAMS: Lazy<Mutex<Option<SessionStrParams>>> = Lazy::new(|| Mutex::new(None));
124
125    fn get_session_params() -> SessionStrParams {
126        let mut session_params = SESSION_PARAMS.lock().unwrap();
127
128        if session_params.is_none() {
129            let mut new_session_params = SessionStrParams::default();
130            let file_path = &format!("{WASM_PATH}{HELLO_CONTRACT}");
131            let module_bytes = match read_wasm_file(file_path) {
132                Ok(module_bytes) => module_bytes,
133                Err(err) => {
134                    eprintln!("Error reading file: {err:?}");
135                    unimplemented!()
136                }
137            };
138            new_session_params.set_session_bytes(module_bytes.into());
139            let args_simple: Vec<String> = ARGS_SIMPLE.iter().map(|s| s.to_string()).collect();
140            new_session_params.set_session_args_simple(args_simple);
141            *session_params = Some(new_session_params);
142        }
143
144        session_params.clone().unwrap()
145    }
146
147    #[tokio::test]
148    #[ignore]
149    async fn _test_speculative_deploy_with_valid_params() {
150        // Arrange
151        let sdk = SDK::new(None, None, None);
152        let verbosity = Some(Verbosity::High);
153        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
154
155        let secret_key = get_user_secret_key(None).unwrap();
156        let account = public_key_from_secret_key(&secret_key).unwrap();
157
158        let deploy_params =
159            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
160        let payment_params = PaymentStrParams::default();
161        payment_params.set_payment_amount(PAYMENT_AMOUNT);
162
163        // Act
164        let result = sdk
165            .speculative_deploy(
166                deploy_params,
167                get_session_params().clone(),
168                payment_params,
169                verbosity,
170                Some(default_speculative_address),
171            )
172            .await;
173
174        // Assert
175        assert!(result.is_ok());
176    }
177
178    #[tokio::test]
179    async fn test_speculative_deploy_with_valid_params_without_secret_key() {
180        // Arrange
181        let sdk = SDK::new(None, None, None);
182        let verbosity = Some(Verbosity::High);
183        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
184
185        let deploy_params = DeployStrParams::new(&chain_name, "", None, None, None, None);
186        let payment_params = PaymentStrParams::default();
187        payment_params.set_payment_amount(PAYMENT_AMOUNT);
188
189        // Act
190        let result = sdk
191            .speculative_deploy(
192                deploy_params,
193                get_session_params().clone(),
194                payment_params,
195                verbosity,
196                Some(default_speculative_address),
197            )
198            .await;
199
200        // Assert
201        assert!(result.is_err());
202    }
203
204    #[tokio::test]
205    async fn test_speculative_deploy_with_invalid_params() {
206        // Arrange
207        let sdk = SDK::new(None, None, None);
208        let verbosity = Some(Verbosity::High);
209        let (_, _, default_speculative_address, _, _) = get_network_constants();
210
211        let error_message = "Missing a required arg - exactly one of the following must be provided: [\"payment_amount\", \"payment_hash\", \"payment_name\", \"payment_package_hash\", \"payment_package_name\", \"payment_path\", \"has_payment_bytes\"]";
212
213        let deploy_params = DeployStrParams::default();
214        let payment_params = PaymentStrParams::default();
215        payment_params.set_payment_amount(""); // This is not valid payment amount
216
217        // Act
218        let result = sdk
219            .speculative_deploy(
220                deploy_params,
221                get_session_params().clone(),
222                payment_params,
223                verbosity,
224                Some(default_speculative_address),
225            )
226            .await;
227
228        // Assert
229        assert!(result.is_err());
230
231        let err_string = result.err().unwrap().to_string();
232
233        assert!(err_string.contains(error_message));
234    }
235}