casper_rust_wasm_sdk/sdk/rpcs/
get_reward.rs1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::types::identifier::block_identifier::BlockIdentifier;
3use crate::{
4 types::{public_key::PublicKey, sdk_error::SdkError, verbosity::Verbosity},
5 SDK,
6};
7use casper_client::{
8 cli::get_reward as get_reward_cli, get_reward as get_reward_lib,
9 rpcs::results::GetRewardResult as _GetRewardResult, rpcs::EraIdentifier, JsonRpcId,
10 SuccessResponse,
11};
12#[cfg(all(feature = "js", target_arch = "wasm32"))]
13use casper_types::EraId;
14#[cfg(all(feature = "js", target_arch = "wasm32"))]
15use gloo_utils::format::JsValueSerdeExt;
16use rand::RngExt;
17#[cfg(all(feature = "js", target_arch = "wasm32"))]
18use serde::{Deserialize, Serialize};
19#[cfg(all(feature = "js", target_arch = "wasm32"))]
20use wasm_bindgen::prelude::*;
21
22#[cfg(all(feature = "js", target_arch = "wasm32"))]
24#[derive(Debug, Deserialize, Serialize)]
25#[cfg_attr(feature = "js", wasm_bindgen)]
26pub struct GetRewardResult(_GetRewardResult);
27
28#[cfg(all(feature = "js", target_arch = "wasm32"))]
29impl From<GetRewardResult> for _GetRewardResult {
30 fn from(result: GetRewardResult) -> Self {
31 result.0
32 }
33}
34
35#[cfg(all(feature = "js", target_arch = "wasm32"))]
36impl From<_GetRewardResult> for GetRewardResult {
37 fn from(result: _GetRewardResult) -> Self {
38 GetRewardResult(result)
39 }
40}
41
42#[cfg(all(feature = "js", target_arch = "wasm32"))]
43#[cfg_attr(feature = "js", wasm_bindgen)]
44impl GetRewardResult {
45 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
47 #[cfg(feature = "js")]
48 pub fn api_version(&self) -> JsValue {
49 JsValue::from_serde(&self.0.api_version).unwrap()
50 }
51
52 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
54 #[cfg(feature = "js")]
55 pub fn reward_amount(&self) -> JsValue {
56 JsValue::from_serde(&self.0.reward_amount).unwrap()
57 }
58
59 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
61 #[cfg(feature = "js")]
62 pub fn era_id(&self) -> JsValue {
63 JsValue::from_serde(&self.0.era_id).unwrap()
64 }
65
66 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
68 pub fn delegation_rate(&self) -> u8 {
69 self.0.delegation_rate
70 }
71
72 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
74 #[cfg(feature = "js")]
75 pub fn switch_block_hash(&self) -> JsValue {
76 JsValue::from_serde(&self.0.switch_block_hash).unwrap()
77 }
78
79 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toJson"))]
81 #[cfg(feature = "js")]
82 pub fn to_json(&self) -> JsValue {
83 JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
84 }
85}
86
87#[derive(Debug, Deserialize, Clone, Default, Serialize)]
89#[cfg(all(feature = "js", target_arch = "wasm32"))]
90#[cfg_attr(
91 feature = "js",
92 wasm_bindgen(js_name = "getRewardOptions", getter_with_clone)
93)]
94pub struct GetRewardOptions {
95 pub validator_public_key: Option<PublicKey>,
96 pub validator_public_key_as_string: Option<String>,
97 pub delegator_public_key: Option<PublicKey>,
98 pub delegator_public_key_as_string: Option<String>,
99 pub maybe_era_id: Option<u64>,
100 pub maybe_era_id_as_string: Option<String>,
101 pub maybe_block_identifier: Option<BlockIdentifier>,
102 pub rpc_address: Option<String>,
103 pub verbosity: Option<Verbosity>,
104}
105
106#[cfg(all(feature = "js", target_arch = "wasm32"))]
107#[cfg_attr(feature = "js", wasm_bindgen)]
108impl SDK {
109 #[cfg(feature = "js")]
111 pub fn get_reward_options(&self, options: JsValue) -> Result<GetRewardOptions, JsError> {
112 options
113 .into_serde::<GetRewardOptions>()
114 .map_err(|err| JsError::new(&format!("Error deserializing options: {err:?}")))
115 }
116
117 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "get_reward"))]
119 #[cfg(feature = "js")]
120 pub async fn get_reward_js_alias(
121 &self,
122 options: Option<GetRewardOptions>,
123 ) -> Result<GetRewardResult, JsError> {
124 let GetRewardOptions {
125 validator_public_key,
126 validator_public_key_as_string,
127 delegator_public_key,
128 delegator_public_key_as_string,
129 maybe_era_id,
130 maybe_era_id_as_string,
131 maybe_block_identifier,
132 verbosity,
133 rpc_address,
134 } = options.unwrap_or_default();
135
136 let validator = if let Some(pk) = validator_public_key {
137 pk
138 } else if let Some(hex) = validator_public_key_as_string {
139 PublicKey::new(&hex).map_err(|err| JsError::new(&format!("{err:?}")))?
140 } else {
141 return Err(JsError::new(
142 "validator_public_key or validator_public_key_as_string is required",
143 ));
144 };
145
146 let delegator = if let Some(pk) = delegator_public_key {
147 Some(pk)
148 } else if let Some(hex) = delegator_public_key_as_string {
149 Some(PublicKey::new(&hex).map_err(|err| JsError::new(&format!("{err:?}")))?)
150 } else {
151 None
152 };
153
154 let maybe_era_identifier = if let Some(era_id) = maybe_era_id {
155 Some(EraIdentifier::Era(EraId::new(era_id)))
156 } else if let Some(era_str) = maybe_era_id_as_string {
157 if era_str.is_empty() {
158 None
159 } else {
160 let era_id: u64 = era_str
161 .parse()
162 .map_err(|err| JsError::new(&format!("Invalid era id: {err:?}")))?;
163 Some(EraIdentifier::Era(EraId::new(era_id)))
164 }
165 } else {
166 maybe_block_identifier.map(|block| EraIdentifier::Block(block.into()))
167 };
168
169 let result = self
170 .get_reward(
171 validator,
172 delegator,
173 maybe_era_identifier,
174 verbosity,
175 rpc_address,
176 )
177 .await;
178 match result {
179 Ok(data) => Ok(data.result.into()),
180 Err(err) => {
181 let err = &format!("Error occurred with {err:?}");
182 Err(JsError::new(err))
183 }
184 }
185 }
186
187 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "info_get_reward"))]
189 #[deprecated(note = "This function is an alias. Please use `get_reward` instead.")]
190 #[allow(deprecated)]
191 #[cfg(feature = "js")]
192 pub async fn info_get_reward(
193 &self,
194 options: Option<GetRewardOptions>,
195 ) -> Result<GetRewardResult, JsError> {
196 self.get_reward_js_alias(options).await
197 }
198}
199
200impl SDK {
201 pub async fn get_reward(
211 &self,
212 validator: PublicKey,
213 maybe_delegator: Option<PublicKey>,
214 maybe_era_identifier: Option<EraIdentifier>,
215 verbosity: Option<Verbosity>,
216 rpc_address: Option<String>,
217 ) -> Result<SuccessResponse<_GetRewardResult>, SdkError> {
218 let random_id = rand::rng().random::<u64>().to_string();
219 get_reward_lib(
220 JsonRpcId::from(random_id),
221 &self.get_rpc_address(rpc_address),
222 self.get_verbosity(verbosity).into(),
223 maybe_era_identifier,
224 validator.into(),
225 maybe_delegator.map(Into::into),
226 )
227 .await
228 .map_err(SdkError::from)
229 }
230
231 pub async fn get_reward_as_string(
233 &self,
234 validator: &str,
235 maybe_delegator: Option<&str>,
236 maybe_era_id: Option<&str>,
237 verbosity: Option<Verbosity>,
238 rpc_address: Option<String>,
239 ) -> Result<SuccessResponse<_GetRewardResult>, SdkError> {
240 let random_id = rand::rng().random::<u64>().to_string();
241 get_reward_cli(
242 &random_id,
243 &self.get_rpc_address(rpc_address),
244 self.get_verbosity(verbosity).into(),
245 maybe_era_id.unwrap_or(""),
246 validator,
247 maybe_delegator.unwrap_or(""),
248 )
249 .await
250 .map_err(SdkError::from)
251 }
252}
253
254#[cfg(test)]
255mod tests {
256 use super::*;
257
258 #[tokio::test]
259 async fn test_get_reward_with_none_rpc_address() {
260 let sdk = SDK::new(None, None, None);
261 let error_message = "failed to parse node address as valid URL";
262 let result = sdk
263 .get_reward_as_string(
264 "01aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
265 None,
266 None,
267 None,
268 None,
269 )
270 .await;
271 assert!(result.is_err());
272 let err_string = result.err().unwrap().to_string();
273 assert!(
274 err_string.contains(error_message)
275 || err_string.contains("Failed")
276 || err_string.contains("parse")
277 || err_string.contains("PublicKey")
278 || err_string.contains("Validator")
279 );
280 }
281
282 #[tokio::test]
283 async fn test_get_reward_with_error() {
284 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
285 let result = sdk
286 .get_reward_as_string(
287 "01aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
288 None,
289 None,
290 None,
291 None,
292 )
293 .await;
294 assert!(result.is_err());
295 }
296}