Skip to main content

casper_rust_wasm_sdk/sdk/rpcs/
get_block_transfers.rs

1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::types::hash::block_hash::BlockHash;
3#[cfg(all(feature = "js", target_arch = "wasm32"))]
4use crate::types::identifier::block_identifier::BlockIdentifier;
5use crate::{
6    types::{
7        identifier::block_identifier::BlockIdentifierInput, sdk_error::SdkError,
8        verbosity::Verbosity,
9    },
10    SDK,
11};
12use casper_client::{
13    cli::get_block_transfers as get_block_transfers_cli,
14    get_block_transfers as get_block_transfers_lib,
15    rpcs::results::GetBlockTransfersResult as _GetBlockTransfersResult, JsonRpcId, SuccessResponse,
16};
17#[cfg(all(feature = "js", target_arch = "wasm32"))]
18use gloo_utils::format::JsValueSerdeExt;
19use rand::RngExt;
20#[cfg(all(feature = "js", target_arch = "wasm32"))]
21use serde::{Deserialize, Serialize};
22#[cfg(all(feature = "js", target_arch = "wasm32"))]
23use wasm_bindgen::prelude::*;
24
25// Define a struct to wrap the GetBlockTransfersResult
26#[cfg(all(feature = "js", target_arch = "wasm32"))]
27#[derive(Debug, Deserialize, Clone, Serialize)]
28#[cfg_attr(feature = "js", wasm_bindgen)]
29pub struct GetBlockTransfersResult(_GetBlockTransfersResult);
30
31#[cfg(all(feature = "js", target_arch = "wasm32"))]
32impl From<GetBlockTransfersResult> for _GetBlockTransfersResult {
33    fn from(result: GetBlockTransfersResult) -> Self {
34        result.0
35    }
36}
37
38#[cfg(all(feature = "js", target_arch = "wasm32"))]
39impl From<_GetBlockTransfersResult> for GetBlockTransfersResult {
40    fn from(result: _GetBlockTransfersResult) -> Self {
41        GetBlockTransfersResult(result)
42    }
43}
44
45#[cfg(all(feature = "js", target_arch = "wasm32"))]
46#[cfg_attr(feature = "js", wasm_bindgen)]
47impl GetBlockTransfersResult {
48    /// Gets the API version as a JsValue.
49    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
50    #[cfg(feature = "js")]
51    pub fn api_version(&self) -> JsValue {
52        JsValue::from_serde(&self.0.api_version).unwrap()
53    }
54
55    /// Gets the block hash as an Option<BlockHash>.
56    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
57    pub fn block_hash(&self) -> Option<BlockHash> {
58        self.0.block_hash.map(Into::into)
59    }
60
61    /// Gets the transfers as a JsValue.
62    #[cfg_attr(feature = "js", wasm_bindgen(getter))]
63    #[cfg(feature = "js")]
64    pub fn transfers(&self) -> JsValue {
65        JsValue::from_serde(&self.0.transfers).unwrap()
66    }
67
68    /// Converts the GetBlockTransfersResult to a JsValue.
69    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toJson"))]
70    #[cfg(feature = "js")]
71    pub fn to_json(&self) -> JsValue {
72        JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
73    }
74}
75
76/// Options for the `get_block_transfers` method.
77#[derive(Debug, Deserialize, Clone, Default, Serialize)]
78#[cfg(all(feature = "js", target_arch = "wasm32"))]
79#[cfg_attr(
80    feature = "js",
81    wasm_bindgen(js_name = "getBlockTransfersOptions", getter_with_clone)
82)]
83pub struct GetBlockTransfersOptions {
84    pub maybe_block_id_as_string: Option<String>,
85    pub maybe_block_identifier: Option<BlockIdentifier>,
86    pub verbosity: Option<Verbosity>,
87    pub rpc_address: Option<String>,
88}
89
90#[cfg(all(feature = "js", target_arch = "wasm32"))]
91#[cfg_attr(feature = "js", wasm_bindgen)]
92impl SDK {
93    /// Parses block transfers options from a JsValue.
94    ///
95    /// # Arguments
96    ///
97    /// * `options` - A JsValue containing block transfers options to be parsed.
98    ///
99    /// # Returns
100    ///
101    /// Parsed block transfers options as a `GetBlockTransfersOptions` struct.
102    #[cfg(feature = "js")]
103    pub fn get_block_transfers_options(
104        &self,
105        options: JsValue,
106    ) -> Result<GetBlockTransfersOptions, JsError> {
107        options
108            .into_serde::<GetBlockTransfersOptions>()
109            .map_err(|err| JsError::new(&format!("Error deserializing options: {err:?}")))
110    }
111
112    /// Retrieves block transfers information using the provided options.
113    ///
114    /// # Arguments
115    ///
116    /// * `options` - An optional `GetBlockTransfersOptions` struct containing retrieval options.
117    ///
118    /// # Returns
119    ///
120    /// A `Result` containing either a `GetBlockTransfersResult` or a `JsError` in case of an error.
121    ///
122    /// # Errors
123    ///
124    /// Returns a `JsError` if there is an error during the retrieval process.
125    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "get_block_transfers"))]
126    #[cfg(feature = "js")]
127    pub async fn get_block_transfers_js_alias(
128        &self,
129        options: Option<GetBlockTransfersOptions>,
130    ) -> Result<GetBlockTransfersResult, JsError> {
131        let GetBlockTransfersOptions {
132            maybe_block_id_as_string,
133            maybe_block_identifier,
134            verbosity,
135            rpc_address,
136        } = options.unwrap_or_default();
137
138        let maybe_block_identifier = if let Some(maybe_block_identifier) = maybe_block_identifier {
139            Some(BlockIdentifierInput::BlockIdentifier(
140                maybe_block_identifier,
141            ))
142        } else {
143            maybe_block_id_as_string.map(BlockIdentifierInput::String)
144        };
145
146        let result = self
147            .get_block_transfers(maybe_block_identifier, verbosity, rpc_address)
148            .await;
149        match result {
150            Ok(data) => Ok(data.result.into()),
151            Err(err) => {
152                let err = &format!("Error occurred with {err:?}");
153                Err(JsError::new(err))
154            }
155        }
156    }
157
158    // JavaScript alias for `get_block_transfers`.
159    #[cfg_attr(feature = "js", wasm_bindgen(js_name = "chain_get_block_transfers"))]
160    #[deprecated(note = "This function is an alias. Please use `get_block_transfers` instead.")]
161    #[allow(deprecated)]
162    #[cfg(feature = "js")]
163    pub async fn chain_get_block_transfers(
164        &self,
165        options: Option<GetBlockTransfersOptions>,
166    ) -> Result<GetBlockTransfersResult, JsError> {
167        self.get_block_transfers_js_alias(options).await
168    }
169}
170
171impl SDK {
172    /// Retrieves block transfers information based on the provided options.
173    ///
174    /// # Arguments
175    ///
176    /// * `maybe_block_identifier` - An optional `BlockIdentifierInput` specifying the block identifier.
177    /// * `verbosity` - An optional `Verbosity` level for controlling the output verbosity.
178    /// * `rpc_address` - An optional string specifying the rpc address to use for the request.
179    ///
180    /// # Returns
181    ///
182    /// A `Result` containing either a `_GetBlockTransfersResult` or a `SdkError` in case of an error.
183    ///
184    /// # Errors
185    ///
186    /// Returns a `SdkError` if there is an error during the retrieval process.
187    pub async fn get_block_transfers(
188        &self,
189        maybe_block_identifier: Option<BlockIdentifierInput>,
190        verbosity: Option<Verbosity>,
191        rpc_address: Option<String>,
192    ) -> Result<SuccessResponse<_GetBlockTransfersResult>, SdkError> {
193        //log("get_block_transfers!");
194        let random_id = rand::rng().random::<u64>().to_string();
195        if let Some(BlockIdentifierInput::String(maybe_block_id)) = maybe_block_identifier {
196            get_block_transfers_cli(
197                &random_id,
198                &self.get_rpc_address(rpc_address),
199                self.get_verbosity(verbosity).into(),
200                &maybe_block_id,
201            )
202            .await
203            .map_err(SdkError::from)
204        } else {
205            let maybe_block_identifier =
206                if let Some(BlockIdentifierInput::BlockIdentifier(maybe_block_identifier)) =
207                    maybe_block_identifier
208                {
209                    Some(maybe_block_identifier)
210                } else {
211                    None
212                };
213            get_block_transfers_lib(
214                JsonRpcId::from(random_id),
215                &self.get_rpc_address(rpc_address),
216                self.get_verbosity(verbosity).into(),
217                maybe_block_identifier.map(Into::into),
218            )
219            .await
220            .map_err(SdkError::from)
221        }
222    }
223}
224
225#[cfg(test)]
226mod tests {
227    use super::*;
228    use crate::types::{
229        hash::block_hash::BlockHash, identifier::block_identifier::BlockIdentifier,
230    };
231    use sdk_tests::tests::helpers::get_network_constants;
232
233    #[tokio::test]
234    async fn test_get_block_transfers_with_none_values() {
235        // Arrange
236        let sdk = SDK::new(None, None, None);
237        let error_message = "failed to parse node address as valid URL";
238
239        // Act
240        let result = sdk.get_block_transfers(None, None, None).await;
241
242        // Assert
243        assert!(result.is_err());
244        let err_string = result.err().unwrap().to_string();
245        assert!(err_string.contains(error_message));
246    }
247
248    #[tokio::test]
249    async fn test_get_block_transfers_with_block_id_string() {
250        // Arrange
251        let sdk = SDK::new(None, None, None);
252        let verbosity = Some(Verbosity::High);
253        let (rpc_address, _, _, _, _) = get_network_constants();
254        let result = sdk
255            .get_block(None, verbosity, Some(rpc_address.clone()))
256            .await;
257        let block_hash = BlockHash::from(
258            *result
259                .unwrap()
260                .result
261                .block_with_signatures
262                .unwrap()
263                .block
264                .hash(),
265        )
266        .to_string();
267        let block_identifier = BlockIdentifierInput::String(block_hash.to_string());
268
269        // Act
270        let result = sdk
271            .get_block_transfers(Some(block_identifier), verbosity, Some(rpc_address))
272            .await;
273
274        // Assert
275        assert!(result.is_ok());
276    }
277
278    #[tokio::test]
279    async fn test_get_block_transfers_with_block_identifier() {
280        // Arrange
281        let sdk = SDK::new(None, None, None);
282        let block_identifier =
283            BlockIdentifierInput::BlockIdentifier(BlockIdentifier::from_height(1));
284        let verbosity = Some(Verbosity::High);
285        let (rpc_address, _, _, _, _) = get_network_constants();
286
287        // Act
288        let result = sdk
289            .get_block_transfers(Some(block_identifier), verbosity, Some(rpc_address))
290            .await;
291
292        // Assert
293        assert!(result.is_ok());
294    }
295
296    #[tokio::test]
297    async fn test_get_block_transfers_with_error() {
298        let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
299
300        let error_message = "error sending request";
301
302        // Act
303        let result = sdk.get_block_transfers(None, None, None).await;
304
305        // Assert
306        assert!(result.is_err());
307        let err_string = result.err().unwrap().to_string();
308        assert!(err_string.contains(error_message));
309    }
310}