pub struct Client {
pub room: Arc<dyn RoomBackend>,
pub iroh_endpoint: Arc<RwLock<Option<Endpoint>>>,
pub iroh_node: Arc<RwLock<Option<IrohNativeNode>>>,
pub connection_manager: Arc<ConnectionManager>,
pub session_token_registry: Arc<SessionTokenRegistry>,
/* private fields */
}Fields§
§room: Arc<dyn RoomBackend>§iroh_endpoint: Arc<RwLock<Option<Endpoint>>>§iroh_node: Arc<RwLock<Option<IrohNativeNode>>>§connection_manager: Arc<ConnectionManager>§session_token_registry: Arc<SessionTokenRegistry>Session token registry — gates incoming connections during short-lived sessions (e.g. share page). When non-empty, incoming handshakes must carry a valid token. Shared across WASM and native paths.
Implementations§
Source§impl Client
impl Client
Sourcepub async fn route_incoming_bi_stream_for_admission(
&self,
remote_endpoint_id: EndpointId,
transport_stable_id: u64,
send: SendStream,
recv: RecvStream,
) -> Result<IncomingBiStreamDisposition, String>
pub async fn route_incoming_bi_stream_for_admission( &self, remote_endpoint_id: EndpointId, transport_stable_id: u64, send: SendStream, recv: RecvStream, ) -> Result<IncomingBiStreamDisposition, String>
Consume the SDK-owned session-token stream while this physical peer is pending admission or provisionally trusted through a durable native device binding. A trusted binding is local, directional evidence; the peer can still owe this side its session-token presentation. Once a session-token admission is recorded, streams pass through untouched.
This method is the native single-consumer boundary: Tauri and other host bridges must call it before forwarding an accepted Iroh stream to an application runtime. Keeping the responder in Rust prevents webview startup, remount, or IPC subscription timing from stranding admission.
Sourcepub fn validate_session_token(&self, token: &str) -> Result<String, String>
pub fn validate_session_token(&self, token: &str) -> Result<String, String>
Validate an incoming session token and consume one use. Returns Ok(scope) on success, Err(reason) on failure. Empty registry = backward-compat gate (all pass).
Sourcepub async fn validate_session_token_for_connection(
&self,
token: &str,
connection_id: &str,
) -> Result<String, String>
pub async fn validate_session_token_for_connection( &self, token: &str, connection_id: &str, ) -> Result<String, String>
Phase 1: verdict-only admission. Returns the deterministic scope
associated with (token, connection_id) without running any
post-admission side effects (replacement peer accept, native WebRTC
recovery, etc.). Callers that own the response writer must:
- Call this to compute the verdict.
- Write + flush the approval/rejection response to the wire.
- Then invoke
Self::run_post_session_token_admission_side_effectsto fire the lifecycle hooks (replacement, WebRTC restart, …).
This separation eliminates the
[session-token-response:protocol-byte] 0 bytes read race where a
concurrent accept_replacement_peer could retire the very transport
the response writer was about to flush onto.
Existing callers that do not own a wire-level response writer (e.g.
the inline TS/handshake paths in
inspect_incoming_native_main_frame) still get the legacy “validate
- side effects“ semantics via
Self::validate_session_token_for_connection_with_side_effects.
pub async fn validate_session_token_for_connection_with_payload( &self, token: &str, connection_id: &str, payload_suffix: Option<&str>, ) -> Result<String, String>
Sourcepub fn try_begin_session_token_response(
&self,
connection_id: &str,
) -> Option<AdmissionResponseGuard>
pub fn try_begin_session_token_response( &self, connection_id: &str, ) -> Option<AdmissionResponseGuard>
Reserve the connection while a host adapter writes an SDK-owned session-token verdict. The guard must remain alive until the response has been flushed, then be dropped before post-admission lifecycle work.
Sourcepub async fn validate_session_token_for_connection_with_side_effects(
&self,
token: &str,
connection_id: &str,
) -> Result<String, String>
pub async fn validate_session_token_for_connection_with_side_effects( &self, token: &str, connection_id: &str, ) -> Result<String, String>
Pre-Phase-1 helper: validates and immediately runs post-admission
side effects in the same call. Used by callers that do not own a
dedicated response writer (i.e. paths where there is no opportunity
to interleave a wire flush between the verdict and the side
effects). Equivalent to the pre-Phase-1 behaviour of
validate_session_token_for_connection.
pub async fn validate_session_token_for_connection_with_payload_and_side_effects( &self, token: &str, connection_id: &str, payload_suffix: Option<&str>, ) -> Result<String, String>
Sourcepub async fn run_post_session_token_admission_side_effects(
&self,
connection_id: &str,
is_first_presentation: bool,
)
pub async fn run_post_session_token_admission_side_effects( &self, connection_id: &str, is_first_presentation: bool, )
Run the lifecycle side effects that previously lived inline in
validate_session_token_for_connection. Idempotent: if
is_first_presentation is false, this is a no-op (matching the
pre-Phase-1 behaviour where duplicate token frames were skipped).
Only callers that own a session-token response writer should invoke this directly — and only after the response has been written and the wire flushed.
pub async fn inspect_incoming_native_main_frame( &self, connection_id: &str, remote_node_id: Option<&str>, known_device_id: Option<&str>, frame: &[u8], ) -> Result<InspectedMainFrame, String>
pub fn extract_native_handshake_device_id(&self, frame: &[u8]) -> Option<String>
pub fn session_registry_active(&self) -> bool
pub fn ensure_native_stream_admitted( &self, connection_id: &str, remote_node_id: Option<&str>, known_device_id: Option<&str>, ) -> Result<Option<String>, String>
pub fn session_admission(&self, connection_id: &str) -> SessionAdmission
Complete an already-accepted session admission with the peer’s authoritative device id once a later handshake/native binding proves it.
Some reconnect paths validate the session token before the managed connection record has been tagged with the browser/desktop device id. The admission is valid, but trusted-device features that require an authoritative device id (for example drive-view bucket discovery) must not remain stuck in that incomplete state.
pub fn reject_session_connection(&self, connection_id: &str, reason: &str)
pub fn forget_session_connection(&self, connection_id: &str)
pub fn ensure_native_session_admitted( &self, connection_id: &str, remote_node_id: Option<&str>, known_device_id: Option<&str>, claimed_device_id: Option<&str>, ) -> Result<Option<String>, String>
Sourcepub fn register_session_token(
&self,
token: String,
scope: String,
max_connections: u32,
)
pub fn register_session_token( &self, token: String, scope: String, max_connections: u32, )
Register a session token in the registry.
Sourcepub fn register_session_token_with_expiry_ms(
&self,
token: String,
scope: String,
max_connections: u32,
expires_at_ms: u64,
)
pub fn register_session_token_with_expiry_ms( &self, token: String, scope: String, max_connections: u32, expires_at_ms: u64, )
Register a session token with an absolute Unix-millisecond expiry.
Sourcepub fn clear_session_tokens(&self)
pub fn clear_session_tokens(&self)
Clear all registered short-lived session tokens and admission state.
Sourcepub fn ensure_default_admission_gate(&self, scope: &str)
pub fn ensure_default_admission_gate(&self, scope: &str)
Keep the admission gate active even before any explicit share-style tokens are issued. This lets the app enforce “all native connections must be admitted” from startup onward while still allowing trusted native bindings to pass through the verifier path.
Sourcepub fn revoke_session_token(&self, token: &str) -> Vec<String>
pub fn revoke_session_token(&self, token: &str) -> Vec<String>
Revoke a specific session token.
Sourcepub async fn revoke_tokens_by_scope(&self, scope: &str) -> Vec<String>
pub async fn revoke_tokens_by_scope(&self, scope: &str) -> Vec<String>
Revoke all tokens with the given scope.
pub async fn mark_connection_admitted_by_host( &self, connection_id: &str, scope: Option<&str>, authoritative_device_id: Option<String>, )
Sourcepub async fn mark_trusted_user_device_connection_admitted(
&self,
connection_id: &str,
authoritative_device_id: &str,
) -> bool
pub async fn mark_trusted_user_device_connection_admitted( &self, connection_id: &str, authoritative_device_id: &str, ) -> bool
Admit a runtime-discovered managed user-device connection after the transport has been bound to an authoritative device id.
Managed same-user device discovery is already an admission source for
auto-connect; keep the session-token registry, connection scopes, and
connection identity in sync so read-side admission guards do not strand
a healthy connection at session-admission-pending.
pub fn set_native_trusted_connection_verifier( &self, verifier: Option<NativeTrustedConnectionVerifier>, )
pub async fn present_session_token_to_host( &self, endpoint_id: EndpointId, connection_id: &str, token: &str, ) -> Result<String, String>
pub async fn present_session_token_to_host_with_payload( &self, endpoint_id: EndpointId, connection_id: &str, token: &str, token_payload: Option<&str>, ) -> Result<String, String>
Sourcepub async fn remote_session_admission_ready_for_ticket(
&self,
endpoint_ticket: &str,
) -> Result<bool>
pub async fn remote_session_admission_ready_for_ticket( &self, endpoint_ticket: &str, ) -> Result<bool>
Return whether this side has completed the outbound admission required by a compound endpoint ticket. Plain endpoint tickets require no session-token proof and are therefore already ready.
Sourcepub async fn prepare_inline_reciprocal_session_admission(
&self,
endpoint_id: EndpointId,
expected_transport_stable_id: u64,
stream_instance_id: &str,
presentation_id: &str,
token: &str,
token_payload: &str,
device_id: &str,
stream_contract: SessionTokenStreamContract,
) -> Result<ReciprocalSessionTokenPresentation, String>
pub async fn prepare_inline_reciprocal_session_admission( &self, endpoint_id: EndpointId, expected_transport_stable_id: u64, stream_instance_id: &str, presentation_id: &str, token: &str, token_payload: &str, device_id: &str, stream_contract: SessionTokenStreamContract, ) -> Result<ReciprocalSessionTokenPresentation, String>
Prepare one reciprocal presentation in the Rust admission owner. Browser adapters may provide the credential they learned from the authoritative directory, but the resulting transcript is fenced to the current inbound admission epoch, physical generation, and exact stream instance before any bytes are sent.
Sourcepub async fn confirm_inline_reciprocal_session_admission(
&self,
endpoint_id: EndpointId,
expected_transport_stable_id: u64,
stream_instance_id: &str,
presentation_id: &str,
accepted: bool,
approval_scope: Option<&str>,
) -> Result<(), String>
pub async fn confirm_inline_reciprocal_session_admission( &self, endpoint_id: EndpointId, expected_transport_stable_id: u64, stream_instance_id: &str, presentation_id: &str, accepted: bool, approval_scope: Option<&str>, ) -> Result<(), String>
Commit the peer’s ACK for an inline reciprocal presentation to the Rust-owned admission state. The adapter reports only the correlated ACK; token, scope expectation, identity epoch, and route generation all come from the Rust-owned preparation transcript.
pub async fn present_session_token_to_host_with_payload_and_device_id( &self, endpoint_id: EndpointId, connection_id: &str, token: &str, token_payload: Option<&str>, device_id: Option<&str>, ) -> Result<String, String>
pub async fn present_session_token_to_endpoint( &self, endpoint_id: EndpointId, token: &str, ) -> Result<String, String>
pub async fn present_session_token_to_endpoint_with_payload( &self, endpoint_id: EndpointId, token: &str, token_payload: Option<&str>, ) -> Result<String, String>
pub async fn present_session_token_to_endpoint_with_payload_and_device_id( &self, endpoint_id: EndpointId, token: &str, token_payload: Option<&str>, device_id: Option<&str>, ) -> Result<String, String>
Source§impl Client
impl Client
pub fn set_connection_application_crypto_key( &self, connection_id: &str, key: [u8; 32], )
pub fn set_connection_application_crypto_required(&self, connection_id: &str)
Sourcepub fn set_trusted_user_device_application_crypto_required(
&self,
required: bool,
)
pub fn set_trusted_user_device_application_crypto_required( &self, required: bool, )
Require reciprocal application protection for every trusted native user-device connection promoted after this call.
Products with protected named channels should enable this before initializing presence or auto-connect on every participating runtime.
pub fn clear_connection_application_crypto_key(&self, connection_id: &str)
pub fn connection_application_crypto_key( &self, connection_id: &str, ) -> Option<[u8; 32]>
pub fn connection_requires_application_crypto( &self, connection_id: &str, ) -> bool
Sourcepub fn wrap_incoming_application_bi_stream_for_connection(
&self,
connection_id: &str,
send: SendStream,
recv: RecvStream,
) -> Result<(PeerSendStream, PeerRecvStream)>
pub fn wrap_incoming_application_bi_stream_for_connection( &self, connection_id: &str, send: SendStream, recv: RecvStream, ) -> Result<(PeerSendStream, PeerRecvStream)>
Wrap an incoming product stream against the exact logical connection selected by the native ingress router. Product hosts should prefer this over endpoint-only lookup so a retired same-endpoint record can never supply a stale application key.
Sourcepub async fn wrap_incoming_application_bi_stream_for_transport(
&self,
endpoint_id: &EndpointId,
transport_stable_id: u64,
send: SendStream,
recv: RecvStream,
) -> Result<(PeerSendStream, PeerRecvStream)>
pub async fn wrap_incoming_application_bi_stream_for_transport( &self, endpoint_id: &EndpointId, transport_stable_id: u64, send: SendStream, recv: RecvStream, ) -> Result<(PeerSendStream, PeerRecvStream)>
Wrap a native product stream against the exact admitted physical transport generation that produced it. Native host bridges should use this boundary before exposing stream bytes outside Rust so application keys remain owned by the runtime and a same-endpoint replacement cannot lend its key to a retired stream.
Sourcepub async fn wrap_incoming_application_bi_stream_for_transport_with_prefix(
&self,
endpoint_id: &EndpointId,
transport_stable_id: u64,
send: SendStream,
recv: RecvStream,
recv_prefix: &[u8],
) -> Result<(PeerSendStream, PeerRecvStream)>
pub async fn wrap_incoming_application_bi_stream_for_transport_with_prefix( &self, endpoint_id: &EndpointId, transport_stable_id: u64, send: SendStream, recv: RecvStream, recv_prefix: &[u8], ) -> Result<(PeerSendStream, PeerRecvStream)>
Generation-fenced incoming wrapper that also restores bytes inspected by the native admission router while classifying an out-of-order encrypted product frame.
Sourcepub async fn wrap_incoming_application_bi_stream(
&self,
endpoint_id: &EndpointId,
send: SendStream,
recv: RecvStream,
) -> Result<(PeerSendStream, PeerRecvStream)>
pub async fn wrap_incoming_application_bi_stream( &self, endpoint_id: &EndpointId, send: SendStream, recv: RecvStream, ) -> Result<(PeerSendStream, PeerRecvStream)>
Wrap an admitted incoming application stream with the same per-peer
application-crypto boundary used by open_peer_bi on the sender.
Product hosts should call this before parsing channel envelopes or
application frames from the public incoming-stream queue.
pub fn handle_inbound_peer_application_frame( &self, _connection_id: &str, _remote_node_id: Option<&str>, _transport: &str, frame: &[u8], ) -> Result<bool>
route provenance is required; use handle_inbound_peer_application_frame_for_transport
pub async fn handle_inbound_peer_application_frame_for_transport( &self, connection_id: &str, remote_node_id: Option<&str>, transport: &str, expected_transport_stable_id: Option<u64>, frame: &[u8], ) -> Result<bool>
Source§impl Client
impl Client
pub async fn start_external_auto_connect( self: &Arc<Self>, user_id: String, local_device_id: String, ) -> Result<()>
pub async fn submit_external_desired_peers( self: &Arc<Self>, revision: u64, peers_json: &str, ) -> Result<bool>
pub async fn wake_native_external_auto_connect(&self) -> bool
Sourcepub async fn schedule_native_external_auto_connect_recovery(
&self,
remote_node_id: &str,
) -> bool
pub async fn schedule_native_external_auto_connect_recovery( &self, remote_node_id: &str, ) -> bool
Coalesce a burst of recoverable native transport-loss notices before
waking the one external desired-peer actor. A local interface can close
several routes in one network transition; eagerly reconciling after
each close would redial routes that the same transition is still
retiring. A newer provider revision still wakes immediately and fences
this scheduled notice through schedule_epoch.
pub async fn stop_external_auto_connect(&self)
Source§impl Client
impl Client
pub async fn is_connection_transport_alive( &self, endpoint_id: EndpointId, ) -> bool
pub async fn is_managed_connection_transport_alive( &self, connection_id: &str, ) -> bool
Source§impl Client
impl Client
pub fn new_with_app_tag( project_id: String, app_tag: String, token_provider: Box<dyn Fn() -> Option<String> + Send + Sync>, ) -> Self
pub fn new( project_id: String, api_key: String, token_provider: Box<dyn Fn() -> Option<String> + Send + Sync>, ) -> Self
pub fn builder( project_id: String, api_key: String, token_provider: Box<dyn Fn() -> Option<String> + Send + Sync>, ) -> ClientBuilder
pub fn builder_with_native_auth( project_id: String, api_key: String, auth_state: NativeAuthState, ) -> ClientBuilder
pub fn builder_with_app_tag( project_id: String, app_tag: String, token_provider: Box<dyn Fn() -> Option<String> + Send + Sync>, ) -> ClientBuilder
pub fn builder_with_native_space_auth( project_id: String, api_key: String, space_key: String, auth_state: NativeAuthState, ) -> ClientBuilder
pub fn app_tag(&self) -> &str
Sourcepub fn auth_readiness(&self) -> Arc<AuthReadinessStore> ⓘ
pub fn auth_readiness(&self) -> Arc<AuthReadinessStore> ⓘ
Phase 5: returns the shared auth-readiness store so external
hosts (the Plutonium TS auth bridge in src/lib/pluto.ts,
integration tests, or any future native auth layer) can push
leg state via mark_* and so consumers can subscribe via
subscribe() / wait_until_ready().
Sourcepub async fn correlation_for_connection(
&self,
connection_id: &str,
) -> CorrelationContext
pub async fn correlation_for_connection( &self, connection_id: &str, ) -> CorrelationContext
Phase 7: build a CorrelationContext for a given connection id.
Looks up the connection’s recorded scopes in the connection
manager and infers session_kind from the most specific scope
(drive-grant scopes ⇒ drive-grant-guest, user-device ⇒
app-user-device). Cheap; safe to call from any log site.
pub async fn init_native_device_identity( &self, base_dir: PathBuf, preferred_name: Option<&str>, ) -> Result<NativeDeviceIdentity>
pub async fn get_native_device_identity(&self) -> Result<NativeDeviceIdentity>
pub async fn get_native_system_device_info( &self, ) -> Result<NativeSystemDeviceInfo>
pub async fn update_native_device_name( &self, device_name: &str, ) -> Result<NativeDeviceIdentity>
pub fn subscribe_native_device_updates(&self) -> Receiver<NativeDeviceIdentity>
pub fn subscribe_native_connection_state_updates( &self, ) -> Receiver<ConnectionStateSnapshot>
pub async fn init_iroh( &self, secret_key: Option<Vec<u8>>, extra_alpns: Vec<Vec<u8>>, ) -> Result<String>
pub async fn init_iroh_without_internal_router( &self, secret_key: Option<Vec<u8>>, extra_alpns: Vec<Vec<u8>>, ) -> Result<String>
Sourcepub async fn init_iroh_without_internal_router_with_test_relay(
&self,
secret_key: Option<Vec<u8>>,
extra_alpns: Vec<Vec<u8>>,
test_relay_url: Option<&str>,
) -> Result<String>
pub async fn init_iroh_without_internal_router_with_test_relay( &self, secret_key: Option<Vec<u8>>, extra_alpns: Vec<Vec<u8>>, test_relay_url: Option<&str>, ) -> Result<String>
Initializes a native endpoint against a loopback test relay while leaving the single ALPN router to the embedding application.
This is the test-relay equivalent of
Self::init_iroh_without_internal_router. Product harnesses that
attach Docs/Blobs/Gossip to the shared endpoint must use this boundary;
starting OpenRTC’s base router first would create two competing accept
loops on one endpoint.
Sourcepub async fn init_iroh_with_test_relay(
&self,
secret_key: Option<Vec<u8>>,
extra_alpns: Vec<Vec<u8>>,
test_relay_url: Option<&str>,
) -> Result<String>
pub async fn init_iroh_with_test_relay( &self, secret_key: Option<Vec<u8>>, extra_alpns: Vec<Vec<u8>>, test_relay_url: Option<&str>, ) -> Result<String>
Initializes an endpoint against a loopback relay owned by the local test harness. The URL is intentionally restricted to loopback HTTPS so this cannot weaken the trusted production relay policy.
pub async fn get_endpoint(&self) -> Result<Endpoint>
pub async fn current_node_id(&self) -> Option<String>
pub async fn adopt_endpoint(&self, endpoint: Endpoint)
Sourcepub async fn adopt_endpoint_with_router_mode(
&self,
endpoint: Endpoint,
spawn_internal_router: bool,
) -> Result<String>
pub async fn adopt_endpoint_with_router_mode( &self, endpoint: Endpoint, spawn_internal_router: bool, ) -> Result<String>
Installs a host-built native endpoint while preserving one OpenRTC connection lifecycle. Companion transports use this boundary to add Iroh custom transports without becoming a second session owner.
Sourcepub async fn register_native_custom_transport_kind(
&self,
transport_id: u64,
kind: IrohPathKind,
) -> Result<()>
pub async fn register_native_custom_transport_kind( &self, transport_id: u64, kind: IrohPathKind, ) -> Result<()>
Registers the semantic label for an Iroh custom transport discriminator. Registration changes capability/path reporting only; the transport and endpoint remain owned by the host or companion crate.
Sourcepub async fn register_native_transport_upgrade_provider(
&self,
provider: Arc<dyn NativeTransportUpgradeProvider>,
) -> Result<()>
pub async fn register_native_transport_upgrade_provider( &self, provider: Arc<dyn NativeTransportUpgradeProvider>, ) -> Result<()>
Register a hardware transport provider without giving it ownership of the OpenRTC connection lifecycle.
pub async fn node_addr(&self) -> Result<EndpointAddr>
pub async fn endpoint_ticket(&self) -> Result<String>
Sourcepub async fn endpoint_ticket_with_token(
&self,
scope: &str,
max_connections: u32,
) -> Result<String>
pub async fn endpoint_ticket_with_token( &self, scope: &str, max_connections: u32, ) -> Result<String>
Generate a compound ticket with an embedded session token. Registers the token in the session token registry.
pub async fn export_endpoint_handle(&self) -> Result<EndpointHandle>
pub async fn connect(&self, endpoint_id: EndpointId) -> Result<BiStream>
pub async fn ensure_connected(&self, endpoint_id: EndpointId) -> Result<()>
pub async fn ensure_connected_addr( &self, endpoint_id: EndpointId, endpoint_addr: EndpointAddr, ) -> Result<()>
pub async fn disconnect(&self, endpoint_id: EndpointId) -> Result<()>
Sourcepub async fn is_current_transport_stable_id(
&self,
endpoint_id: EndpointId,
expected_transport_stable_id: u64,
) -> bool
pub async fn is_current_transport_stable_id( &self, endpoint_id: EndpointId, expected_transport_stable_id: u64, ) -> bool
Validate queued ingress against the physical transport currently owned by the Iroh node. This is a read-only fence used before TypeScript reads or dispatches an incoming stream.
Sourcepub async fn is_current_transport_stable_id_str(
&self,
endpoint_id: &str,
expected_transport_stable_id: u64,
) -> Result<bool>
pub async fn is_current_transport_stable_id_str( &self, endpoint_id: &str, expected_transport_stable_id: u64, ) -> Result<bool>
String-boundary variant for native adapters that must validate a generation without taking a direct dependency on OpenRTC’s transport implementation crate.
pub async fn disconnect_with_reason( &self, endpoint_id: EndpointId, reason: &str, ) -> Result<()>
pub fn runtime_policy_snapshot(&self) -> RuntimePolicySnapshot
pub async fn open_bi( &self, endpoint_id: EndpointId, ) -> Result<(SendStream, RecvStream)>
pub async fn open_uni(&self, endpoint_id: EndpointId) -> Result<SendStream>
pub async fn subscribe_accept_events( &self, ) -> Result<BoxStream<'static, AcceptEvent>>
pub async fn incoming_streams(&self) -> Result<Receiver<IncomingStream>>
pub async fn set_node_id(&self, node_id: String)
Sourcepub async fn handle_incoming_connection(
&self,
connection: Connection,
) -> Result<()>
pub async fn handle_incoming_connection( &self, connection: Connection, ) -> Result<()>
Route an already-accepted iroh connection through the pluto-rtc native connection pipeline so connection ownership stays in pluto-rtc core.
Sourcepub async fn disconnect_device(
self: &Arc<Self>,
device_id: &str,
node_id_hint: Option<&str>,
) -> Vec<String>
pub async fn disconnect_device( self: &Arc<Self>, device_id: &str, node_id_hint: Option<&str>, ) -> Vec<String>
Manually disconnect from a peer for the current app session.
device_id is the canonical peer identifier; node_id_hint is an
optional iroh node id that lets the lookup succeed even when no
connection record was tagged with the device id (e.g. inbound
connections that never finished the device-id handshake before the
user clicked disconnect).
Returns the list of connection_ids that were retired.
Sourcepub async fn get_connection(
&self,
endpoint_id: EndpointId,
) -> Option<Connection>
pub async fn get_connection( &self, endpoint_id: EndpointId, ) -> Option<Connection>
Get a raw iroh::Connection for a given EndpointId from the native node. Returns None if the node is not initialized or no connection exists.
Sourcepub async fn iroh_transport_rtt_ms(&self, peer_id: &str) -> Option<u64>
pub async fn iroh_transport_rtt_ms(&self, peer_id: &str) -> Option<u64>
Returns the current transport RTT for the active iroh path to peer_id.
This is the QUIC/path-level RTT reported by iroh, so it is comparable to WebRTC transport RTT. App-level diagnostic pings should remain a fallback for readiness checks and encrypted stream verification.
Sourcepub async fn iroh_path_kind(&self, peer_id: &str) -> IrohPathKind
pub async fn iroh_path_kind(&self, peer_id: &str) -> IrohPathKind
Returns the current path kind for an active iroh connection to peer_id.
DirectQuic— selected path is a direct UDP/QUIC address (low latency, no relay)Relay— selected path goes through an iroh relay server (higher latency)Unknown— no live connection found or the path list is empty
Used by the transport-upgrade logic to decide when WebRTC/MoQ upgrades are worthwhile (relay only) and when they can be suspended (direct QUIC available).
pub async fn is_connected(&self, endpoint_id: EndpointId) -> bool
Source§impl Client
impl Client
Sourcepub fn spawn_iroh_path_watcher(
&self,
connection_id: &str,
remote_node_id: &str,
connection: &Connection,
force_restart: bool,
)
pub fn spawn_iroh_path_watcher( &self, connection_id: &str, remote_node_id: &str, connection: &Connection, force_restart: bool, )
Spawn a task that watches the iroh connection’s selected path and calls
handle_path_change whenever it transitions between relay and a native
direct path (QUIC, LAN, or a registered custom transport such as BLE).
Used for both incoming connections (from handle_incoming_connection) and
outgoing connections (from the auto-connect path) so that transport-upgrade
decisions are driven reactively regardless of which side initiated the iroh dial.
force_restart — passed to handle_path_change/maybe_start_native_webrtc_upgrade.
Set to true for incoming connection path watchers so that a stale
Connecting session left over from a browser refresh is replaced when the
new iroh connection’s initial path snapshot fires. Set to false for
outgoing (auto-connect) path watchers so an in-progress negotiation is
not disrupted by routine path-change events.
Source§impl Client
impl Client
pub async fn report_transport_status_for_generation( &self, connection_id: &str, active_transport: &str, parallel_transport: Option<&str>, expected_transport_stable_id: u64, expected_transport_generation: u64, expected_route_generation: u64, ) -> Option<PeerSessionSnapshot>
pub async fn add_peer_scope(&self, id: &str, scope: &str) -> Vec<String>
pub async fn release_peer_scope( &self, id: &str, scope: Option<&str>, ) -> Vec<String>
pub async fn peer_scopes(&self, id: &str) -> Vec<String>
pub async fn same_peer(&self, left: &str, right: &str) -> bool
pub async fn peer_snapshot(&self, id: &str) -> Option<PeerSnapshot>
Sourcepub async fn peer_session(&self, id: &str) -> Option<PeerSessionSnapshot>
pub async fn peer_session(&self, id: &str) -> Option<PeerSessionSnapshot>
Peer-session view over the Rust-owned connection manager.
Delegation rule:
- Rust owns peer-session truth and settled readiness
- host wrappers may forward or normalize this snapshot shape
- app code and TS wrappers must not reinterpret transport records into a second peer/session model
pub async fn peer_sessions(&self) -> Vec<PeerSessionSnapshot>
pub async fn connection_state( &self, connection_id: &str, ) -> Option<ConnectionStateSnapshot>
pub async fn connection_states(&self) -> Vec<ConnectionStateSnapshot>
pub async fn wait_for_settled_peer( &self, id: &str, timeout_ms: Option<u64>, ) -> Option<PeerSessionSnapshot>
Sourcepub async fn wait_for_settled_scope(
&self,
scope: &str,
timeout_ms: Option<u64>,
) -> Option<PeerSessionSnapshot>
pub async fn wait_for_settled_scope( &self, scope: &str, timeout_ms: Option<u64>, ) -> Option<PeerSessionSnapshot>
Wait for the single authoritative peer session admitted for an exact application scope.
This is the scope-oriented counterpart to Self::wait_for_settled_peer
for transient capabilities that intentionally do not have a durable
device alias (for example, a one-time drive grant). Matching is exact,
and multiple live sessions carrying the same scope fail closed rather
than choosing an arbitrary route.
pub async fn open_peer_bi( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
Sourcepub async fn open_peer_protected_bi(
&self,
id: &str,
timeout_ms: Option<u64>,
) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
pub async fn open_peer_protected_bi( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
Open an application-protected bidirectional stream to a settled peer.
Unlike Self::open_peer_bi, this method requires a reciprocal
application-crypto handshake even when the admitted peer did not
originally request application protection. The active OpenRTC
connection generation owns the negotiation and confirmation; callers
never install keys or retry control frames themselves.
Sourcepub async fn send_peer_application_frame(
&self,
id: &str,
frame: &[u8],
timeout_ms: Option<u64>,
) -> Result<()>
pub async fn send_peer_application_frame( &self, id: &str, frame: &[u8], timeout_ms: Option<u64>, ) -> Result<()>
Send one complete application frame on a fresh settled peer stream.
The runtime owns finish() so WASM/JS stream cancellation cannot reset
the QUIC send half before the remote intake observes the payload.
Sourcepub async fn open_peer_bi_explicit_file_sender(
&self,
id: &str,
timeout_ms: Option<u64>,
) -> Result<(Option<String>, String, PeerSendStream)>
pub async fn open_peer_bi_explicit_file_sender( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream)>
Open a bidirectional stream for the explicit-file protocol.
Explicit transfers reserve protocol byte 0x02 inside the managed
application-crypto stream. SDK admission control is the only plaintext
framing allowed on an admitted Iroh connection; product protocol bytes
must pass through the same protection boundary as their payload.
Sourcepub async fn open_peer_bi_explicit_file(
&self,
id: &str,
timeout_ms: Option<u64>,
) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
pub async fn open_peer_bi_explicit_file( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
Open the native explicit-file stream with its receiver-acknowledgement half. Product protocols use this when completion means the remote peer has durably accepted the payload, not merely that local writes finished.
Sourcepub async fn open_peer_bi_diagnostic(
&self,
id: &str,
timeout_ms: Option<u64>,
) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
pub async fn open_peer_bi_diagnostic( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream, PeerRecvStream)>
Open an encrypted-capable bidirectional stream for diagnostics that
participate in proving peer readiness. Normal protocol traffic should use
open_peer_bi, which requires settled_ready; diagnostics may run once
the transport is alive, admission is not blocked, and required E2EE keys
are installed.
Sourcepub async fn open_peer_bi_transport_only(
&self,
id: &str,
timeout_ms: Option<u64>,
) -> Result<(Option<String>, String, SendStream, RecvStream)>
pub async fn open_peer_bi_transport_only( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, SendStream, RecvStream)>
Like open_peer_bi but skips the settled_ready check — usable as soon
as the transport is alive (e.g. for latency probes on a trusted-device peer
that is transport-connected but may not have completed auth settlement yet).
pub async fn open_peer_uni( &self, id: &str, timeout_ms: Option<u64>, ) -> Result<(Option<String>, String, PeerSendStream)>
Sourcepub async fn resolve_peer_connection_ids(&self, id: &str) -> Vec<String>
pub async fn resolve_peer_connection_ids(&self, id: &str) -> Vec<String>
Resolve the canonical managed connection ids for any peer-facing lookup token (device id, device-id hint, node id, connection id).
This keeps peer-identity resolution inside the Rust core so host wrappers can adopt/query protocol connections without rebuilding their own aliasing rules.
pub async fn resolve_peer_connection_records( &self, id: &str, ) -> Vec<ConnectionRecord>
pub async fn best_connection_record_for_peer( &self, id: &str, ) -> Option<ConnectionRecord>
pub async fn list_managed_connections(&self) -> Vec<ConnectionRecord>
Sourcepub async fn managed_connection_device_hint(&self, id: &str) -> Option<String>
pub async fn managed_connection_device_hint(&self, id: &str) -> Option<String>
Resolve the best available device-facing hint for a managed connection.
Delegation rule:
- host wrappers must not rebuild device-id hint lookup from sibling records, metadata stores, or node-id scans
- the Rust core owns peer alias resolution and is the only place that may interpret node ids as transport metadata for device recovery
pub async fn managed_connection_adoption( &self, record: &ConnectionRecord, ) -> Option<ManagedConnectionAdoption>
pub async fn retire_managed_connection( &self, connection_id: &str, reason: Option<String>, )
Sourcepub async fn bind_connection_device_id(
&self,
connection_id: &str,
device_id: &str,
) -> Option<PeerSnapshot>
pub async fn bind_connection_device_id( &self, connection_id: &str, device_id: &str, ) -> Option<PeerSnapshot>
Bind a device-id to an already-existing managed connection.
This is the accept-side counterpart to the dialer’s deviceId knowledge
acquired via presence/tickets. When a handshake’s transport-trust payload
reveals the remote deviceId, the TS Client calls this to re-index the
connection store by device_id, so subsequent peer_session(deviceId)
lookups resolve to the live transport instead of returning None.
Sourcepub async fn bind_node_device_id(&self, node_id: &str, device_id: &str)
pub async fn bind_node_device_id(&self, node_id: &str, device_id: &str)
Supply the durable device identity learned by the signaling directory for every physical connection currently owned by a remote node.
Incoming transports can settle before browser discovery has populated its node-to-device cache. Keeping this reconciliation in the Rust owner makes that startup-order race idempotent without creating another retry or connection lifecycle in the host layer.
pub async fn report_managed_connection_settled( &self, connection_id: &str, settled: bool, device_id: Option<&str>, ) -> Option<PeerSnapshot>
pub async fn report_managed_connection_settled_for_transport( &self, connection_id: &str, settled: bool, expected_transport_stable_id: u64, expected_transport_generation: u64, expected_route_generation: u64, ) -> Option<PeerSnapshot>
pub async fn probe_peer_health(&self, id: &str) -> bool
pub async fn update_presence( &self, user_id: &str, device_name: &str, ticket: &str, metadata: Option<&str>, ) -> Result<()>
pub async fn update_presence_with_ttl( &self, user_id: &str, device_name: &str, ticket: &str, ttl_ms: u64, metadata: Option<&str>, ) -> Result<()>
pub async fn update_durable_device_record_with_ttl( &self, user_id: &str, device_name: &str, ticket: &str, ttl_ms: u64, metadata: Option<&str>, ) -> Result<()>
pub async fn update_live_presence_record( &self, user_id: &str, device_name: &str, ticket: &str, metadata: Option<&str>, ) -> Result<()>
pub async fn set_offline(&self, user_id: &str) -> Result<()>
pub async fn update_device( &self, user_id: &str, device_id: &str, device_name: Option<&str>, capabilities: Option<DeviceCapabilities>, metadata: Option<&str>, ) -> Result<()>
pub async fn delete_device(&self, user_id: &str, device_id: &str) -> Result<()>
Sourcepub fn active_session_identity(&self) -> Option<(String, String)>
pub fn active_session_identity(&self) -> Option<(String, String)>
Returns the (user_id, local_device_id) that were registered when the
auto-connect loop was started, or None if the loop hasn’t started yet.
Sourcepub async fn update_signaling_excluded_peers(
&self,
user_id: &str,
excluded_peers: &[String],
) -> Result<()>
pub async fn update_signaling_excluded_peers( &self, user_id: &str, excluded_peers: &[String], ) -> Result<()>
Update excludedPeers on the local device’s live gateway lease.
Pass the full desired list (not a diff) - the backend overwrites the field.
Browser/WASM presence is owned by WasmPresenceManager, which publishes
this hot state through the coordination gateway. Calling a second
signaling owner from WASM would duplicate billed mutations.
Sourcepub fn current_excluded_peers_snapshot(&self) -> Vec<String>
pub fn current_excluded_peers_snapshot(&self) -> Vec<String>
Convenience: read the current in-memory auto-connect exclusion set as a sorted Vec.
This intentionally returns only canonical device IDs. Node-id aliases are
local-only runtime hints and must not be published into signaling’s
excludedPeers field.
Sourcepub async fn exclude_peer_and_publish(&self, remote_device_id: &str)
pub async fn exclude_peer_and_publish(&self, remote_device_id: &str)
Exclude a remote device from auto-connect for this app session and publish the current session exclusions so peers do not immediately dial us back.
Sourcepub async fn unexclude_peer_and_publish(&self, remote_device_id: &str)
pub async fn unexclude_peer_and_publish(&self, remote_device_id: &str)
Clear a remote device from this app session’s auto-connect exclusion and publish the remaining session exclusions.
pub async fn search_devices(&self, user_id: &str) -> Result<Vec<Device>>
pub async fn devices_with_status( &self, user_id: &str, ) -> Result<Vec<DeviceStatusSnapshot>>
pub async fn runtime_status(&self) -> RuntimeStatus
pub async fn notify_network_change(&self) -> Result<usize>
Sourcepub async fn search_devices_raw(&self, user_id: &str) -> Result<Vec<Device>>
pub async fn search_devices_raw(&self, user_id: &str) -> Result<Vec<Device>>
Search devices without excluding the local node. Useful for tests.
pub async fn connect_device( &self, device_id: Option<&str>, endpoint_ticket: &str, ) -> Result<ManagedConnectResult>
pub async fn managed_connection_health( &self, connection_id: &str, ) -> Option<ManagedConnectionHealthSnapshot>
pub async fn managed_connection_bridge_action( &self, connection_id: &str, ) -> Option<ManagedConnectionBridgeAction>
pub async fn send_message( &self, target_id: &str, payload: &str, state: Option<&str>, reply_payload: Option<&str>, ) -> Result<String>
pub async fn subscribe_devices( &self, user_id: &str, ) -> Result<BoxStream<'static, Result<Vec<DeviceEvent>>>>
pub async fn create_session(&self, session: SignalingSession) -> Result<()>
pub async fn update_session( &self, session_id: &str, update: Value, ) -> Result<()>
pub async fn subscribe_sessions( &self, local_device_id: &str, ) -> Result<BoxStream<'static, Result<Vec<SessionEvent>>>>
pub fn start_signaling_loop( self: Arc<Self>, user_id: String, device_name: String, ticket: String, metadata: Option<String>, ) -> JoinHandle<()>
pub async fn start_managed_user_device_presence_loop( self: Arc<Self>, user_id: String, device_name: String, metadata: Option<String>, ) -> Result<JoinHandle<()>>
pub fn start_heartbeat_loop( self: Arc<Self>, room_id: String, member_id: String, tag: String, ) -> JoinHandle<()>
pub fn start_auto_connect( self: Arc<Self>, user_id: String, local_device_id: String, )
pub fn force_reconnect_snapshot(self: Arc<Self>)
pub fn stop_presence_loop(&self)
pub fn request_presence_update(&self) -> bool
pub fn stop_auto_connect(&self)
pub fn stop_auth_scoped_activity(&self)
Sourcepub fn set_auto_connect_excluded(&self, device_id: &str, excluded: bool)
pub fn set_auto_connect_excluded(&self, device_id: &str, excluded: bool)
Exclude or re-include a device from the auto-connect loop.
Exclusion is session-scoped: it lives only in memory and is reset on process restart.
Calling with excluded = false clears any prior exclusion for that device.
pub fn is_auto_connect_excluded(&self, device_id: &str) -> bool
Sourcepub fn set_app_backgrounded(self: &Arc<Self>, backgrounded: bool)
pub fn set_app_backgrounded(self: &Arc<Self>, backgrounded: bool)
Signal whether the app is currently backgrounded.
Hosts should stop presence, auto-connect, and active sessions while a mobile app is backgrounded. The core also gates reconnect work so a late subscription event cannot restart foreground activity.
pub fn is_app_backgrounded(&self) -> bool
Source§impl Client
impl Client
pub async fn update_transport_config( &self, transport_config: TransportConfig, ) -> Result<()>
pub async fn transport_config(&self) -> TransportConfig
pub async fn is_webrtc_transport_enabled(&self) -> bool
pub async fn is_moq_transport_enabled(&self) -> bool
pub async fn is_ble_transport_enabled(&self) -> bool
pub async fn native_webrtc_state_for_peer( &self, id: &str, ) -> Option<(String, NativeWebRTCState)>
pub async fn native_moq_state_for_peer( &self, id: &str, ) -> Option<(String, NativeMoQState)>
pub async fn native_moq_state_detail_for_peer( &self, id: &str, ) -> Option<(String, NativeMoQState, bool)>
pub async fn native_moq_data_ready_for_peer(&self, id: &str) -> bool
pub async fn try_send_peer_over_webrtc( &self, id: &str, payload: &[u8], ) -> Result<bool>
pub async fn get_connected_webrtc_session_for_peer( &self, id: &str, ) -> Option<Arc<NativeWebRTCDataChannel>>
pub async fn get_webrtc_session_for_peer( &self, id: &str, ) -> Option<Arc<NativeWebRTCDataChannel>>
pub async fn try_send_peer_over_moq( &self, id: &str, payload: &[u8], ) -> Result<bool>
pub async fn send_peer_over_moq(&self, id: &str, data: &[u8]) -> Result<()>
pub async fn handle_typescript_webrtc_signal_frame( &self, connection_id: &str, remote_node_id: Option<&str>, frame: &Value, ) -> bool
pub async fn request_webrtc_upgrade( &self, id: &str, remote_node_id: Option<&str>, reason: Option<&str>, role_override: Option<&str>, force_restart: bool, ) -> Result<bool>
pub async fn request_moq_upgrade( &self, id: &str, remote_node_id: Option<&str>, reason: Option<&str>, ) -> Result<bool>
Source§impl Client
Transport-agnostic send — available on all targets.
impl Client
Transport-agnostic send — available on all targets.
Sourcepub async fn send_peer(&self, id: &str, data: &[u8]) -> Result<()>
pub async fn send_peer(&self, id: &str, data: &[u8]) -> Result<()>
Send data to peer_id using the best available transport.
Native route order is edge-aware: proven upgraded routes stay first,
relay/unknown iroh can probe upgraded transports first, and direct
iroh/LAN/BLE paths stay primary with upgraded transports as fallback.
On WASM, only the iroh path is active; use the TypeScript Connection.sendTyped()
for full transport priority in browser environments.
Source§impl Client
impl Client
pub fn subscribe_native_peer_data(&self) -> Receiver<NativePeerDataEvent>
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Client
impl !Unpin for Client
impl !UnsafeUnpin for Client
impl !UnwindSafe for Client
impl Freeze for Client
impl Send for Client
impl Sync for Client
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more