pub struct Conversation { /* private fields */ }Expand description
In-memory conversation handle. Holds the OpenMLS group plus our wire-level cursor.
Implementations§
Source§impl Conversation
impl Conversation
pub fn id(&self) -> ConversationId
pub fn meta(&self) -> &ConversationMeta
Sourcepub fn members(&self) -> Vec<MemberInfo>
pub fn members(&self) -> Vec<MemberInfo>
Current member roster, recovered locally from the MLS group’s leaf
credentials — no network and no out-of-band ping.profile message.
Each BasicCredential was built from the member’s UserId
(BasicCredential::new(own_user.0.clone()) in Self::create /
Self::join), so we round-trip it back here. Each entry is one
leaf; a multi-device user appears once per device leaf.
pub fn epoch(&self) -> u64
pub fn cursor(&self) -> &SyncCursor
Sourcepub fn send_application(
&mut self,
plaintext: &[u8],
now_ms: u64,
) -> Result<MessageEnvelope>
pub fn send_application( &mut self, plaintext: &[u8], now_ms: u64, ) -> Result<MessageEnvelope>
Encrypt an application message and produce a wire envelope ready for transport.
Uses the [CR-6] plaintext content_hash path: the envelope’s content_hash is
SHA-256(plaintext), not the MLS ciphertext. This is what makes rebase clean
and gives cross-binding hash parity.
Sourcepub fn add_members(
&mut self,
entries: Vec<(DeviceId, Vec<u8>)>,
now_ms: u64,
) -> Result<AddOutcome>
pub fn add_members( &mut self, entries: Vec<(DeviceId, Vec<u8>)>, now_ms: u64, ) -> Result<AddOutcome>
Add members by KeyPackage. Produces the Commit envelope to broadcast plus the Welcome envelope(s) to deliver out-of-band to the newly-added devices.
[CR-2] takes a Vec<(DeviceId, KeyPackage)> instead of a bare Vec<KeyPackage>. The
DeviceId for each entry is the caller’s assertion of which device owns that
KeyPackage — hosts typically get it from the directory service alongside the
KeyPackage itself. The mapping is persisted per-conversation so [MessagingClient::revoke_device]
can later locate the leaf to remove without a fresh directory lookup. The SDK does
not cryptographically verify the device claim; that’s a host policy concern
(typically: the directory authenticates the key_package_id → device_id mapping).
pub fn remove_members( &mut self, leaf_indexes: Vec<u32>, now_ms: u64, ) -> Result<MessageEnvelope>
Sourcepub fn process(
&mut self,
env: &MessageEnvelope,
now_ms: u64,
) -> Result<Option<IncomingMessage>>
pub fn process( &mut self, env: &MessageEnvelope, now_ms: u64, ) -> Result<Option<IncomingMessage>>
Process an inbound envelope. Returns Some(IncomingMessage) for application traffic.
Sourcepub fn export_secret(
&self,
label: &str,
context: &[u8],
length: usize,
) -> Result<Zeroizing<Vec<u8>>>
pub fn export_secret( &self, label: &str, context: &[u8], length: usize, ) -> Result<Zeroizing<Vec<u8>>>
Export a derived secret keyed to this group’s current epoch ([CR-8]).
Wraps MlsGroup::export_secret (the MLS exporter, RFC 9420 §8.5) and surfaces the
bytes in a Zeroizing<Vec<u8>> so the local copy is wiped on drop. Used by the host
to seed:
- the ephemeral channel (
ping/ephemeral, §5.4 of the architecture) - call media keys (
ping/calls/media/{call_id}, §7.2) - call-ephemeral framer keys (
ping/calls/ephemeral/{call_id}, §7.5)
label should use the documented ping/* namespacing convention. There is no
runtime enforcement — cross-binding parity is enforced by conformance fixtures
pinning specific label strings.
Output is the secret. Callers MUST treat the buffer as a secret: never log, never persist unencrypted. The wrapper zeroes our local copy on drop; the caller is responsible for zeroing any copy they make.
Sourcepub fn export_state_snapshot(&self, now_ms: u64) -> Result<Zeroizing<Vec<u8>>>
pub fn export_state_snapshot(&self, now_ms: u64) -> Result<Zeroizing<Vec<u8>>>
[CR-7] Export a portable snapshot of this group’s MLS state.
Walks the provider’s working set, picks every entry whose key references this group’s id, and bundles them with format metadata. Returns CBOR-encoded bytes suitable for inclusion in:
LinkingTicket.catchup_snapshot.conversation_metas[i].group_state_bytes(via [CR-13] — host calls this and passes the bytes through);IdentityBackup.device_group_snapshot(the Permissive-recovery path perdocs/architecture/recovery.md).
Returns Err if the encoded snapshot exceeds [GROUP_SNAPSHOT_HARD_CAP].
Output is wrapped in Zeroizing because the bytes contain past epoch secrets;
the caller’s copy on the FFI side is the host’s responsibility to wipe.
Sourcepub fn leaf_index_of(&self, device_id: &DeviceId) -> Option<u32>
pub fn leaf_index_of(&self, device_id: &DeviceId) -> Option<u32>
Look up the leaf index this device controls, if known ([CR-2]).
Returns the locally-tracked leaf for device_id. Only populated for devices we
added via Self::add_members or for our own leaf via Self::create /
Self::join. Devices a peer admitted on our behalf are not in this map.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Conversation
impl !UnwindSafe for Conversation
impl Freeze for Conversation
impl Send for Conversation
impl Sync for Conversation
impl Unpin for Conversation
impl UnsafeUnpin for Conversation
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
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