lib

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

README.md (6424B)


      1 # radroots_nostr_connect
      2 
      3 `radroots_nostr_connect` is the relay-independent Nostr Connect (NIP-46)
      4 security-protocol package for Radroots. It owns bounded URIs, methods,
      5 permissions, request and response envelopes, and explicit client and server
      6 state machines. Hosts provide relay I/O, timeout policy, approval policy,
      7 signing authority, persistence, and runtime execution.
      8 
      9 The crate is pre-release and publication remains disabled. Its Cargo version
     10 is frozen at `0.1.0-alpha` until the coordinated release contract explicitly
     11 changes it.
     12 
     13 ## Canonical surface
     14 
     15 | Module | Responsibility |
     16 | --- | --- |
     17 | `client` | Prepared/published/completed request state, host transport SPI, cancellation, and progress. |
     18 | `error` | Normalized protocol, validation, correlation, replay, and transport errors. |
     19 | `message` | Bounded requests, responses, envelopes, capabilities, and package-owned event payloads. |
     20 | `method` | Standard and validated extension method identifiers. |
     21 | `permission` | Canonical permission values and bounded permission sets. |
     22 | `server` | Replay-aware request parsing and permission-evaluation inputs without policy ownership. |
     23 | `uri` | Canonical `nostrconnect://` and `bunker://` parsing, validation, and rendering. |
     24 
     25 The curated root exports are `Client`, `Server`, `Method`, `Permission`,
     26 `Request`, `Response`, `BunkerUri`, `ClientUri`, and `Error`. Supporting types
     27 remain in their owning modules so callers make protocol boundaries explicit.
     28 The reviewed Rust surface is recorded in the
     29 [public API baseline](../../contracts/api_baselines/radroots_nostr_connect.txt).
     30 
     31 ## Preparing a client request
     32 
     33 Preparing a request validates and encrypts it but does not publish it:
     34 
     35 ```rust
     36 use radroots_identity::PublicKey;
     37 use radroots_nostr_connect::{
     38     Client, Request,
     39     client::Target,
     40     message::RequestId,
     41     uri::RelayUrl,
     42 };
     43 
     44 let signer = PublicKey::from_hex(
     45     "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
     46 )?;
     47 let relay = RelayUrl::parse("wss://relay.example.com")?;
     48 let client = Client::generate(Target::try_new(signer, vec![relay])?)?;
     49 let operation = client.prepare(RequestId::parse("example-ping")?, Request::Ping)?;
     50 
     51 assert!(operation.publication().is_ok());
     52 # Ok::<(), Box<dyn std::error::Error>>(())
     53 ```
     54 
     55 A runnable version is available at
     56 [`examples/prepare_request.rs`](examples/prepare_request.rs).
     57 
     58 `Client::execute` accepts a caller-owned `client::Transport`. The transport
     59 publishes and receives package-owned `ClientEvent` values and reports timeout
     60 or cancellation explicitly. The protocol crate never creates a relay pool,
     61 executor, Tokio runtime, background worker, or global session.
     62 
     63 ## Server requests and approval
     64 
     65 `Server` parses already-decrypted request JSON, rejects malformed or replayed
     66 requests, and returns a `ServerRequest` containing the required protocol
     67 permission. It does not decide whether that permission is granted. Approval
     68 UI, actor authorization, durable grants, session selection, secret access,
     69 event signing, encryption, and response publication belong to the host.
     70 
     71 A host constructs a correlated plaintext `ServerResponse`, then performs its
     72 own encryption, event signing, and transport commit. The package never treats
     73 successful parsing as authorization or successful response construction as
     74 delivery.
     75 
     76 ## Features and supported targets
     77 
     78 | Feature | Default | Effect |
     79 | --- | --- | --- |
     80 | `serde` | yes | Propagates serialization support to Radroots protocol dependencies. |
     81 
     82 The complete public feature vocabulary is exactly `serde`. No feature starts
     83 work, selects a relay implementation, installs a runtime, opens storage, or
     84 changes approval policy. The Release V1 package is standard-library based; its
     85 default and no-default configurations also compile for
     86 `wasm32-unknown-unknown` as a protocol library.
     87 
     88 ## Serialization and compatibility
     89 
     90 Wire values are validated before use and have explicit size or count bounds.
     91 Unknown canonical extension methods round-trip without relaxing validation.
     92 Current NIP-46 lifecycle vectors live at
     93 `contracts/conformance/vectors/nip46/current_session.v1.json`.
     94 
     95 Serde compatibility applies to the documented NIP-46 messages, URIs,
     96 permissions, and capabilities. Rust layout, debug output, and the pre-1.0 Rust
     97 API are not wire contracts. Cargo package versions evolve independently from
     98 versioned protocol or conformance artifacts.
     99 
    100 ## Security, side effects, and commit points
    101 
    102 URI secrets, client keys, encrypted events, protocol payloads, and auth URLs
    103 are redacted from diagnostics. Callers must still treat URI strings and
    104 plaintext request/response JSON as sensitive and avoid logging them.
    105 
    106 Constructing a client generates or imports in-memory key material. Preparing a
    107 request performs validation, encryption, and event signing in memory; it does
    108 not perform network or durable I/O. `Transport::publish` is the remote-exposure
    109 commit point: after it succeeds, cancellation or dropping the future stops
    110 local waiting but cannot retract signer-side work. Cancellation before
    111 publication prevents exposure; cancellation after publication is reported as
    112 a distinct phase. The host owns deadlines and cancellation wakeups.
    113 
    114 Server parsing and response construction are in-memory protocol operations.
    115 They do not persist approval, consume secrets, sign events, or claim delivery.
    116 
    117 ## Intended consumers
    118 
    119 Direct consumers are `radroots_sdk`, Myc, and remote-signer tooling.
    120 Applications should normally compose NIP-46 through `radroots_sdk`; direct
    121 users of this package are hosts implementing protocol transports or signer
    122 services.
    123 
    124 This package must not acquire relay-pool implementation, secret persistence,
    125 approval UI, global sessions, Tokio runtime ownership, or Myc-specific service
    126 storage. Those responsibilities remain in adapters, security providers,
    127 applications, and host runtimes.
    128 
    129 ## Package charter
    130 
    131 The authoritative responsibility, dependency, feature, module, root-export,
    132 and forbidden-scope contract is the
    133 [Radroots crates Release V1 specification](../../contracts/crates/release_v1/radroots_crates_release_v1.toml).
    134 The reviewed surface is the
    135 [`radroots_nostr_connect` API baseline](../../contracts/api_baselines/radroots_nostr_connect.txt).
    136 
    137 ## Copyright
    138 
    139 Except as otherwise noted, all files in the `radroots_nostr_connect`
    140 distribution are copyright (c) 2025 Tyson Lupul. See `LICENSE` for usage,
    141 redistribution, and warranty terms.