casper_rust_wasm_sdk/sdk/deploy/
speculative_transfer.rs

1#[cfg(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        },
9        sdk_error::SdkError,
10        verbosity::Verbosity,
11    },
12    SDK,
13};
14use casper_client::{
15    cli::deploy::make_transfer, rpcs::results::SpeculativeExecResult as _SpeculativeExecResult,
16    SuccessResponse,
17};
18use rand::Rng;
19#[cfg(target_arch = "wasm32")]
20use wasm_bindgen::prelude::*;
21
22#[cfg(target_arch = "wasm32")]
23#[wasm_bindgen]
24impl SDK {
25    /// JS function for speculative transfer.
26    ///
27    /// # Arguments
28    ///
29    /// * `amount` - The amount to transfer.
30    /// * `target_account` - The target account.
31    /// * `transfer_id` - An optional transfer ID (defaults to a random number).
32    /// * `deploy_params` - The deployment parameters.
33    /// * `payment_params` - The payment parameters.
34    /// * `verbosity` - The verbosity level for logging (optional).
35    /// * `rpc_address` - The address of the node to connect to (optional).
36    ///
37    /// # Returns
38    ///
39    /// A `Result` containing the result of the speculative transfer or a `JsError` in case of an error.
40    #[wasm_bindgen(js_name = "speculative_transfer")]
41    #[allow(clippy::too_many_arguments, deprecated)]
42    #[deprecated(note = "prefer speculative_transfer_transaction")]
43    pub async fn speculative_transfer_js_alias(
44        &self,
45        amount: &str,
46        target_account: &str,
47        transfer_id: Option<String>,
48        deploy_params: DeployStrParams,
49        payment_params: PaymentStrParams,
50        verbosity: Option<Verbosity>,
51        rpc_address: Option<String>,
52    ) -> Result<SpeculativeExecResult, JsError> {
53        let result = self
54            .speculative_transfer(
55                amount,
56                target_account,
57                transfer_id,
58                deploy_params,
59                payment_params,
60                verbosity,
61                rpc_address,
62            )
63            .await;
64        match result {
65            Ok(data) => Ok(data.result.into()),
66            Err(err) => {
67                let err = &format!("Error occurred with {:?}", err);
68                Err(JsError::new(err))
69            }
70        }
71    }
72}
73
74impl SDK {
75    /// Perform a speculative transfer.
76    ///
77    /// # Arguments
78    ///
79    /// * `amount` - The amount to transfer.
80    /// * `target_account` - The target account.
81    /// * `transfer_id` - An optional transfer ID (defaults to a random number).
82    /// * `deploy_params` - The deployment parameters.
83    /// * `payment_params` - The payment parameters.
84    /// * `verbosity` - The verbosity level for logging (optional).
85    /// * `rpc_address` - The address of the node to connect to (optional).
86    ///
87    /// # Returns
88    ///
89    /// A `Result` containing the result a `SuccessResponse<_SpeculativeExecResult>` or a `SdkError` in case of an error.
90    #[allow(clippy::too_many_arguments, deprecated)]
91    #[deprecated(note = "prefer speculative_transfer_transaction")]
92    pub async fn speculative_transfer(
93        &self,
94        amount: &str,
95        target_account: &str,
96        transfer_id: Option<String>,
97        deploy_params: DeployStrParams,
98        payment_params: PaymentStrParams,
99        verbosity: Option<Verbosity>,
100        rpc_address: Option<String>,
101    ) -> Result<SuccessResponse<_SpeculativeExecResult>, SdkError> {
102        // log("speculative_transfer!");
103        let transfer_id = if let Some(transfer_id) = transfer_id {
104            transfer_id
105        } else {
106            rand::thread_rng().gen::<u64>().to_string()
107        };
108        let deploy = make_transfer(
109            "",
110            amount,
111            target_account,
112            &transfer_id,
113            deploy_str_params_to_casper_client(&deploy_params),
114            payment_str_params_to_casper_client(&payment_params),
115            false,
116        );
117
118        if let Err(err) = deploy {
119            return Err(SdkError::from(err));
120        }
121
122        self.speculative_exec_deploy(deploy.unwrap().into(), verbosity, rpc_address)
123            .await
124    }
125}
126
127#[cfg(test)]
128#[allow(deprecated)]
129mod tests {
130    use super::*;
131    use crate::helpers::public_key_from_secret_key;
132    use sdk_tests::{
133        config::{PAYMENT_TRANSFER_AMOUNT, TRANSFER_AMOUNT},
134        tests::helpers::{get_network_constants, get_user_secret_key},
135    };
136
137    #[tokio::test]
138    #[ignore]
139    async fn _test_speculative_transfer_with_valid_params() {
140        // Arrange
141        let sdk = SDK::new(None, None, None);
142        let verbosity = Some(Verbosity::High);
143        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
144
145        let secret_key = get_user_secret_key(None).unwrap();
146        let account = public_key_from_secret_key(&secret_key).unwrap();
147
148        let deploy_params =
149            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
150        let payment_params = PaymentStrParams::default();
151        payment_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
152
153        // Act
154        let result = sdk
155            .speculative_transfer(
156                TRANSFER_AMOUNT,
157                &account,
158                None,
159                deploy_params,
160                payment_params,
161                verbosity,
162                Some(default_speculative_address),
163            )
164            .await;
165
166        // Assert
167        assert!(result.is_ok());
168    }
169
170    #[tokio::test]
171    async fn test_speculative_transfer_with_valid_params_without_secret_key() {
172        // Arrange
173        let sdk = SDK::new(None, None, None);
174        let verbosity = Some(Verbosity::High);
175        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
176
177        let secret_key = get_user_secret_key(None).unwrap();
178        let account = public_key_from_secret_key(&secret_key).unwrap();
179
180        let deploy_params = DeployStrParams::new(&chain_name, &account, None, None, None, None);
181        let payment_params = PaymentStrParams::default();
182        payment_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
183
184        // Act
185        let result = sdk
186            .speculative_transfer(
187                TRANSFER_AMOUNT,
188                &account,
189                None,
190                deploy_params,
191                payment_params,
192                verbosity,
193                Some(default_speculative_address),
194            )
195            .await;
196
197        // Assert
198        assert!(result.is_err());
199    }
200
201    #[tokio::test]
202    async fn test_speculative_transfer_with_invalid_params() {
203        // Arrange
204        let sdk = SDK::new(None, None, None);
205        let verbosity = Some(Verbosity::High);
206        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
207
208        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\"]";
209        let secret_key = get_user_secret_key(None).unwrap();
210        let account = public_key_from_secret_key(&secret_key).unwrap();
211
212        let deploy_params =
213            DeployStrParams::new(&chain_name, &account, Some(secret_key), None, None, None);
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_transfer(
220                TRANSFER_AMOUNT,
221                &account,
222                None,
223                deploy_params,
224                payment_params,
225                verbosity,
226                Some(default_speculative_address),
227            )
228            .await;
229
230        // Assert
231        assert!(result.is_err());
232
233        let err_string = result.err().unwrap().to_string();
234        assert!(err_string.contains(error_message));
235    }
236}