Skip to main content

casper_rust_wasm_sdk/sdk/transaction/
speculative_transfer_transaction.rs

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