#[cfg(feature = "native-crypto")]
pub mod ble;
#[cfg(feature = "native-crypto")]
pub mod nostr;
#[cfg(feature = "native-crypto")]
pub mod qssh;
#[cfg(feature = "native-crypto")]
pub mod onchain;
use crate::{Error, Result};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransportMessage {
pub id: String,
pub from: String,
pub to: String,
pub payload: Vec<u8>,
pub timestamp: u64,
pub metadata: MessageMetadata,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MessageMetadata {
Ble {
hop_count: u8,
ttl: u8,
},
Nostr {
event_id: String,
relay: String,
},
Qssh {
session_id: String,
},
OnChain {
block_hash: String,
tx_index: u32,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransportCapability {
Send,
Receive,
Persistence,
OfflineDelivery,
GroupChannel,
PostQuantum,
}
#[async_trait]
pub trait Transport: Send + Sync {
fn name(&self) -> &str;
fn capabilities(&self) -> Vec<TransportCapability>;
async fn is_connected(&self) -> bool;
async fn connect(&mut self) -> Result<()>;
async fn disconnect(&mut self) -> Result<()>;
async fn send(&self, message: TransportMessage) -> Result<()>;
async fn receive(&mut self) -> Result<TransportMessage>;
async fn poll(&mut self) -> Result<Option<TransportMessage>>;
}
pub struct TransportManager {
transports: Vec<Box<dyn Transport>>,
}
impl TransportManager {
pub fn new() -> Self {
Self {
transports: Vec::new(),
}
}
pub fn add_transport(&mut self, transport: Box<dyn Transport>) {
self.transports.push(transport);
}
pub fn transports(&self) -> &[Box<dyn Transport>] {
&self.transports
}
pub async fn connect_all(&mut self) -> Result<()> {
for transport in &mut self.transports {
if let Err(e) = transport.connect().await {
tracing::warn!("Failed to connect {}: {}", transport.name(), e);
}
}
Ok(())
}
pub async fn disconnect_all(&mut self) -> Result<()> {
for transport in &mut self.transports {
if let Err(e) = transport.disconnect().await {
tracing::warn!("Failed to disconnect {}: {}", transport.name(), e);
}
}
Ok(())
}
pub async fn send(&self, message: TransportMessage) -> Result<()> {
for transport in &self.transports {
if transport.is_connected().await {
return transport.send(message).await;
}
}
Err(Error::Connection("No transports available".into()))
}
pub async fn poll_all(&mut self) -> Vec<TransportMessage> {
let mut messages = Vec::new();
for transport in &mut self.transports {
while let Ok(Some(msg)) = transport.poll().await {
messages.push(msg);
}
}
messages
}
}
impl Default for TransportManager {
fn default() -> Self {
Self::new()
}
}