sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit 14417d787b2a9216fc32c156972b21f515699f29
parent 37b664841acf4f2fb052ec6ae3b139448a454a1b
Author: triesap <tyson@radroots.org>
Date:   Mon,  3 Aug 2026 12:43:16 +0000

facade: add safe convenience builders

- Add deterministic memory and explicit local-only ordinary construction.
- Provide inert transport, NIP-46, native, daemon, and model feature helpers.
- Keep resources caller-owned and perform I/O only in the explicit native open.
- Record the single reviewed SDK API addition required by the facade default.

Diffstat:
Mcrates/radroots/Cargo.toml | 2+-
Mcrates/radroots/src/client.rs | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/radroots/src/storage.rs | 3+++
Mcrates/radroots/src/transport.rs | 5++++-
Mcrates/radroots/tests/public_surface.rs | 8++++++++
Mcrates/sdk/src/client.rs | 12++++++++++++
Mdocs/api/radroots_sdk-0.1.0-alpha.txt | 2++
7 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/crates/radroots/Cargo.toml b/crates/radroots/Cargo.toml @@ -28,7 +28,7 @@ radroots_transport = { workspace = true } [features] default = ["client"] -client = [] +client = ["radroots_sdk/memory"] native = ["client"] nostr = ["client"] nip46 = ["nostr"] diff --git a/crates/radroots/src/client.rs b/crates/radroots/src/client.rs @@ -1 +1,66 @@ //! Curated client construction and operation entry points. + +#[cfg(feature = "nostr")] +use std::sync::Arc; + +#[cfg(feature = "nostr")] +use radroots_transport::{EventSink, EventSource}; + +use crate::{ClientBuilder, transport::Profile}; + +/// Creates the safe ordinary client builder with deterministic in-process +/// storage and no transport, signer, runtime, worker, or file authority. +#[must_use] +pub fn memory() -> ClientBuilder { + ClientBuilder::memory_default() +} + +/// Returns the explicit no-transport profile used by ordinary local work. +#[must_use] +pub const fn local_only() -> Profile { + Profile::local_only() +} + +/// Adds caller-owned source and sink capabilities without connecting them or +/// selecting a fallback transport. +#[cfg(feature = "nostr")] +#[must_use] +pub fn with_transport( + builder: ClientBuilder, + source: Arc<dyn EventSource>, + sink: Arc<dyn EventSink>, +) -> ClientBuilder { + builder.source(source).sink(sink) +} + +/// Adds an explicitly constructed NIP-46 signer provider. +#[cfg(feature = "nip46")] +#[must_use] +pub fn with_nip46_signer( + builder: ClientBuilder, + provider: crate::signing::Provider, +) -> ClientBuilder { + builder.signing(provider) +} + +/// Explicitly opens validated native SQLite storage. +#[cfg(feature = "native")] +pub async fn native(options: crate::storage::SqliteOptions) -> crate::Result<ClientBuilder> { + ClientBuilder::sqlite(options).await +} + +/// Reports whether the concrete GeoNames capability was selected at compile +/// time. Asset inspection, acquisition, and database opening remain explicit. +#[cfg(feature = "geonames")] +#[must_use] +pub const fn geonames_enabled() -> bool { + true +} + +/// Reports whether canonical knowledge contracts were selected at compile +/// time. Merely selecting the feature performs no event or storage operation. +#[cfg(feature = "knowledge")] +#[must_use] +pub const fn knowledge_enabled() -> bool { + true +} diff --git a/crates/radroots/src/storage.rs b/crates/radroots/src/storage.rs @@ -1,3 +1,6 @@ //! Curated storage entry points. pub use radroots_sdk::storage::{IntegrityStatus, Operations, Status}; + +#[cfg(feature = "native")] +pub use radroots_sdk::storage::{SqliteOpenMode, SqliteOptions, SqlitePaths}; diff --git a/crates/radroots/src/transport.rs b/crates/radroots/src/transport.rs @@ -2,6 +2,9 @@ pub use radroots_sdk::transport::Profile; pub use radroots_transport::{ - Error, Target, TargetSet, TransportId, + Error, EventSink, EventSource, Target, TargetSet, TransportId, policy::{SatisfactionClass, SatisfactionPolicy, TargetPolicy}, }; + +#[cfg(feature = "radrootsd")] +pub use radroots_sdk::transport::{DaemonAuth, DaemonConfig, DaemonDelivery, DaemonError}; diff --git a/crates/radroots/tests/public_surface.rs b/crates/radroots/tests/public_surface.rs @@ -34,6 +34,14 @@ fn canonical_domain_paths_compile() { }; } +#[cfg(feature = "client")] +#[test] +fn ordinary_memory_and_local_only_construction_is_inert() { + let client = radroots::client::memory().build().expect("memory client"); + assert!(!client.is_closed()); + assert!(radroots::client::local_only().is_local_only()); +} + #[cfg(feature = "knowledge")] #[test] fn canonical_knowledge_paths_compile() { diff --git a/crates/sdk/src/client.rs b/crates/sdk/src/client.rs @@ -70,6 +70,18 @@ impl ClientBuilder { Self::new().storage(Arc::new(MemoryStorage::new(generation))) } + /// Creates the ordinary deterministic in-process memory configuration. + /// + /// This performs no I/O and is intended for ephemeral local clients whose + /// source-generation identity does not need to survive the process. Hosts + /// that persist cursors should call [`Self::memory`] with their own + /// generation instead. + #[cfg(feature = "memory")] + #[must_use] + pub fn memory_default() -> Self { + Self::new().storage(Arc::new(MemoryStorage::default())) + } + /// Explicitly opens canonical SQLite storage from validated host-owned /// configuration and returns a builder containing only the storage SPI. #[cfg(feature = "sqlite")] diff --git a/docs/api/radroots_sdk-0.1.0-alpha.txt b/docs/api/radroots_sdk-0.1.0-alpha.txt @@ -68,6 +68,7 @@ impl radroots_sdk::client::ClientBuilder pub fn radroots_sdk::client::ClientBuilder::build(self) -> radroots_sdk::error::Result<radroots_sdk::client::Client> pub fn radroots_sdk::client::ClientBuilder::capability_availability(self, radroots_sdk::capability::CapabilityId, radroots_sdk::capability::Availability) -> Self pub fn radroots_sdk::client::ClientBuilder::memory(radroots_storage::event::SourceGeneration) -> Self +pub fn radroots_sdk::client::ClientBuilder::memory_default() -> Self pub fn radroots_sdk::client::ClientBuilder::new() -> Self pub fn radroots_sdk::client::ClientBuilder::signer(self, alloc::sync::Arc<dyn radroots_signing::signer::Signer>) -> Self pub fn radroots_sdk::client::ClientBuilder::signing(self, radroots_sdk::signing::Provider) -> Self @@ -337,6 +338,7 @@ impl radroots_sdk::client::ClientBuilder pub fn radroots_sdk::client::ClientBuilder::build(self) -> radroots_sdk::error::Result<radroots_sdk::client::Client> pub fn radroots_sdk::client::ClientBuilder::capability_availability(self, radroots_sdk::capability::CapabilityId, radroots_sdk::capability::Availability) -> Self pub fn radroots_sdk::client::ClientBuilder::memory(radroots_storage::event::SourceGeneration) -> Self +pub fn radroots_sdk::client::ClientBuilder::memory_default() -> Self pub fn radroots_sdk::client::ClientBuilder::new() -> Self pub fn radroots_sdk::client::ClientBuilder::signer(self, alloc::sync::Arc<dyn radroots_signing::signer::Signer>) -> Self pub fn radroots_sdk::client::ClientBuilder::signing(self, radroots_sdk::signing::Provider) -> Self