openrtc 2.0.0-rc.2

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.0.0-rc.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.0.0-rc.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 `WasmClient.newV2(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 2.0 WASM package
does not expose the old `(projectId, appTag)` constructors; those bindings are
available only to an explicit rollback build using the Rust `legacy-v1`
feature.

## OpenRTC 2.0 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_v2(
    "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_v2::{
    NativeV2CapabilityOptions,
    NativeV2ControlPlane,
    NativeV2DeviceSigner,
};

// `signer` keeps one per-install Ed25519 private key in host secure storage.
let rtc = NativeV2ControlPlane::anonymous(
    "pk_test_0000000000000000000000000000000000000000",
    Arc::new(signer) as Arc<dyn NativeV2DeviceSigner>,
)?;
let room = rtc.join_room(
    "match-123",
    "desktop",
    NativeV2CapabilityOptions::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 `NativeV2ControlPlane` 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 `NativeV2SignalingSlot` exactly once and pass a
`NativeV2IdentityCredentialRelay` provider to
`Client::builder_v2_with_identity_provider`. 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.