lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

README.md (10868B)


      1 # radroots_sdk
      2 
      3 `radroots_sdk` is the host-neutral asynchronous client engine for Radroots.
      4 It composes the canonical event, trade, signing, transport, storage, and sync
      5 crates without installing a runtime, starting workers, opening files, probing
      6 the network, selecting an account, or choosing fallback transports.
      7 
      8 The crate root intentionally exports only `Client`, `ClientBuilder`, `Error`,
      9 and `Result`. Advanced operations live in the `farm`, `listing`, `trade`,
     10 `signing`, `transport`, `storage`, `sync`, `diagnostics`, and `capability`
     11 modules.
     12 
     13 The package charter is the normative [`radroots_sdk` crate
     14 specification](../../contracts/crates/release_v1/radroots_crates_release_v1.toml).
     15 This advanced front door is intended for CLI, Studio, FFI/mobile, and native
     16 applications that need to compose storage, signing, transport, or sync
     17 capabilities directly. Ordinary Rust applications should use the curated
     18 `radroots` facade.
     19 
     20 Persistent startup capacity failures use `ErrorKind::StorageSpaceInsufficient`
     21 and the existing `storage_space_insufficient` protocol report. Native sources
     22 remain available through the error chain; display, debug and protocol reports
     23 exclude their paths and diagnostic text. Hosts retain existing stores and
     24 reconcile prior effects before retrying.
     25 
     26 ## Getting started
     27 
     28 The default `memory` feature provides an inert, in-process backend. The caller
     29 supplies its source generation; building the client creates no files, opens no
     30 network connection, installs no runtime, and starts no worker.
     31 
     32 ```rust
     33 use radroots_sdk::{ClientBuilder, capability::CapabilityId};
     34 use radroots_storage::event::SourceGeneration;
     35 
     36 let generation = SourceGeneration::new([1; 32])?;
     37 let client = ClientBuilder::memory(generation).build()?;
     38 let storage = client
     39     .capabilities()
     40     .get(CapabilityId::CANONICAL_STORAGE);
     41 assert!(storage.is_some());
     42 
     43 # Ok::<(), Box<dyn std::error::Error>>(())
     44 ```
     45 
     46 The complete executable form, including explicit asynchronous shutdown, lives
     47 in [`examples/safe_memory_client.rs`](examples/safe_memory_client.rs). The
     48 side-effect-free transport-selection example lives in
     49 [`examples/transport_profile.rs`](examples/transport_profile.rs).
     50 
     51 ## Feature contract
     52 
     53 The complete public feature vocabulary is:
     54 
     55 | Feature | Capability |
     56 | --- | --- |
     57 | `memory` | deterministic in-process reference storage; the default feature |
     58 | `sqlite` | explicit canonical SQLite storage construction |
     59 | `sync` | composition with a caller-supplied canonical sync engine |
     60 | `nostr` | Nostr conversion and concrete source/sink adapters; implies `sync` |
     61 | `nip46` | NIP-46 signer provider; implies `nostr` |
     62 | `local-signing` | explicit local signing and secret-provider adapters |
     63 | `radrootsd` | explicitly invoked private daemon execution adapter; implies `sync` |
     64 | `geonames` | concrete GeoNames provider integration |
     65 | `knowledge` | deterministic knowledge event contracts/codecs |
     66 | `native` | `sqlite`, `sync`, and `local-signing` |
     67 | `full` | every supported production capability |
     68 
     69 There are no `runtime`, `local-runtime`, `signer-adapters`,
     70 `transport-nostr-runtime`, `transport-nostr-client`, or fixture features.
     71 Features compile capabilities; they do not perform I/O. Optional dependencies
     72 are activated only by their owning feature.
     73 
     74 The supported qualification matrix is:
     75 
     76 ```sh
     77 cargo check -p radroots_sdk --lib --no-default-features
     78 cargo check -p radroots_sdk --all-targets
     79 cargo check -p radroots_sdk --lib --no-default-features --features memory
     80 cargo check -p radroots_sdk --lib --no-default-features --features sqlite
     81 cargo check -p radroots_sdk --lib --no-default-features --features sync
     82 cargo check -p radroots_sdk --lib --no-default-features --features blossom
     83 cargo check -p radroots_sdk --lib --no-default-features --features nostr
     84 cargo check -p radroots_sdk --lib --no-default-features --features nip46
     85 cargo check -p radroots_sdk --lib --no-default-features --features local-signing
     86 cargo check -p radroots_sdk --lib --no-default-features --features radrootsd
     87 cargo check -p radroots_sdk --lib --no-default-features --features geonames
     88 cargo check -p radroots_sdk --lib --no-default-features --features knowledge
     89 cargo check -p radroots_sdk --lib --no-default-features --features native
     90 cargo check -p radroots_sdk --lib --no-default-features --features full
     91 cargo check -p radroots_sdk --all-targets --all-features
     92 ```
     93 
     94 ## Explicit composition
     95 
     96 `ClientBuilder` requires a storage capability. `ClientBuilder::memory(...)`
     97 and `ClientBuilder::sqlite(...)` are explicit constructors; merely enabling a
     98 feature or constructing an empty builder creates no resource. Signers, event
     99 sources, event sinks, and the sync engine are injected separately.
    100 
    101 `client.storage_operations()` exposes actual owner backup capture, verification,
    102 and finalization through the existing storage SPI. SQLite requires an explicit
    103 host-owned backup root in its open options. Unsupported backends refuse these
    104 operations even if they support reliability metadata. Related application
    105 state, identity binding, media leases, and export consent remain host concerns;
    106 these operations expose no paths and do not create an application-wide snapshot
    107 transaction. Failed capture may retain staging for explicit reconciliation.
    108 
    109 Before inventory and capture, hosts exclude new writes and await
    110 `settle_backup_writes()` to drain earlier owner work, including operations whose
    111 caller was cancelled. Keep that host exclusion until capture completes; the
    112 settling call does not grant a continuing reservation or stop new commands.
    113 
    114 `storage_operations().stage_restore(plan)` verifies and stages a retained
    115 snapshot without replacing live state. `finalize_restore(plan)` delegates
    116 verification, close and installation to the same owner. These operations
    117 return bounded `RestoreCapabilityError` values, never paths or handles.
    118 Unsupported backends fail closed. After an installation attempt, explicitly
    119 close and reopen before inspecting restored state. Canceling finalization does
    120 not release the writer early: explicit close must still drain both pools.
    121 The host must preserve a durable delivery guard and reconcile historical IDs
    122 and remote outcomes; a restored snapshot never authorizes automatic resend.
    123 
    124 Native mobile hosts can retain one client while changing host-owned identity
    125 and relay selection. The host injects one opaque implementation of the
    126 canonical `radroots_signing::Signer` SPI; the SDK has no mutable secret slot and
    127 accepts no secret string. `transport::NostrSlot` validates a complete relay set
    128 before atomically installing it. `ClientBuilder::host_sync(sync::HostPolicy)`
    129 explicitly opts SDK-created memory or SQLite storage into system-clock and
    130 random operation-ID policy without creating a runtime, timer, retry loop, or
    131 worker.
    132 
    133 `Client::signing()` exposes focused operations over that opaque signer. Every
    134 returned event is independently rebound to the exact request, expected public
    135 key, caller-observed deadline, cancellation signal, event ID, fields, and
    136 signature. The `blossom` feature adds a domain-separated BUD-11 upload plan and
    137 canonical HTTP authorization header; this credential type cannot enter the
    138 relay push API and is never persisted by the SDK. Durable authored relay work
    139 continues through the canonical sync operations. Host UI lifecycle code owns
    140 polling, background policy, native key custody, and explicit retry.
    141 
    142 Transport profiles are explicit. `Profile::local_only()` contains no target.
    143 `Profile::delivery(...)` retains the exact canonical target set and
    144 satisfaction policy. Preview transports report unavailable and never
    145 substitute Nostr, daemon, local persistence, or another route.
    146 
    147 Farm, listing, and trade preparation is deterministic and side-effect-free.
    148 Commit operations accept native operation and idempotency identities,
    149 cancellation policy, and an explicit transport profile, then return the
    150 canonical sync receipt. Repeating the same idempotent request is the supported
    151 resume/replay path.
    152 
    153 Preparation has no commit point. During commit, durable local acceptance is
    154 the first commit point; a cancellation observed before that point returns
    155 without claiming acceptance. Cancellation after durable acceptance cannot
    156 roll the accepted event back: the returned error/receipt identifies the safe
    157 resume path, and retrying with the same idempotency identity must not create a
    158 second logical operation. Dropping `Client::close` before completion leaves
    159 the shared client in a retry-required closing state; call `close` again.
    160 
    161 The SDK does not define a second wire model. Canonical lower-crate domain and
    162 protocol types own serialization, validation, versioning, and size limits.
    163 SDK request, plan, and receipt structs are constructor-led orchestration types;
    164 their private representation is not a persistence or interchange format.
    165 
    166 ## Reliability and privacy
    167 
    168 Backup, restore, integrity, and status operations delegate to
    169 `radroots_storage::StorageReliability` and return its native versioned plans,
    170 manifests, revisions, stages, and status values. Restore is staged and must be
    171 explicitly finalized. Client shutdown is explicit and asynchronous.
    172 
    173 Public farm/listing events contain only the coarse locality represented by the
    174 canonical event model. Exact coordinates, private trade terms, protected
    175 content, and key references remain behind the private-artifact and secrets
    176 SPIs. Diagnostics contain only capability and canonical storage status. Public
    177 errors and daemon failures use stable, redacted classifications while retaining
    178 private source chains for local diagnostics.
    179 
    180 Signer material and bearer credentials are caller-owned capabilities. The SDK
    181 does not read a keyring, accept or generate secret strings, persist secrets, or
    182 include credentials in `Debug`, `Display`, diagnostics, receipts, or public
    183 error text. A concrete local adapter may be composed explicitly outside the
    184 mobile surface, but its key remains opaque. Hosts remain responsible for
    185 native custody and for protecting source chains and lower-level logs they
    186 choose to expose.
    187 
    188 ## Daemon execution
    189 
    190 The `radrootsd` feature compiles a private HTTP/RPC adapter using the versioned
    191 `radroots_protocol::radrootsd::transport_publish::v5` contract. Constructing
    192 `transport::DaemonDelivery` is inert. Network contact occurs only when the host
    193 invokes `deliver`; bearer credentials are redacted, HTTP error bodies are not
    194 surfaced, and the response must match the signed event and requested policies.
    195 
    196 ## Release posture
    197 
    198 This package is enabled for package-realistic validation only. Actual crates.io
    199 publication remains blocked pending the approval packet and a separately
    200 authorized operator step. The crate is licensed under `MIT OR Apache-2.0`.
    201 
    202 The reviewed all-features public API baseline is recorded at
    203 [`contracts/api_baselines/radroots_sdk.txt`](../../contracts/api_baselines/radroots_sdk.txt).