Skip to main content

MessagingClient

Struct MessagingClient 

Source
pub struct MessagingClient { /* private fields */ }

Implementations§

Source§

impl MessagingClient

Source

pub async fn init(cfg: ClientConfig) -> Result<Arc<Self>>

Initialise. Creates a new local device if none is recorded in storage; otherwise rehydrates.

Source

pub fn user_id(&self) -> UserId

Source

pub fn device_id(&self) -> DeviceId

Source

pub fn device_info(&self, now_ms: u64) -> DeviceInfo

Source

pub fn fresh_key_package(&self) -> Result<Vec<u8>>

Generate a fresh KeyPackage to publish to the directory. Hosts call this when registering a device or topping up the directory.

Source

pub async fn create_conversation( self: &Arc<Self>, name: Option<String>, now_ms: u64, ) -> Result<ConversationId>

Create a new conversation owned by this client (and seeded with a single member: this device).

Source

pub async fn join_conversation( self: &Arc<Self>, welcome_envelope: &MessageEnvelope, now_ms: u64, ) -> Result<ConversationId>

Join via a Welcome bundled in a MessageEnvelope of kind Welcome.

Source

pub fn list_conversations(&self) -> Vec<ConversationMeta>

Source

pub async fn send( &self, conv_id: ConversationId, plaintext: Vec<u8>, now_ms: u64, ) -> Result<MessageEnvelope>

Send an application message. Returns once the envelope has been handed to the transport.

Source

pub async fn add_members( &self, conv_id: ConversationId, entries: Vec<(DeviceId, Vec<u8>)>, now_ms: u64, ) -> Result<()>

Add members. The Commit goes on the wire; the Welcome should be delivered to the new devices’ inboxes (the host transport implements that — typically as a separate addressed envelope).

[CR-2] Each entry is (DeviceId, KeyPackage_bytes). The host typically gets the device_id from the directory at the same time it gets the KeyPackage; we use it to record a per-conversation device_id → leaf_index map so Self::revoke_device can later locate the leaf without a fresh directory lookup. The SDK does not cryptographically verify the host’s device-id claim — that’s a directory policy concern.

Source

pub async fn remove_members( &self, conv_id: ConversationId, leaf_indexes: Vec<u32>, now_ms: u64, ) -> Result<()>

Source

pub async fn process_envelope( &self, env: &MessageEnvelope, now_ms: u64, ) -> Result<Option<IncomingMessage>>

Process an inbound envelope coming from the transport’s subscribe callback or a sync pull. Returns Some for application traffic, None for handshake messages (already merged).

Source

pub async fn sync_conversations( &self, now_ms: u64, ) -> Result<Vec<IncomingMessage>>

Catch-up sync: pull missing events for every open conversation since its cursor. Returns the list of newly-decrypted application messages, in apply order.

Source

pub async fn build_linking_ticket( self: &Arc<Self>, new_device_id: DeviceId, new_device_kp: Vec<u8>, last_app_events: Vec<(ConversationId, Vec<u8>)>, now_ms: u64, ) -> Result<LinkingTicket>

Build a LinkingTicket for a new device. The caller obtains new_device_kp from the new device (e.g., via QR-encoded handshake) and is responsible for sealing the returned ticket against the new device’s ephemeral X25519 pubkey before transmission via [ping_link::seal_ticket].

[CR-13] last_app_events is a host-supplied list of (conversation_id, app_event_bytes) for the new device’s “what you missed” UI. The SDK adds its own metas + (currently- empty) per-conversation MLS state and bundles everything into [device::CatchupSnapshot], CBOR-encoded into the ticket’s catchup_snapshot field. Pass an empty Vec to suppress catchup data (the new device sees an empty conversation list until normal sync runs).

Source

pub async fn consume_linking_ticket( self: &Arc<Self>, ticket: &LinkingTicket, now_ms: u64, ) -> Result<()>

Apply a received linking ticket. Joins the user’s DeviceGroup; the catch-up snapshot (if any) is decrypted by the host using the standard per-conversation channel afterwards.

Source

pub fn export_conversation_state_snapshot( &self, conv_id: ConversationId, now_ms: u64, ) -> Result<Zeroizing<Vec<u8>>>

[CR-7] Export the MLS state snapshot for one open conversation.

Thin pass-through to Conversation::export_state_snapshot. Returned bytes are wrapped in Zeroizing because they contain past epoch secrets.

Source

pub async fn import_state_snapshot( self: &Arc<Self>, snapshot_bytes: &[u8], now_ms: u64, ) -> Result<ConversationId>

[CR-7] Import a GroupStateSnapshot produced by another device’s Conversation::export_state_snapshot.

Replays the snapshot’s entries into this client’s OpenMLS provider, then reconstructs the Conversation handle via MlsGroup::load. After return, the conversation is in list_conversations() and send/process_envelope work against it normally.

Scope. This is for the same-user hand-off (linking, recovery). The snapshot exposes the exporter’s view of past epoch secrets for the target group; only call this when the receiving device has been authenticated to the same user identity (mnemonic, QR-handshake). Cross-user history transfer uses HPKE-sealed AppEvent re-shares (umbrella §15.6), not this method.

Sanity. Refuses snapshots whose group_id doesn’t match the bytes the receiver intends to claim — guards against host bugs that shuffle snapshots between groups. Refuses mismatched OpenMLS storage versions outright; no silent forward/back compatibility.

Source

pub fn export_conversation_secret( &self, conv_id: ConversationId, label: &str, context: &[u8], length: usize, ) -> Result<Zeroizing<Vec<u8>>>

Export a derived secret from one conversation’s MLS exporter ([CR-8]).

Thin pass-through to Conversation::export_secret. See that method’s doc comment for the contract on label, context, length validation, and zeroization. The returned Zeroizing<Vec<u8>> is automatically wiped when dropped.

Source

pub async fn revoke_device( &self, device_id: DeviceId, now_ms: u64, ) -> Result<Vec<MessageEnvelope>>

Revoke a device by removing its leaf from every conversation where we know its position ([CR-2]).

Returns one Commit envelope per conversation the device was a leaf in. The host broadcasts each envelope to the affected conversation; the SDK has also already handed them to the transport via transport.send (idempotent broadcast is the host’s call).

Scope. The SDK can only resolve leaves it recorded itself — either when it admitted the device via Self::add_members or when this device joined as the target via Welcome. For peer-admitted devices the leaf index isn’t locally known; those conversations are silently skipped. The host can fall back to remove_members(leaf_index) directly using a transport-side directory lookup if it needs to revoke from those conversations too. See docs/architecture/multi-device.md §Device removal for the broader flow.

Conversations with no entry for device_id produce no envelope; an empty Vec return is a valid outcome (e.g. the device was already revoked, or was never added by this client).

Trait Implementations§

Source§

impl Debug for MessagingClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more