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        .map_err(|e| *e)?;
104
105        self.speculative_exec(transaction, verbosity, rpc_address)
106            .await
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113    use crate::helpers::public_key_from_secret_key;
114    use sdk_tests::{
115        config::{PAYMENT_TRANSFER_AMOUNT, TRANSFER_AMOUNT},
116        tests::helpers::{get_network_constants, get_user_secret_key},
117    };
118
119    #[tokio::test]
120    #[ignore]
121    async fn _test_speculative_transfer_transaction_with_valid_params() {
122        // Arrange
123        let sdk = SDK::new(None, None, None);
124        let verbosity = Some(Verbosity::High);
125        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
126
127        let secret_key = get_user_secret_key(None).unwrap();
128        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
129
130        let transaction_params = TransactionStrParams::default();
131        transaction_params.set_secret_key(&secret_key);
132        transaction_params.set_chain_name(&chain_name);
133        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
134
135        // Act
136        let result = sdk
137            .speculative_transfer_transaction(
138                None,
139                &initiator_addr,
140                TRANSFER_AMOUNT,
141                transaction_params,
142                None,
143                verbosity,
144                Some(default_speculative_address),
145            )
146            .await;
147
148        // Assert
149        assert!(result.is_ok());
150    }
151
152    #[tokio::test]
153    async fn test_speculative_transfer_transaction_with_valid_params_without_secret_key() {
154        // Arrange
155        let sdk = SDK::new(None, None, None);
156        let verbosity = Some(Verbosity::High);
157        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
158
159        let secret_key = get_user_secret_key(None).unwrap();
160        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
161
162        let transaction_params = TransactionStrParams::default();
163        transaction_params.set_chain_name(&chain_name);
164        transaction_params.set_initiator_addr(&initiator_addr);
165        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
166
167        // Act
168        let result = sdk
169            .speculative_transfer_transaction(
170                None,
171                &initiator_addr,
172                TRANSFER_AMOUNT,
173                transaction_params,
174                None,
175                verbosity,
176                Some(default_speculative_address),
177            )
178            .await;
179
180        // Assert
181        assert!(result.is_err());
182    }
183
184    #[tokio::test]
185    async fn test_speculative_transfer_transaction_with_invalid_params() {
186        // Arrange
187        let sdk = SDK::new(None, None, None);
188        let verbosity = Some(Verbosity::High);
189        let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
190
191        let error_message = "error";
192        let secret_key = get_user_secret_key(None).unwrap();
193        let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
194
195        let transaction_params = TransactionStrParams::default();
196        transaction_params.set_chain_name(&chain_name);
197        transaction_params.set_secret_key(&secret_key);
198        transaction_params.set_payment_amount(PAYMENT_TRANSFER_AMOUNT);
199
200        // Act
201        let result = sdk
202            .speculative_transfer_transaction(
203                None,
204                &initiator_addr,
205                TRANSFER_AMOUNT,
206                transaction_params,
207                None,
208                verbosity,
209                Some(default_speculative_address),
210            )
211            .await;
212
213        // Assert
214        assert!(result.is_err());
215
216        let err_string = result.err().unwrap().to_string();
217        assert!(err_string.contains(error_message));
218    }
219}