commit d45da25f5252ffcc596e9bb06320a0cde8f62bb6
parent 10aa5d702a09085823560f5a97838605e76b5e7f
Author: triesap <tyson@radroots.org>
Date: Fri, 12 Jun 2026 23:50:09 -0700
relay: split transport storage features
- Keep the default relay transport surface equivalent for full rr-rs users
- Allow client-only consumers to publish signed events without storage crates
- Gate fetch, outbox, and storage error exports behind the storage feature
- Validate formatting and relay transport client/full feature checks
Diffstat:
4 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/crates/relay_transport/Cargo.toml b/crates/relay_transport/Cargo.toml
@@ -13,9 +13,21 @@ documentation = "https://docs.rs/radroots_relay_transport"
readme = "README"
[features]
-default = ["std", "runtime-tokio"]
+default = ["std", "client", "storage", "runtime-tokio"]
std = []
+client = [
+ "dep:radroots_nostr",
+ "radroots_nostr/std",
+ "radroots_nostr/client",
+ "radroots_nostr/events",
+]
+storage = [
+ "dep:radroots_event_store",
+ "dep:radroots_outbox",
+ "client",
+]
runtime-tokio = [
+ "storage",
"radroots_event_store/runtime-tokio",
"radroots_outbox/runtime-tokio",
]
@@ -25,16 +37,16 @@ radroots_events = { workspace = true, default-features = false, features = [
"std",
"serde",
] }
-radroots_event_store = { workspace = true, default-features = false, features = [
+radroots_event_store = { workspace = true, optional = true, default-features = false, features = [
"sqlite",
"runtime-tokio",
] }
-radroots_nostr = { workspace = true, default-features = false, features = [
+radroots_nostr = { workspace = true, optional = true, default-features = false, features = [
"std",
"client",
"events",
] }
-radroots_outbox = { workspace = true, default-features = false, features = [
+radroots_outbox = { workspace = true, optional = true, default-features = false, features = [
"sqlite",
"runtime-tokio",
] }
diff --git a/crates/relay_transport/src/error.rs b/crates/relay_transport/src/error.rs
@@ -31,12 +31,15 @@ pub enum RadrootsRelayTransportError {
#[error("Nostr event JSON error: {0}")]
NostrEventJson(String),
+ #[cfg(feature = "storage")]
#[error("Event store error: {0}")]
EventStore(#[from] radroots_event_store::RadrootsEventStoreError),
+ #[cfg(feature = "storage")]
#[error("Outbox error: {0}")]
Outbox(#[from] radroots_outbox::RadrootsOutboxError),
+ #[cfg(feature = "storage")]
#[error("Outbox claim {0} does not contain a signed event")]
MissingSignedOutboxEvent(i64),
diff --git a/crates/relay_transport/src/lib.rs b/crates/relay_transport/src/lib.rs
@@ -1,25 +1,30 @@
#![forbid(unsafe_code)]
mod error;
+#[cfg(feature = "storage")]
mod fetch;
+#[cfg(feature = "storage")]
mod outbox;
mod outcome;
mod publish;
mod relay;
pub use error::RadrootsRelayTransportError;
+#[cfg(feature = "storage")]
pub use fetch::{
RadrootsMockRelayFetchAdapter, RadrootsRelayFetchAdapter, RadrootsRelayFetchEventReceipt,
RadrootsRelayFetchItem, RadrootsRelayFetchMode, RadrootsRelayFetchReceipt,
RadrootsRelayFetchRequest, fetch_and_ingest_relay_events,
};
+#[cfg(feature = "storage")]
pub use outbox::{
RadrootsOutboxPublishPolicy, RadrootsOutboxPublishReceipt, publish_claimed_outbox_event,
};
pub use outcome::{RadrootsRelayOutcome, RadrootsRelayOutcomeKind};
+#[cfg(feature = "client")]
+pub use publish::RadrootsNostrClientPublishAdapter;
pub use publish::{
- RadrootsMockRelayPublishAdapter, RadrootsNostrClientPublishAdapter,
- RadrootsRelayPublishAdapter, RadrootsRelayPublishReceipt, RadrootsRelayPublishRelayReceipt,
- RadrootsRelayPublishRequest, publish_signed_event,
+ RadrootsMockRelayPublishAdapter, RadrootsRelayPublishAdapter, RadrootsRelayPublishReceipt,
+ RadrootsRelayPublishRelayReceipt, RadrootsRelayPublishRequest, publish_signed_event,
};
pub use relay::{RadrootsRelayTargetSet, RadrootsRelayUrl, RadrootsRelayUrlPolicy};
diff --git a/crates/relay_transport/src/publish.rs b/crates/relay_transport/src/publish.rs
@@ -5,13 +5,16 @@ use crate::{
RadrootsRelayTransportError, RadrootsRelayUrlPolicy,
};
use futures::future::BoxFuture;
-use nostr::JsonUtil;
use radroots_events::draft::RadrootsSignedNostrEvent;
-use radroots_nostr::prelude::{RadrootsNostrClient, RadrootsNostrEvent};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::sync::{Arc, Mutex};
+#[cfg(feature = "client")]
+use nostr::JsonUtil;
+#[cfg(feature = "client")]
+use radroots_nostr::prelude::{RadrootsNostrClient, RadrootsNostrEvent};
+
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RadrootsRelayPublishRequest {
pub signed_event: RadrootsSignedNostrEvent,
@@ -180,17 +183,20 @@ impl RadrootsRelayPublishAdapter for RadrootsMockRelayPublishAdapter {
}
}
+#[cfg(feature = "client")]
#[derive(Clone)]
pub struct RadrootsNostrClientPublishAdapter {
client: RadrootsNostrClient,
}
+#[cfg(feature = "client")]
impl RadrootsNostrClientPublishAdapter {
pub fn new(client: RadrootsNostrClient) -> Self {
Self { client }
}
}
+#[cfg(feature = "client")]
impl RadrootsRelayPublishAdapter for RadrootsNostrClientPublishAdapter {
fn publish<'a>(
&'a self,