casper_rust_wasm_sdk/sdk/transaction/
speculative_transfer_transaction.rs

1#[cfg(target_arch = "wasm32")]
2use crate::rpcs::speculative_exec::SpeculativeExecTxnResult;
3use crate::{
4    make_transfer_transaction,
5    types::{
6        sdk_error::SdkError, transaction_params::transaction_str_params::TransactionStrParams,
7        uref::URef, verbosity::Verbosity,
8    },
9    SDK,
10};
11use casper_client::{
12    rpcs::results::SpeculativeExecTxnResult as _SpeculativeExecTxnResult, SuccessResponse,
13};
14#[cfg(target_arch = "wasm32")]
15use wasm_bindgen::prelude::*;
16
17#[cfg(target_arch = "wasm32")]
18#[wasm_bindgen]
19impl SDK {
20    /// JS function for speculative transfer transaction.
21    ///
22    /// # Arguments
23    ///
24    /// * `maybe_source` - Optional transfer source uref.
25    /// * `target_account` - The target account.
26    /// * `amount` - The amount to transfer.
27    /// * `maybe_id` - An optional transfer ID (defaults to a random number).
28    /// * `transaction_params` - The transactionment parameters.
29    /// * `verbosity` - The verbosity level for logging (optional).
30    /// * `rpc_address` - The address of the node to connect to (optional).
31    ///
32    /// # Returns
33    ///
34    /// A `Result` containing the result of the speculative transfer or a `JsError` in case of an error.
35    #[allow(clippy::too_many_arguments)]
36    #[wasm_bindgen(js_name = "speculative_transfer_transaction")]
37    pub async fn speculative_transfer_transaction_js_alias(
38        &self,
39        maybe_source: Option<URef>,
40        target_account: &str,
41        amount: &str,
42        transaction_params: TransactionStrParams,
43        maybe_id: Option<String>,
44        verbosity: Option<Verbosity>,
45        rpc_address: Option<String>,
46    ) -> Result<SpeculativeExecTxnResult, JsError> {
47        let result = self
48            .speculative_transfer_transaction(
49                maybe_source,
50                target_account,
51                amount,
52                transaction_params,
53                maybe_id,
54                verbosity,
55                rpc_address,
56            )
57            .await;
58        match result {
59            Ok(data) => Ok(data.result.into()),
60            Err(err) => {
61                let err = &format!("Error occurred with {:?}", err);
62                Err(JsError::new(err))
63            }
64        }
65    }
66}
67
68impl SDK {
69    /// Perform a speculative transfer transaction.
70    ///
71    /// # Arguments
72    ///
73    /// * `maybe_source` - Optional transfer source uref.
74    /// * `amount` - The amount to transfer.
75    /// * `target_account` - The target account.
76    /// * `transaction_params` - The transactionment parameters.
77    /// * `maybe_id` - An optional transfer ID (defaults to a random number).
78    /// * `verbosity` - The verbosity level for logging (optional).
79    /// * `rpc_address` - The address of the node to connect to (optional).
80    ///
81    /// # Returns
82    ///
83    /// A `Result` containing the result a `SuccessResponse<_SpeculativeExecTxnResult>` or a `SdkError` in case of an error.
84    #[allow(clippy::too_many_arguments)]
85    pub async fn speculative_transfer_transaction(
86        &self,
87        maybe_source: Option<URef>,
88        target_account: &str,
89        amount: &str,
90        transaction_params: TransactionStrParams,
91        maybe_id: Option<String>,
92        verbosity: Option<Verbosity>,
93        rpc_address: Option<String>,
94    ) -> Result<SuccessResponse<_SpeculativeExecTxnResult>, SdkError> {
95        // log("speculative_transfer_transaction!");
96        let transaction = make_transfer_transaction(
97            maybe_source,
98            target_account,
99            amount,
100            transaction_params,
101            maybe_id,
102        )?;
103
104        self.speculative_exec(transaction, verbosity, rpc_address)
105            .await
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use super::*;
112    use crate::helpers::public_key_from_secret_key;
113    use sdk_tests::{
114        config::{PAYMENT_TRANSFER_AMOUNT, TRANSFER_AMOUNT},
115        tests::helpers::{get_network_constants, get_user_secret_key},
116    };
117
118    #[tokio::test]
119    #[ignore]
120    async fn _test_speculative_transfer_transaction_with_valid_params() {
121        // Arrange
122        let sdk = SDK::new(None, None, None);
123        let verbosity = Some(Verbosity::High);
124        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
125
126        let secret_key = get_user_secret_key(None).unwrap();
127        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
128
129        let transaction_params = TransactionStrParams::default();
130        transaction_params.set_secret_key(&secret_key);
131        transaction_params.set_chain_name(&chain_name);
132        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
133
134        // Act
135        let result = sdk
136            .speculative_transfer_transaction(
137                None,
138                &initiator_addr,
139                TRANSFER_AMOUNT,
140                transaction_params,
141                None,
142                verbosity,
143                Some(default_speculative_address),
144            )
145            .await;
146
147        // Assert
148        assert!(result.is_ok());
149    }
150
151    #[tokio::test]
152    async fn test_speculative_transfer_transaction_with_valid_params_without_secret_key() {
153        // Arrange
154        let sdk = SDK::new(None, None, None);
155        let verbosity = Some(Verbosity::High);
156        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
157
158        let secret_key = get_user_secret_key(None).unwrap();
159        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
160
161        let transaction_params = TransactionStrParams::default();
162        transaction_params.set_chain_name(&chain_name);
163        transaction_params.set_initiator_addr(&initiator_addr);
164        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
165
166        // Act
167        let result = sdk
168            .speculative_transfer_transaction(
169                None,
170                &initiator_addr,
171                TRANSFER_AMOUNT,
172                transaction_params,
173                None,
174                verbosity,
175                Some(default_speculative_address),
176            )
177            .await;
178
179        // Assert
180        assert!(result.is_err());
181    }
182
183    #[tokio::test]
184    async fn test_speculative_transfer_transaction_with_invalid_params() {
185        // Arrange
186        let sdk = SDK::new(None, None, None);
187        let verbosity = Some(Verbosity::High);
188        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
189
190        let error_message = "Node request failure";
191        let secret_key = get_user_secret_key(None).unwrap();
192        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
193
194        let transaction_params = TransactionStrParams::default();
195        transaction_params.set_chain_name(&chain_name);
196        transaction_params.set_secret_key(&secret_key);
197        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
198
199        // Act
200        let result = sdk
201            .speculative_transfer_transaction(
202                None,
203                &initiator_addr,
204                TRANSFER_AMOUNT,
205                transaction_params,
206                None,
207                verbosity,
208                Some(default_speculative_address),
209            )
210            .await;
211
212        // Assert
213        assert!(result.is_err());
214
215        let err_string = result.err().unwrap().to_string();
216        assert!(err_string.contains(error_message));
217    }
218}