casper_rust_wasm_sdk/sdk/rpcs/
get_block.rs1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::types::identifier::block_identifier::BlockIdentifier;
3use crate::{
4 types::{
5 identifier::block_identifier::BlockIdentifierInput, sdk_error::SdkError,
6 verbosity::Verbosity,
7 },
8 SDK,
9};
10use casper_client::{
11 cli::get_block as get_block_cli, get_block as get_block_lib,
12 rpcs::results::GetBlockResult as _GetBlockResult, JsonRpcId, SuccessResponse,
13};
14#[cfg(all(feature = "js", target_arch = "wasm32"))]
15use casper_types::Block;
16#[cfg(all(feature = "js", target_arch = "wasm32"))]
17use gloo_utils::format::JsValueSerdeExt;
18use rand::RngExt;
19#[cfg(all(feature = "js", target_arch = "wasm32"))]
20use serde::{Deserialize, Serialize};
21#[cfg(all(feature = "js", target_arch = "wasm32"))]
22use wasm_bindgen::prelude::*;
23
24#[cfg(all(feature = "js", target_arch = "wasm32"))]
26#[derive(Debug, Deserialize, Serialize)]
27#[cfg_attr(feature = "js", wasm_bindgen)]
28pub struct GetBlockResult(_GetBlockResult);
29
30#[cfg(all(feature = "js", target_arch = "wasm32"))]
31impl From<GetBlockResult> for _GetBlockResult {
32 fn from(result: GetBlockResult) -> Self {
33 result.0
34 }
35}
36
37#[cfg(all(feature = "js", target_arch = "wasm32"))]
38impl From<_GetBlockResult> for GetBlockResult {
39 fn from(result: _GetBlockResult) -> Self {
40 GetBlockResult(result)
41 }
42}
43#[cfg(all(feature = "js", target_arch = "wasm32"))]
44#[cfg_attr(feature = "js", wasm_bindgen)]
45impl GetBlockResult {
46 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
48 #[cfg(feature = "js")]
49 pub fn api_version(&self) -> JsValue {
50 JsValue::from_serde(&self.0.api_version).unwrap()
51 }
52
53 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
55 #[cfg(feature = "js")]
56 pub fn block(&self) -> JsValue {
57 let block = self.0.block_with_signatures.clone().unwrap().block;
58
59 match block {
60 Block::V1(block_v1) => JsValue::from_serde(&block_v1).unwrap(),
61 Block::V2(block_v2) => JsValue::from_serde(&block_v2).unwrap(),
62 }
63 }
64
65 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toJson"))]
67 #[cfg(feature = "js")]
68 pub fn to_json(&self) -> JsValue {
69 JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
70 }
71}
72
73#[derive(Debug, Deserialize, Default, Serialize)]
75#[cfg(all(feature = "js", target_arch = "wasm32"))]
76#[cfg_attr(
77 feature = "js",
78 wasm_bindgen(js_name = "getBlockOptions", getter_with_clone)
79)]
80pub struct GetBlockOptions {
81 pub maybe_block_id_as_string: Option<String>,
82 pub maybe_block_identifier: Option<BlockIdentifier>,
83 pub rpc_address: Option<String>,
84 pub verbosity: Option<Verbosity>,
85}
86
87#[cfg(all(feature = "js", target_arch = "wasm32"))]
88#[cfg_attr(feature = "js", wasm_bindgen)]
89impl SDK {
90 #[cfg(feature = "js")]
100 pub fn get_block_options(&self, options: JsValue) -> Result<GetBlockOptions, JsError> {
101 options
102 .into_serde::<GetBlockOptions>()
103 .map_err(|err| JsError::new(&format!("Error deserializing options: {err:?}")))
104 }
105
106 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "get_block"))]
120 #[cfg(feature = "js")]
121 pub async fn get_block_js_alias(
122 &self,
123 options: Option<GetBlockOptions>,
124 ) -> Result<GetBlockResult, JsError> {
125 let GetBlockOptions {
126 maybe_block_id_as_string,
127 maybe_block_identifier,
128 verbosity,
129 rpc_address,
130 } = options.unwrap_or_default();
131
132 let maybe_block_identifier = if let Some(maybe_block_identifier) = maybe_block_identifier {
133 Some(BlockIdentifierInput::BlockIdentifier(
134 maybe_block_identifier,
135 ))
136 } else {
137 maybe_block_id_as_string.map(BlockIdentifierInput::String)
138 };
139
140 let result = self
141 .get_block(maybe_block_identifier, verbosity, rpc_address)
142 .await;
143 match result {
144 Ok(data) => Ok(data.result.into()),
145 Err(err) => {
146 let err = &format!("Error occurred with {err:?}");
147 Err(JsError::new(err))
148 }
149 }
150 }
151
152 #[deprecated(note = "This function is an alias. Please use `get_block` instead.")]
166 #[allow(deprecated)]
167 #[cfg(feature = "js")]
168 pub async fn chain_get_block(
169 &self,
170 options: Option<GetBlockOptions>,
171 ) -> Result<GetBlockResult, JsError> {
172 self.get_block_js_alias(options).await
173 }
174}
175
176impl SDK {
177 pub async fn get_block(
193 &self,
194 maybe_block_identifier: Option<BlockIdentifierInput>,
195 verbosity: Option<Verbosity>,
196 rpc_address: Option<String>,
197 ) -> Result<SuccessResponse<_GetBlockResult>, SdkError> {
198 let random_id = rand::rng().random::<u64>().to_string();
200 if let Some(BlockIdentifierInput::String(maybe_block_id)) = maybe_block_identifier {
201 get_block_cli(
202 &random_id,
203 &self.get_rpc_address(rpc_address),
204 self.get_verbosity(verbosity).into(),
205 &maybe_block_id,
206 )
207 .await
208 .map_err(SdkError::from)
209 } else {
210 let maybe_block_identifier =
211 if let Some(BlockIdentifierInput::BlockIdentifier(maybe_block_identifier)) =
212 maybe_block_identifier
213 {
214 Some(maybe_block_identifier)
215 } else {
216 None
217 };
218 get_block_lib(
219 JsonRpcId::from(random_id),
220 &self.get_rpc_address(rpc_address),
221 self.get_verbosity(verbosity).into(),
222 maybe_block_identifier.map(Into::into),
223 )
224 .await
225 .map_err(SdkError::from)
226 }
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233 use crate::types::{
234 hash::block_hash::BlockHash, identifier::block_identifier::BlockIdentifier,
235 };
236 use sdk_tests::tests::helpers::get_network_constants;
237
238 #[tokio::test]
239 async fn test_get_block_with_none_values() {
240 let sdk = SDK::new(None, None, None);
242 let error_message = "failed to parse node address as valid URL";
243
244 let result = sdk.get_block(None, None, None).await;
246
247 assert!(result.is_err());
249 let err_string = result.err().unwrap().to_string();
250 assert!(err_string.contains(error_message));
251 }
252
253 #[tokio::test]
254 async fn test_get_block_with_block_id_string() {
255 let sdk = SDK::new(None, None, None);
257 let verbosity = Some(Verbosity::High);
258 let (rpc_address, _, _, _, _) = get_network_constants();
259 let result = sdk
260 .get_block(None, verbosity, Some(rpc_address.clone()))
261 .await;
262 let block_hash = BlockHash::from(
263 *result
264 .unwrap()
265 .result
266 .block_with_signatures
267 .unwrap()
268 .block
269 .hash(),
270 )
271 .to_string();
272 let block_identifier = BlockIdentifierInput::String(block_hash.to_string());
273
274 let result = sdk
276 .get_block(Some(block_identifier), verbosity, Some(rpc_address))
277 .await;
278
279 assert!(result.is_ok());
281 }
282
283 #[tokio::test]
284 async fn test_get_block_with_block_identifier() {
285 let sdk = SDK::new(None, None, None);
287 let block_identifier =
288 BlockIdentifierInput::BlockIdentifier(BlockIdentifier::from_height(1));
289 let verbosity = Some(Verbosity::High);
290 let (rpc_address, _, _, _, _) = get_network_constants();
291
292 let result = sdk
294 .get_block(Some(block_identifier), verbosity, Some(rpc_address))
295 .await;
296 assert!(result.is_ok());
298 }
299
300 #[tokio::test]
301 async fn test_get_block_with_error() {
302 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
303
304 let error_message = "error sending request";
305
306 let result = sdk.get_block(None, None, None).await;
308
309 assert!(result.is_err());
311 let err_string = result.err().unwrap().to_string();
312 assert!(err_string.contains(error_message));
313 }
314}