Skip to content

Commit 7e9e741

Browse files
committed
feat: implement CardanoStakeDistribution features exposed by mithril-client crate in the WASM library
1 parent 5f54920 commit 7e9e741

File tree

2 files changed

+171
-2
lines changed

2 files changed

+171
-2
lines changed

mithril-client-wasm/src/client_wasm.rs

+167-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::Arc;
44
use wasm_bindgen::prelude::*;
55

66
use mithril_client::{
7+
common::Epoch,
78
feedback::{FeedbackReceiver, MithrilEvent},
89
CardanoTransactionsProofs, Client, ClientBuilder, MessageBuilder, MithrilCertificate,
910
};
@@ -292,6 +293,70 @@ impl MithrilUnstableClient {
292293

293294
Ok(serde_wasm_bindgen::to_value(&result)?)
294295
}
296+
297+
/// Call the client to get a cardano stake distribution from a hash
298+
#[wasm_bindgen]
299+
pub async fn get_cardano_stake_distribution(&self, hash: &str) -> WasmResult {
300+
let result = self
301+
.client
302+
.cardano_stake_distribution()
303+
.get(hash)
304+
.await
305+
.map_err(|err| format!("{err:?}"))?
306+
.ok_or(JsValue::from_str(&format!(
307+
"No cardano stake distribution found for hash: '{hash}'"
308+
)))?;
309+
310+
Ok(serde_wasm_bindgen::to_value(&result)?)
311+
}
312+
313+
/// Call the client to get a cardano stake distribution from an epoch
314+
/// The epoch represents the epoch at the end of which the Cardano stake distribution is computed by the Cardano node
315+
#[wasm_bindgen]
316+
pub async fn get_cardano_stake_distribution_by_epoch(&self, epoch: Epoch) -> WasmResult {
317+
let result = self
318+
.client
319+
.cardano_stake_distribution()
320+
.get_by_epoch(epoch)
321+
.await
322+
.map_err(|err| format!("{err:?}"))?
323+
.ok_or(JsValue::from_str(&format!(
324+
"No cardano stake distribution found for epoch: '{epoch}'"
325+
)))?;
326+
327+
Ok(serde_wasm_bindgen::to_value(&result)?)
328+
}
329+
330+
/// Call the client for the list of available cardano stake distributions
331+
#[wasm_bindgen]
332+
pub async fn list_cardano_stake_distributions(&self) -> WasmResult {
333+
let result = self
334+
.client
335+
.cardano_stake_distribution()
336+
.list()
337+
.await
338+
.map_err(|err| format!("{err:?}"))?;
339+
340+
Ok(serde_wasm_bindgen::to_value(&result)?)
341+
}
342+
343+
/// Call the client to compute a cardano stake distribution message
344+
#[wasm_bindgen]
345+
pub async fn compute_cardano_stake_distribution_message(
346+
&self,
347+
certificate: JsValue,
348+
cardano_stake_distribution: JsValue,
349+
) -> WasmResult {
350+
let certificate =
351+
serde_wasm_bindgen::from_value(certificate).map_err(|err| format!("{err:?}"))?;
352+
let cardano_stake_distribution = serde_wasm_bindgen::from_value(cardano_stake_distribution)
353+
.map_err(|err| format!("{err:?}"))?;
354+
let result = MessageBuilder::new()
355+
.compute_cardano_stake_distribution_message(&certificate, &cardano_stake_distribution)
356+
.map_err(|err| format!("{err:?}"))?;
357+
358+
Ok(serde_wasm_bindgen::to_value(&result)?)
359+
}
295360
}
296361

