commit 391bb65a541192eac6bd9c6fd6e1cae25289a549
parent 4afca1dfb4b01dd654503f99f8f9d9cee0266786
Author: triesap <tyson@radroots.org>
Date: Mon, 27 Jul 2026 20:45:48 +0000
transport: close cli compatibility boundary
- enable the governed legacy replica ingest feature
- construct relay fetches from validated typed targets
- consume sealed transport targets through public accessors
- preserve standalone CLI compatibility with the pinned source graph
Diffstat:
4 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -41,7 +41,7 @@ radroots_nostr_signer = { path = "../lib/crates/nostr_signer", version = "=1.0.0
radroots_protected_store = { path = "../lib/crates/protected_store", version = "=1.0.0-alpha.1", features = ["std"] }
radroots_replica_store = { path = "../lib/crates/replica_store", version = "=1.0.0-alpha.1" }
radroots_replica_schema = { path = "../lib/crates/replica_schema", version = "=1.0.0-alpha.1" }
-radroots_replica_sync = { path = "../lib/crates/replica_sync", version = "=1.0.0-alpha.1" }
+radroots_replica_sync = { path = "../lib/crates/replica_sync", version = "=1.0.0-alpha.1", features = ["legacy-ingest"] }
radroots_transport = { path = "../lib/crates/transport", version = "=1.0.0-alpha.1", default-features = false }
radroots_transport_nostr = { path = "../lib/crates/transport_nostr", version = "=1.0.0-alpha.1", default-features = false, features = [
"runtime-tokio",
diff --git a/src/runtime/config.rs b/src/runtime/config.rs
@@ -1967,7 +1967,7 @@ fn validate_relay_url(value: &str, source: &str) -> Result<String, RuntimeError>
})
}
-fn nostr_relay_url_policy_for_url(value: &str) -> RadrootsRelayUrlPolicy {
+pub(crate) fn nostr_relay_url_policy_for_url(value: &str) -> RadrootsRelayUrlPolicy {
if value.trim_start().starts_with("ws://") {
RadrootsRelayUrlPolicy::Localhost
} else {
diff --git a/src/runtime/sdk.rs b/src/runtime/sdk.rs
@@ -26,7 +26,8 @@ use radroots_sdk::{
};
use radroots_transport_nostr::{
RadrootsNostrClientFetchAdapter, RadrootsRelayFetchRequest, RadrootsRelayFetchedEventsReceipt,
- RadrootsRelayTransportError, fetch_relay_events_blocking,
+ RadrootsRelayTargetSet, RadrootsRelayTransportError, RadrootsRelayUrl,
+ fetch_relay_events_blocking,
};
use tokio::runtime::{Builder as TokioRuntimeBuilder, Runtime};
use tokio::sync::{Mutex, broadcast};
@@ -37,7 +38,7 @@ use crate::runtime::RuntimeError;
use crate::runtime::account;
use crate::runtime::config::{
CapabilityBindingTargetKind, ReticulumBehavior, RuntimeConfig, SIGNER_REMOTE_NIP46_CAPABILITY,
- SignerBackend, TransportProfileKind,
+ SignerBackend, TransportProfileKind, nostr_relay_url_policy_for_url,
};
const SDK_STORAGE_DIR_NAME: &str = "sdk";
@@ -631,8 +632,18 @@ pub(crate) fn fetch_relay_events_via_shared_transport(
max_events: usize,
filter: RadrootsNostrFilter,
) -> Result<RadrootsRelayFetchedEventsReceipt, RadrootsRelayTransportError> {
- let request = RadrootsRelayFetchRequest::fetch(observed_at_ms, max_events, [filter])?
- .with_relay_urls(relay_urls.iter().cloned())
+ let relay_targets = RadrootsRelayTargetSet::from_urls(
+ relay_urls
+ .iter()
+ .map(|url| RadrootsRelayUrl::parse(url, nostr_relay_url_policy_for_url(url)))
+ .collect::<Result<Vec<_>, _>>()?,
+ )?;
+ let request = RadrootsRelayFetchRequest::fetch(
+ observed_at_ms,
+ max_events,
+ relay_targets,
+ [filter],
+ )?
.with_timeout_ms(CLI_RELAY_FETCH_TIMEOUT_MS)?;
fetch_relay_events_blocking(&RadrootsNostrClientFetchAdapter, request)
}
diff --git a/src/runtime/sync.rs b/src/runtime/sync.rs
@@ -918,11 +918,11 @@ fn sync_transport_target_view(
}
.map_err(|error| RuntimeError::Config(format!("invalid transport target: {error}")))?;
Ok(SyncTransportTargetView {
- transport_kind: target.kind.canonical_label(),
- endpoint_uri: target.uri.as_str().to_owned(),
- endpoint_fingerprint: target.fingerprint.as_str().to_owned(),
- target_scope: target.scope.as_ref().map(|scope| scope.as_str().to_owned()),
- target_label: target.label.as_ref().map(|label| label.as_str().to_owned()),
+ transport_kind: target.kind().canonical_label(),
+ endpoint_uri: target.uri().as_str().to_owned(),
+ endpoint_fingerprint: target.fingerprint().as_str().to_owned(),
+ target_scope: target.scope().map(|scope| scope.as_str().to_owned()),
+ target_label: target.label().map(|label| label.as_str().to_owned()),
})
}