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}