casper_rust_wasm_sdk/sdk/rpcs/
get_block.rs1#[cfg(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(target_arch = "wasm32")]
15use casper_types::Block;
16#[cfg(target_arch = "wasm32")]
17use gloo_utils::format::JsValueSerdeExt;
18use rand::Rng;
19#[cfg(target_arch = "wasm32")]
20use serde::{Deserialize, Serialize};
21#[cfg(target_arch = "wasm32")]
22use wasm_bindgen::prelude::*;
23
24#[cfg(target_arch = "wasm32")]
26#[derive(Debug, Deserialize, Serialize)]
27#[wasm_bindgen]
28pub struct GetBlockResult(_GetBlockResult);
29
30#[cfg(target_arch = "wasm32")]
31impl From<GetBlockResult> for _GetBlockResult {
32 fn from(result: GetBlockResult) -> Self {
33 result.0
34 }
35}
36
37#[cfg(target_arch = "wasm32")]
38impl From<_GetBlockResult> for GetBlockResult {
39 fn from(result: _GetBlockResult) -> Self {
40 GetBlockResult(result)
41 }
42}
43#[cfg(target_arch = "wasm32")]
44#[wasm_bindgen]
45impl GetBlockResult {
46 #[wasm_bindgen(getter)]
48 pub fn api_version(&self) -> JsValue {
49 JsValue::from_serde(&self.0.api_version).unwrap()
50 }
51
52 #[wasm_bindgen(getter)]
54 pub fn block(&self) -> JsValue {
55 let block = self.0.block_with_signatures.clone().unwrap().block;
56
57 match block {
58 Block::V1(block_v1) => JsValue::from_serde(&block_v1).unwrap(),
59 Block::V2(block_v2) => JsValue::from_serde(&block_v2).unwrap(),
60 }
61 }
62
63 #[wasm_bindgen(js_name = "toJson")]
65 pub fn to_json(&self) -> JsValue {
66 JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
67 }
68}
69
70#[derive(Debug, Deserialize, Default, Serialize)]
72#[cfg(target_arch = "wasm32")]
73#[wasm_bindgen(js_name = "getBlockOptions", getter_with_clone)]
74pub struct GetBlockOptions {
75 pub maybe_block_id_as_string: Option<String>,
76 pub maybe_block_identifier: Option<BlockIdentifier>,
77 pub rpc_address: Option<String>,
78 pub verbosity: Option<Verbosity>,
79}
80
81#[cfg(target_arch = "wasm32")]
82#[wasm_bindgen]
83impl SDK {
84 pub fn get_block_options(&self, options: JsValue) -> Result<GetBlockOptions, JsError> {
94 options
95 .into_serde::<GetBlockOptions>()
96 .map_err(|err| JsError::new(&format!("Error deserializing options: {:?}", err)))
97 }
98
99 #[wasm_bindgen(js_name = "get_block")]
113 pub async fn get_block_js_alias(
114 &self,
115 options: Option<GetBlockOptions>,
116 ) -> Result<GetBlockResult, JsError> {
117 let GetBlockOptions {
118 maybe_block_id_as_string,
119 maybe_block_identifier,
120 verbosity,
121 rpc_address,
122 } = options.unwrap_or_default();
123
124 let maybe_block_identifier = if let Some(maybe_block_identifier) = maybe_block_identifier {
125 Some(BlockIdentifierInput::BlockIdentifier(
126 maybe_block_identifier,
127 ))
128 } else {
129 maybe_block_id_as_string.map(BlockIdentifierInput::String)
130 };
131
132 let result = self
133 .get_block(maybe_block_identifier, verbosity, rpc_address)
134 .await;
135 match result {
136 Ok(data) => Ok(data.result.into()),
137 Err(err) => {
138 let err = &format!("Error occurred with {:?}", err);
139 Err(JsError::new(err))
140 }
141 }
142 }
143
144 #[deprecated(note = "This function is an alias. Please use `get_block` instead.")]
158 #[allow(deprecated)]
159 pub async fn chain_get_block(
160 &self,
161 options: Option<GetBlockOptions>,
162 ) -> Result<GetBlockResult, JsError> {
163 self.get_block_js_alias(options).await
164 }
165}
166
167impl SDK {
168 pub async fn get_block(
184 &self,
185 maybe_block_identifier: Option<BlockIdentifierInput>,
186 verbosity: Option<Verbosity>,
187 rpc_address: Option<String>,
188 ) -> Result<SuccessResponse<_GetBlockResult>, SdkError> {
189 if let Some(BlockIdentifierInput::String(maybe_block_id)) = maybe_block_identifier {
192 get_block_cli(
193 &rand::thread_rng().gen::<u64>().to_string(),
194 &self.get_rpc_address(rpc_address),
195 self.get_verbosity(verbosity).into(),
196 &maybe_block_id,
197 )
198 .await
199 .map_err(SdkError::from)
200 } else {
201 let maybe_block_identifier =
202 if let Some(BlockIdentifierInput::BlockIdentifier(maybe_block_identifier)) =
203 maybe_block_identifier
204 {
205 Some(maybe_block_identifier)
206 } else {
207 None
208 };
209 get_block_lib(
210 JsonRpcId::from(rand::thread_rng().gen::<u64>().to_string()),
211 &self.get_rpc_address(rpc_address),
212 self.get_verbosity(verbosity).into(),
213 maybe_block_identifier.map(Into::into),
214 )
215 .await
216 .map_err(SdkError::from)
217 }
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224 use crate::types::{
225 hash::block_hash::BlockHash, identifier::block_identifier::BlockIdentifier,
226 };
227 use sdk_tests::tests::helpers::get_network_constants;
228
229 #[tokio::test]
230 async fn test_get_block_with_none_values() {
231 let sdk = SDK::new(None, None, None);
233 let error_message = "failed to parse node address as valid URL";
234
235 let result = sdk.get_block(None, None, None).await;
237
238 assert!(result.is_err());
240 let err_string = result.err().unwrap().to_string();
241 assert!(err_string.contains(error_message));
242 }
243
244 #[tokio::test]
245 async fn test_get_block_with_block_id_string() {
246 let sdk = SDK::new(None, None, None);
248 let verbosity = Some(Verbosity::High);
249 let (rpc_address, _, _, _, _) = get_network_constants();
250 let result = sdk
251 .get_block(None, verbosity, Some(rpc_address.clone()))
252 .await;
253 let block_hash = BlockHash::from(
254 *result
255 .unwrap()
256 .result
257 .block_with_signatures
258 .unwrap()
259 .block
260 .hash(),
261 )
262 .to_string();
263 let block_identifier = BlockIdentifierInput::String(block_hash.to_string());
264
265 let result = sdk
267 .get_block(Some(block_identifier), verbosity, Some(rpc_address))
268 .await;
269
270 assert!(result.is_ok());
272 }
273
274 #[tokio::test]
275 async fn test_get_block_with_block_identifier() {
276 let sdk = SDK::new(None, None, None);
278 let block_identifier =
279 BlockIdentifierInput::BlockIdentifier(BlockIdentifier::from_height(1));
280 let verbosity = Some(Verbosity::High);
281 let (rpc_address, _, _, _, _) = get_network_constants();
282
283 let result = sdk
285 .get_block(Some(block_identifier), verbosity, Some(rpc_address))
286 .await;
287 assert!(result.is_ok());
289 }
290
291 #[tokio::test]
292 async fn test_get_block_with_error() {
293 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
294
295 let error_message = "error sending request for url (http://localhost/rpc)";
296
297 let result = sdk.get_block(None, None, None).await;
299
300 assert!(result.is_err());
302 let err_string = result.err().unwrap().to_string();
303 assert!(err_string.contains(error_message));
304 }
305}