delta_base_sdk/events.rs
1//! # Base Layer Events
2//!
3//! This module provides types and utilities for working with events emitted by
4//! the base layer. The events notify clients (e.g. domains) about important
5//! state changes in the network, such as epoch transitions and vault
6//! migrations.
7//!
8//! Events are typically received through a subscription stream established via
9//! the [`BaseRpcClient`](crate::rpc::BaseRpcClient).
10
11use crate::sdl::SdlUpdate;
12use primitives::{
13 type_aliases::Epoch,
14 vault::Address,
15};
16use proto_types::{
17 error::{
18 MissingDataSnafu,
19 ProtoError,
20 },
21 events::Event,
22};
23use snafu::OptionExt;
24
25/// Event emitted by the base layer to notify clients of state changes
26///
27/// Base layer events are used to communicate important state changes to clients
28/// (e.g. domains). They are streamed from the base layer via RPC and allow
29/// clients to react to changes in the network.
30///
31/// ## Example
32///
33/// ```no_run
34/// use delta_base_sdk::{events::BaseLayerEvent, rpc::BaseRpcClient};
35/// # use tokio_stream::StreamExt;
36///
37/// async fn handle_events() -> Result<(), Box<dyn std::error::Error>> {
38/// let client = BaseRpcClient::new("http://localhost:50051").await?;
39/// let shard_id = 1;
40///
41/// // Subscribe to events for a specific shard
42/// let mut event_stream = client.stream_base_layer_events(shard_id).await?;
43///
44/// // Process events as they arrive
45/// while let Some(event_result) = event_stream.next().await {
46/// match event_result {
47/// Ok(event) => match event {
48/// BaseLayerEvent::NewEpoch(epoch) => {
49/// println!("New epoch started: {}", epoch);
50/// },
51/// BaseLayerEvent::SdlUpdate(update) => {
52/// println!("SDL update received: {:?}", update.hash);
53/// },
54/// BaseLayerEvent::VaultEmigrated(address) => {
55/// println!("Vault emigrated: {address}");
56/// },
57/// BaseLayerEvent::VaultImmigrated(address) => {
58/// println!("Vault immigrated: {address}");
59/// },
60/// },
61/// Err(e) => eprintln!("Error receiving event: {e}"),
62/// }
63/// }
64/// Ok(())
65/// }
66/// ```
67#[derive(Debug, Clone, Copy)]
68pub enum BaseLayerEvent {
69 /// A new epoch has started in the network
70 ///
71 /// This event is emitted when the network transitions to a new epoch.
72 NewEpoch(Epoch),
73
74 /// Update on a [StateDiffList](crate::sdl::StateDiffList) status
75 ///
76 /// Notification about a SDL's status change, including acceptance or
77 /// rejection. This event can also be received when another domain submits
78 /// an SDL crediting our shard.
79 SdlUpdate(SdlUpdate),
80
81 /// A vault has migrated away from the subscribed domain
82 ///
83 /// This event indicates that the vault with the specified [Address] is now
84 /// emigrated and registered with another domain.
85 VaultEmigrated(Address),
86
87 /// A vault has migrated into the subscribed domain
88 ///
89 /// This event indicates that the vault with the specified [Address] is now
90 /// immigrated and registered with this domain.
91 VaultImmigrated(Address),
92}
93
94impl TryFrom<proto_types::events::BaseLayerEvent> for BaseLayerEvent {
95 type Error = ProtoError;
96
97 fn try_from(value: proto_types::events::BaseLayerEvent) -> Result<Self, Self::Error> {
98 match value.event.context(MissingDataSnafu { field: "event" })? {
99 Event::SdlUpdate(sdl_update) => Ok(Self::SdlUpdate(sdl_update.try_into()?)),
100 Event::Epoch(epoch) => Ok(Self::NewEpoch(epoch)),
101 Event::VaultEmigrated(address) => Ok(Self::VaultEmigrated(address.try_into()?)),
102 Event::VaultImmigrated(address) => Ok(Self::VaultImmigrated(address.try_into()?)),
103 }
104 }
105}