297362
#[cfg(test)]
@@ -301,8 +366,9 @@ mod tests {
301366
use wasm_bindgen_test::*;
302367

303368
use mithril_client::{
304-
common::ProtocolMessage, CardanoTransactionSnapshot, MithrilCertificateListItem,
305-
MithrilStakeDistribution, MithrilStakeDistributionListItem, Snapshot, SnapshotListItem,
369+
common::ProtocolMessage, CardanoStakeDistribution, CardanoStakeDistributionListItem,
370+
CardanoTransactionSnapshot, MithrilCertificateListItem, MithrilStakeDistribution,
371+
MithrilStakeDistributionListItem, Snapshot, SnapshotListItem,
306372
};
307373

308374
const GENESIS_VERIFICATION_KEY: &str = "5b33322c3235332c3138362c3230312c3137372c31312c3131372c3133352c3138372c3136372c3138312c3138382c32322c35392c3230362c3130352c3233312c3135302c3231352c33302c37382c3231322c37362c31362c3235322c3138302c37322c3133342c3133372c3234372c3136312c36385d";
@@ -556,4 +622,103 @@ mod tests {
556622
.await
557623
.expect("Compute tx proof message for matching cert failed");
558624
}
625+
626+
#[wasm_bindgen_test]
627+
async fn list_cardano_stake_distributions_should_return_value_convertible_in_rust_type() {
628+
let csd_list_js_value = get_mithril_client()
629+
.unstable
630+
.list_cardano_stake_distributions()
631+
.await
632+
.expect("cardano_mithril_stake_distributions should not fail");
633+
let csd_list = serde_wasm_bindgen::from_value::<Vec<CardanoStakeDistributionListItem>>(
634+
csd_list_js_value,
635+
)
636+
.expect("conversion should not fail");
637+
638+
assert_eq!(
639+
csd_list.len(),
640+
// Aggregator return up to 20 items for a list route
641+
test_data::csd_hashes().len().min(20)
642+
);
643+
}
644+
645+
#[wasm_bindgen_test]
646+
async fn get_cardano_stake_distribution_should_return_value_convertible_in_rust_type() {
647+
let csd_js_value = get_mithril_client()
648+
.unstable
649+
.get_cardano_stake_distribution(test_data::csd_hashes()[0])
650+
.await
651+
.expect("get_cardano_stake_distribution should not fail");
652+
let csd = serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_js_value)
653+
.expect("conversion should not fail");
654+
655+
assert_eq!(csd.hash, test_data::csd_hashes()[0]);
656+
}
657+
658+
#[wasm_bindgen_test]
659+
async fn get_cardano_stake_distribution_should_fail_with_unknown_hash() {
660+
get_mithril_client()
661+
.unstable
662+
.get_cardano_stake_distribution("whatever")
663+
.await
664+
.expect_err("get_cardano_stake_distribution should fail");
665+
}
666+
667+
#[wasm_bindgen_test]
668+
async fn get_cardano_stake_distribution_by_epoch_should_return_value_convertible_in_rust_type()
669+
{
670+
let csd_reference_js_value = get_mithril_client()
671+
.unstable
672+
.get_cardano_stake_distribution(test_data::csd_hashes()[0])
673+
.await
674+
.unwrap();
675+
let csd_reference =
676+
serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_reference_js_value)
677+
.unwrap();
678+
679+
let csd_js_value = get_mithril_client()
680+
.unstable
681+
.get_cardano_stake_distribution_by_epoch(csd_reference.epoch)
682+
.await
683+
.expect("get_cardano_stake_distribution_by_epoch should not fail");
684+
685+
let csd = serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_js_value)
686+
.expect("conversion should not fail");
687+
688+
assert_eq!(csd.hash, test_data::csd_hashes()[0]);
689+
}
690+
691+
#[wasm_bindgen_test]
692+
async fn get_cardano_stake_distribution_by_epoch_should_fail_with_unknown_epoch() {
693+
get_mithril_client()
694+
.unstable
695+
.get_cardano_stake_distribution_by_epoch(Epoch(u64::MAX))
696+
.await
697+
.expect_err("get_cardano_stake_distribution_by_epoch should fail");
698+
}
699+
700+
#[wasm_bindgen_test]
701+
async fn compute_cardano_stake_distribution_message_should_return_value_convertible_in_rust_type(
702+
) {
703+
let client = get_mithril_client();
704+
let csd_js_value = client
705+
.unstable
706+
.get_cardano_stake_distribution(test_data::csd_hashes()[0])
707+
.await
708+
.unwrap();
709+
let csd = serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_js_value.clone())
710+
.unwrap();
711+
let certificate_js_value = client
712+
.get_mithril_certificate(&csd.certificate_hash)
713+
.await
714+
.unwrap();
715+
716+
let message_js_value = client
717+
.unstable
718+
.compute_cardano_stake_distribution_message(certificate_js_value, csd_js_value)
719+
.await
720+
.expect("compute_cardano_stake_distribution_message should not fail");
721+
serde_wasm_bindgen::from_value::<ProtocolMessage>(message_js_value)
722+
.expect("conversion should not fail");
723+
}
559724
}

mithril-common/src/entities/epoch.rs

+4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ use crate::entities::arithmetic_operation_wrapper::{
1010
};
1111
use crate::signable_builder::Beacon as SignableBeacon;
1212

13+
#[cfg(target_family = "wasm")]
14+
use wasm_bindgen::prelude::*;
15+
1316
/// Epoch represents a Cardano epoch
1417
#[derive(
1518
Debug, Copy, Clone, Default, PartialEq, Serialize, Deserialize, Hash, Eq, PartialOrd, Ord,
1619
)]
20+
#[cfg_attr(target_family = "wasm", wasm_bindgen(js_name = "Epoch"))]
1721
pub struct Epoch(pub u64);
1822

1923
impl Epoch {

0 commit comments

Comments
 (0)