Skip to main content

rings_node/extension/
mod.rs

1#![warn(missing_docs)]
2//! This module provide basic mechanism.
3
4pub mod ext;
5pub mod protocols;
6#[cfg(feature = "snark")]
7pub mod snark;
8pub mod transport;
9pub mod types;
10use std::result::Result;
11use std::sync::Arc;
12
13use async_trait::async_trait;
14use rings_core::message::CustomMessage;
15use rings_core::message::Message;
16use rings_core::message::MessagePayload;
17use rings_core::message::MessageVerificationExt;
18use rings_core::swarm::callback::SwarmCallback;
19
20use crate::extension::ext::Envelope;
21use crate::extension::ext::Extensions;
22use crate::provider::Provider;
23
24/// Backend handles inbound custom messages from the Swarm, routing each decoded
25/// [`Envelope`] to its namespace's protocol via the [`Extensions`] registry. The
26/// registry is shared with the [`Provider`], so protocols registered there are visible
27/// to inbound dispatch here. Each protocol's interpreter does its IO through a
28/// namespace-scoped [`Scope`](ext::Scope); the underlying router capability is internal.
29pub struct Backend {
30    extensions: Extensions,
31}
32
33impl Backend {
34    /// Create a new backend over a provider, sharing its protocol registry.
35    pub fn new(provider: Arc<Provider>) -> Self {
36        Self {
37            extensions: provider.extensions(),
38        }
39    }
40}
41
42#[cfg_attr(feature = "browser", async_trait(?Send))]
43#[cfg_attr(not(feature = "browser"), async_trait)]
44impl SwarmCallback for Backend {
45    async fn on_inbound(&self, payload: &MessagePayload) -> Result<(), Box<dyn std::error::Error>> {
46        let data: Message = payload.transaction.data()?;
47
48        let Message::CustomMessage(CustomMessage(msg)) = data else {
49            return Ok(());
50        };
51
52        let envelope = Envelope::decode(&msg)?;
53        let from = payload.transaction.signer();
54        self.extensions.dispatch(from, envelope).await?;
55
56        Ok(())
57    }
58}