Skip to main content

casper_rust_wasm_sdk/sdk/rpcs/
get_deploy.rs

1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::types::deploy::Deploy;
3use crate::types::hash::deploy_hash::DeployHash;
4use crate::{
5    types::{sdk_error::SdkError, verbosity::Verbosity},
6    SDK,
7};
8use casper_client::{
9    get_deploy, rpcs::results::GetDeployResult as _GetDeployResult, JsonRpcId, SuccessResponse,
10};
11#[cfg(all(feature = "js", target_arch = "wasm32"))]
12use gloo_utils::format::JsValueSerdeExt;
13use rand::RngExt;
14#[cfg(all(feature = "js", target_arch = "wasm32"))]
15use serde::{Deserialize, Serialize};
16#[cfg(all(feature = "js", target_arch = "wasm32"))]
17use wasm_bindgen::prelude::*;
18
19// Define a struct to wrap the GetDeployResult
20#[cfg(all(feature = "js", target_arch = "wasm32"))]
21#[derive(Debug, Deserialize, Clone, Serialize)]
22#[cfg_attr(feature = "js", wasm_bindgen)]
23pub struct GetDeployResult(_GetDeployResult);
24
25#[cfg(all(feature = "js", target_arch = "wasm32"))]
26impl From<GetDeployResult> for _GetDeployResult {
27    fn from(result: GetDeployResult) -> Self {
28        result.0
29    }
30}
31#[cfg(all(feature = "js", target_arch = "wasm32"))]
32impl From<_GetDeployResult> for GetDeployResult {
33    fn from(result: _GetDeployResult) -> Self {
34        GetDeployResult(result)
35    }
36}
37
38#[cfg(all(feature = "js", target_arch = "wasm32"))]
39#[cfg_attr(feature = "js", wasm_bindgen)]
40impl GetDeployResult {
41    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
42    /// Gets the API version as a JavaScript value.
43    #[cfg(feature = "js")]
44    pub fn api_version(&self) -> JsValue {
45        JsValue::from_serde(&self.0.api_version).unwrap()
46    }
47
48    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
49    /// Gets the deploy information.
50    pub fn deploy(&self) -> Deploy {
51        self.0.deploy.clone().into()
52    }
53
54    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
55    /// Gets the execution info as a JavaScript value.
56    #[cfg(feature = "js")]
57    pub fn execution_info(&self) -> JsValue {
58        JsValue::from_serde(&self.0.execution_info).unwrap()
59    }
60
61    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toJson"))]
62    /// Converts the result to a JSON JavaScript value.
63    #[cfg(feature = "js")]
64    pub fn to_json(&self) -> JsValue {
65        JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
66    }
67}
68
69/// Options for the `get_deploy` method.
70#[derive(Debug, Clone, Default, Deserialize, Serialize)]
71#[cfg(all(feature = "js", target_arch = "wasm32"))]
72#[cfg_attr(
73    feature = "js",
74    wasm_bindgen(js_name = "getDeployOptions", getter_with_clone)
75)]
76pub struct GetDeployOptions {
77    pub deploy_hash_as_string: Option<String>,
78    pub deploy_hash: Option<DeployHash>,
79    pub finalized_approvals: Option<bool>,
80    pub rpc_address: Option<String>,
81    pub verbosity: Option<Verbosity>,
82}
83
84#[cfg(all(feature = "js", target_arch = "wasm32"))]
85#[cfg_attr(feature = "js", wasm_bindgen)]
86impl SDK {
87    /// Parses deploy options from a JsValue.
88    ///
89    /// # Arguments
90    ///
91    /// * `options` - A JsValue containing deploy options to be parsed.
92    ///
93    /// # Returns
94    ///
95    /// Parsed deploy options as a `GetDeployOptions` struct.
96    #[deprecated(note = "prefer 'get_transaction_options'")]
97    #[allow(deprecated)]
98    #[cfg(feature = "js")]
99    pub fn get_deploy_options(&self, options: JsValue) -> Result<GetDeployOptions, JsError> {
100        let mut options: GetDeployOptions = options.into_serde()?;
101
102        // Handle finalized_approvals
103        if let Some(finalized_approvals) = options.finalized_approvals {
104            options.finalized_approvals =
105                Some(JsValue::from_bool(finalized_approvals) == JsValue::TRUE);
106        }
107
108        Ok(options)
109    }
110
111    /// Retrieves deploy information using the provided options.
112    ///
113    /// # Arguments
114    ///
115    /// * `options` - An optional `GetDeployOptions` struct containing retrieval options.
116    ///
117    /// # Returns
118    ///
119    /// A `Result` containing either a `GetDeployResult` or an error.
120    #[deprecated(note = "prefer 'get_transaction'")]
121    #[allow(deprecated)]
122    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "get_deploy"))]
123    #[cfg(feature = "js")]
124    pub async fn get_deploy_js_alias(
125        &self,
126        options: Option<GetDeployOptions>,
127    ) -> Result<GetDeployResult, JsError> {
128        let GetDeployOptions {
129            deploy_hash_as_string,
130            deploy_hash,
131            finalized_approvals,
132            verbosity,
133            rpc_address,
134        } = options.unwrap_or_default();
135
136        let err_msg = "Error: Missing deploy hash as string or deploy hash".to_string();
137        let deploy_hash = if let Some(deploy_hash_as_string) = deploy_hash_as_string {
138            DeployHash::new(&deploy_hash_as_string)?
139        } else {
140            if deploy_hash.is_none() {
141                return Err(JsError::new(&err_msg));
142            }
143            deploy_hash.unwrap()
144        };
145
146        let result = self
147            .get_deploy(deploy_hash, finalized_approvals, verbosity, rpc_address)
148            .await;
149        match result {
150            Ok(data) => Ok(data.result.into()),
151            Err(err) => {
152                let err = &format!("Error occurred with {err:?}");
153                Err(JsError::new(err))
154            }
155        }
156    }
157
158    /// Retrieves deploy information using the provided options, alias for `get_deploy`.
159    #[deprecated(note = "This function is an alias. Please use `get_transaction` instead.")]
160    #[allow(deprecated)]
161    #[cfg(feature = "js")]
162    pub async fn info_get_deploy(
163        &self,
164        options: Option<GetDeployOptions>,
165    ) -> Result<GetDeployResult, JsError> {
166        self.get_deploy_js_alias(options).await
167    }
168}
169
170impl SDK {
171    /// Retrieves deploy information based on the provided options.
172    ///
173    /// # Arguments
174    ///
175    /// * `deploy_hash` - The deploy hash.
176    /// * `finalized_approvals` - An optional boolean indicating finalized approvals.
177    /// * `verbosity` - An optional verbosity level.
178    /// * `rpc_address` - An optional rpc address.
179    ///
180    /// # Returns
181    ///
182    /// A `Result` containing either a `_GetDeployResult` or an error.
183    #[deprecated(note = "prefer 'get_transaction'")]
184    #[allow(deprecated)]
185    pub async fn get_deploy(
186        &self,
187        deploy_hash: DeployHash,
188        finalized_approvals: Option<bool>,
189        verbosity: Option<Verbosity>,
190        rpc_address: Option<String>,
191    ) -> Result<SuccessResponse<_GetDeployResult>, SdkError> {
192        //log("get_deploy!");
193        let random_id = JsonRpcId::from(rand::rng().random::<u64>().to_string());
194        get_deploy(
195            random_id,
196            &self.get_rpc_address(rpc_address),
197            self.get_verbosity(verbosity).into(),
198            deploy_hash.into(),
199            finalized_approvals.unwrap_or_default(),
200        )
201        .await
202        .map_err(Into::into)
203    }
204}
205
206#[cfg(test)]
207mod tests {
208    use super::*;
209    use crate::{
210        helpers::public_key_from_secret_key,
211        types::deploy_params::{
212            deploy_str_params::DeployStrParams, payment_str_params::PaymentStrParams,
213        },
214    };
215    use sdk_tests::{
216        config::{PAYMENT_TRANSFER_AMOUNT, TRANSFER_AMOUNT},
217        tests::helpers::{get_network_constants, get_user_secret_key},
218    };
219
220    #[tokio::test]
221    #[allow(deprecated)]
222    async fn test_get_deploy_with_none_values() {
223        // Arrange
224        let sdk = SDK::new(None, None, None);
225        let deploy_hash = DeployHash::from_digest([1u8; 32].into()).unwrap();
226        let error_message = "failed to parse node address as valid URL";
227
228        // Act
229        let result = sdk.get_deploy(deploy_hash, None, None, None).await;
230
231        // Assert
232        assert!(result.is_err());
233        let err_string = result.err().unwrap().to_string();
234        assert!(err_string.contains(error_message));
235    }
236
237    #[tokio::test]
238    #[allow(deprecated)]
239    async fn test_get_deploy_with_invalid_deploy_hash() {
240        // Arrange
241        let sdk = SDK::new(None, None, None);
242        let deploy_hash = DeployHash::from_digest([1u8; 32].into()).unwrap();
243        let verbosity = Some(Verbosity::High);
244        let (rpc_address, _, _, _, _) = get_network_constants();
245
246        // Act
247        let result = sdk
248            .get_deploy(deploy_hash, None, verbosity, Some(rpc_address))
249            .await;
250
251        // Assert
252        assert!(result.is_err());
253    }
254
255    #[tokio::test]
256    #[allow(deprecated)]
257    async fn test_get_deploy_with_valid_deploy_hash() {
258        // Arrange
259        let sdk = SDK::new(None, None, None);
260        let verbosity = Some(Verbosity::High);
261        let (rpc_address, _, _, _, chain_name) = get_network_constants();
262
263        let secret_key = get_user_secret_key(None).unwrap();
264        let account = public_key_from_secret_key(&secret_key).unwrap();
265
266        let deploy_params =
267            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
268        let payment_params = PaymentStrParams::default();
269        payment_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
270        let make_transfer = sdk
271            .transfer(
272                TRANSFER_AMOUNT,
273                &account, // self transfer
274                None,
275                deploy_params,
276                payment_params,
277                verbosity,
278                Some(rpc_address.clone()),
279            )
280            .await
281            .unwrap();
282        let deploy_hash = make_transfer.result.deploy_hash;
283        assert!(!deploy_hash.to_string().is_empty());
284
285        // Act
286        let result = sdk
287            .get_deploy(deploy_hash.into(), None, verbosity, Some(rpc_address))
288            .await;
289
290        // Assert
291        assert!(result.is_ok());
292    }
293
294    #[tokio::test]
295    #[allow(deprecated)]
296    async fn test_get_deploy_with_finalized_approvals() {
297        // Arrange
298        let sdk = SDK::new(None, None, None);
299        let verbosity = Some(Verbosity::High);
300        let (rpc_address, _, _, _, chain_name) = get_network_constants();
301
302        let secret_key = get_user_secret_key(None).unwrap();
303        let account = public_key_from_secret_key(&secret_key).unwrap();
304
305        let deploy_params =
306            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
307        let payment_params = PaymentStrParams::default();
308        payment_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
309        let make_transfer = sdk
310            .transfer(
311                TRANSFER_AMOUNT,
312                &account, // self transfer
313                None,
314                deploy_params,
315                payment_params,
316                verbosity,
317                Some(rpc_address.clone()),
318            )
319            .await
320            .unwrap();
321        let deploy_hash = make_transfer.result.deploy_hash;
322        assert!(!deploy_hash.to_string().is_empty());
323        let finalized_approvals = true;
324
325        // Act
326        let result = sdk
327            .get_deploy(
328                deploy_hash.into(),
329                Some(finalized_approvals),
330                verbosity,
331                Some(rpc_address),
332            )
333            .await;
334
335        // Assert
336        assert!(result.is_ok());
337    }
338
339    #[tokio::test]
340    #[allow(deprecated)]
341    async fn test_get_deploy_with_error() {
342        // Arrange
343        let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
344        let deploy_hash = DeployHash::from_digest([1u8; 32].into()).unwrap();
345        let error_message = "error sending request";
346
347        // Act
348        let result = sdk.get_deploy(deploy_hash, None, None, None).await;
349
350        // Assert
351        assert!(result.is_err());
352        let err_string = result.err().unwrap().to_string();
353        assert!(err_string.contains(error_message));
354    }
355}