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.