openrtc 2.8.0

OpenRTC: a Rust-first P2P runtime for device discovery, signaling, and iroh/QUIC networking.
Documentation
# OpenRTC Rust Core

The `openrtc` crate is the shared realtime engine behind OpenRTC's native and
browser/WASM runtimes.

```toml
[dependencies]
openrtc = "2.5.0"
```

Rust 1.91 or newer is required. The default feature set is intentionally small;
enable only the native transports your host ships:

```toml
openrtc = { version = "2.5.0", features = ["transport-lan"] }
```

It powers:
- the native runtime used by Tauri and other native hosts
- the WASM runtime loaded by the npm package in browsers

## Core Responsibilities
- app-scoped device discovery
- presence publishing and cleanup
- signaling messages and sessions
- room membership
- peer identity resolution
- iroh endpoint lifecycle and connection management
- shared runtime records used by both native and WASM hosts

## Native vs WASM

### Native
Used for:
- Tauri desktop/mobile-style hosts
- headless or CLI-style runners
- advanced endpoint and router integration

Native-only features include:
- endpoint adoption/export
- custom router / no-internal-router mode
- native auth relay helpers
- protocol registry and plugin registration

### WASM
The same runtime logic compiles to WebAssembly for browser hosts.

The npm package loads that WASM build through `new WasmClient(apiKey)` and
keeps assertion exchange, browser key storage, and capability handles in the
provider-neutral TypeScript layer. `setIdentityCredential()` forwards only the
OpenRTC-issued device credential into Rust admission. WASM never accepts an
OpenRTC Firebase project or App Check token. The generated WASM package
does not expose the old `(projectId, appTag)` constructors or a rollback
feature.

## OpenRTC Native Shape

The default constructor accepts only the public developer API key. It validates
and derives the app identity locally, performs no network work, and configures
no Firebase project:

```rust
use openrtc::client::Client;

let client = Client::new(
    "pk_test_0000000000000000000000000000000000000000".into(),
)?;
```

Backend-free pure-Rust prototypes use the high-level, network-idle control
plane rather than implementing HTTP grants or encoding gateway avenue strings:

```rust
use std::sync::Arc;
use openrtc::native::{
    CapabilityOptions,
    ControlPlane,
    DeviceSigner,
};

// `signer` keeps one per-install Ed25519 private key in host secure storage.
let rtc = ControlPlane::anonymous(
    "pk_test_0000000000000000000000000000000000000000",
    Arc::new(signer) as Arc<dyn DeviceSigner>,
)?;
let room = rtc.join_room(
    "match-123",
    "desktop",
    CapabilityOptions::default(),
).await?;
// Install room.signaling() in the runtime, then explicitly retire the avenue.
room.close().await;
```

`join_space`, `join_room`, and `issue_ticket` create no Firebase Auth user and
no monthly-active-principal event. The awaited join issues one bounded
capability plus its avenue grant. A browser request is origin-allowlisted;
originless native HTTP instead requires the same signed install proof and is
bounded by replay, rate, provider-risk, and developer spend ceilings.

Authenticated pure-Rust applications can use `ControlPlane` instead
of implementing grant HTTP calls themselves. The host supplies four narrow,
provider-neutral pieces: an OIDC assertion provider, a secure-storage Ed25519
signer, protected device-certificate storage, and optional enrollment-time
attestation. OpenRTC performs assertion exchange, enrollment, proof signing,
certificate renewal, and one-hour in-place grant refresh. Firebase project
configuration and App Check are never crate inputs.

The assertion provider also owns a monotonic login epoch. Increment it for
login, logout, account switch, or explicit revocation--not for ordinary OAuth
access-token refresh. Implement `subscribe_identity_epoch()` with a Tokio
`watch::Receiver` when the host can provide immediate notifications. OpenRTC
then coalesces assertion exchange/certificate lookup inside one confirmed
epoch and closes the old capability promptly when the epoch changes. A fresh
process still verifies the consumer assertion once before it trusts a stored
device certificate's principal.

Long-running native processes that are constructed before login can install
the returned capability into `SignalingSlot` exactly once and pass a
`CredentialRelay` provider to
`Client::builder`. Replacing an active capability
requires closing and rebuilding it; the slot cannot become a second reconnect
or presence owner.

Capability activation supplies an avenue-scoped
`NativeCoordinationGatewaySignaling` backend whose grant provider owns the
control-plane exchange. Wrap it in `NativeCapabilityHandle`: one handle owns one
devices, space, room, or ticket avenue, refreshes its one-hour OpenRTC grant in
place, and stops when `close()` runs or the handle is dropped. Creating the
handle is still network-idle; the first runtime presence publication activates
its socket. The host keeps consumer authentication, attestation registration,
and its per-install Ed25519 private key in platform-secure storage.

Use `ClientBuilder::new_provider_neutral` only for internal composition where
the already-derived app tag is available. Use the runtime manager and protocol
registry for advanced native transport composition.

## Peer Sessions and Custom Protocols

The Rust core owns one peer-session view per `deviceId`. Host layers should
consume connected peer-session snapshots rather than reason about transport
records directly.

Protocol authors have two supported extension paths:

1. **Session-adjacent stream composition**
   - wait for a connected peer session
   - open `open_bi` / `open_uni` streams
   - define framing and message semantics externally

2. **ALPN protocol plugins**
   - register protocol plugins through `RuntimeManager` / `ProtocolRegistry`
   - use `SessionAdjacent` plugins for runtime-ready hooks without ALPN routing
   - use `Alpn` plugins when the native runtime should register a dedicated ALPN

WASM/browser consumers should prefer the first model. The second is a
Rust-first advanced capability.

## Important Rule
Rust owns discovery, signaling, presence, lifecycle, and peer identity. TypeScript should wrap those contracts, not duplicate them.

See the [lifecycle ownership contract](https://github.com/bluestarburst/openrtc/blob/main/docs/architecture/lifecycle-ownership-contract.md)
and [application security and delivery contract](https://github.com/bluestarburst/openrtc/blob/main/docs/architecture/application-security-and-delivery-contract.md)
before adding host retry, connection, admission, or delivery behavior.