casper_rust_wasm_sdk/sdk/rpcs/
get_deploy.rs

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