casper_rust_wasm_sdk/sdk/rpcs/
get_block_transfers.rs

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