Skip to main content

RoomMessage

Enum RoomMessage 

Source
pub enum RoomMessage {
Show 19 variants MemberAnnounce { sender_fingerprint: String, wrapped_session_key: Option<String>, display_name: Option<String>, sender_ed25519_pubkey: Option<String>, }, SessionKeyRequest { requester_fingerprint: String, }, Encrypted { sender_fingerprint: String, session_id: String, ciphertext_b64: String, }, Plain { sender_fingerprint: String, body: String, }, MemberLeave { sender_fingerprint: String, }, RotateRoomKey { rotator_fingerprint: String, new_salt: Vec<u8>, }, Typing { sender_fingerprint: String, }, FileOffer { sender_fingerprint: String, file_id: String, name: String, size_bytes: u64, mime: Option<String>, chunk_count: u32, encrypted_meta: Option<EncryptedFileMeta>, }, FileChunk { sender_fingerprint: String, file_id: String, chunk_index: u32, total_chunks: u32, data_b64: String, }, OwnerGrant { room_id: String, target_fingerprint: String, }, BanMember { room_id: String, target_fingerprint: String, }, SasInit { tx_id: String, ephemeral_x25519_pubkey_b64: String, target_fingerprint: String, }, SasResponse { tx_id: String, ephemeral_x25519_pubkey_b64: String, }, SasConfirm { tx_id: String, matched: bool, }, JoinRefused { room_id: String, target_fingerprint: String, reason: String, }, CodeJoinRequest { room_id: String, joiner_x25519_pubkey_b64: String, code: String, }, CodeJoinResponse { room_id: String, target_fingerprint: String, owner_x25519_pubkey_b64: String, owner_session_id: String, wrapped_session_key_b64: String, nonce_b64: String, }, ProfileUpdate { sender_fingerprint: String, username: Option<String>, updated_at: i64, }, ContactRequest { requester_fingerprint: String, display_name: Option<String>, note: Option<String>, sender_ed25519_pubkey: Option<String>, },
}
Expand description

All messages on a room’s per-room topic.

Variants§

§

MemberAnnounce

Announce my presence in the room. For encrypted rooms, also share my Megolm session key (passphrase-wrapped).

Fields

§sender_fingerprint: String
§wrapped_session_key: Option<String>

base64(nonce || chacha20poly1305_ciphertext) of the Megolm SessionKey, encrypted under the passphrase-derived key. None for unencrypted rooms.

§display_name: Option<String>

Optional human-readable display name. Serde defaults to None for forward compat with older peers.

§sender_ed25519_pubkey: Option<String>

Base64 of the sender’s 32-byte Ed25519 public key. Lets every existing member learn the new member’s pubkey on first contact, so they can verify future SignedRoomMessage envelopes from this fingerprint. #[serde(default)] for forward compat: a pre-0.3.0 peer that doesn’t send this still works, but its signed messages can’t be verified until it re-announces.

§

SessionKeyRequest

A request from a recently-joined member: “I need session keys”. Existing members respond with MemberAnnounce.

Fields

§requester_fingerprint: String
§

Encrypted

An encrypted message in an encrypted room.

Fields

§sender_fingerprint: String
§session_id: String
§ciphertext_b64: String

base64-encoded MegolmMessage bytes

§

Plain

A plaintext message in an unencrypted room.

Fields

§sender_fingerprint: String
§body: String
§

MemberLeave

Explicit leave notification.

Fields

§sender_fingerprint: String
§

RotateRoomKey

“I’m rotating the room key — derive a new passphrase key from new_salt + the new passphrase you’ll be told out-of-band, then wait for my MemberAnnounce.” Phase 3 v1: simplistic — only the rotator’s outbound changes; receivers must opt in by entering the new passphrase to decrypt new wrapped session keys.

Fields

§rotator_fingerprint: String
§new_salt: Vec<u8>

Argon2id salt for the new passphrase-derived key.

§

Typing

Ephemeral “I’m typing” signal. TTL on the receive side is 3s.

Fields

§sender_fingerprint: String
§

FileOffer

Announce a file the sender is about to push. The receiver creates an attachment row (status=offered) and waits for chunks. For encrypted rooms encrypted_meta carries the Megolm-wrapped file key + ChaCha20 nonce.

Fields

§sender_fingerprint: String
§file_id: String
§name: String
§size_bytes: u64
§chunk_count: u32
§encrypted_meta: Option<EncryptedFileMeta>
§

FileChunk

One chunk of an in-flight file. Receivers reassemble by index and verify the final SHA-256 against file_id.

Fields

§sender_fingerprint: String
§file_id: String
§chunk_index: u32
§total_chunks: u32
§data_b64: String

base64 of raw chunk bytes (plaintext bytes for unencrypted rooms, ChaCha20-Poly1305 ciphertext for encrypted).

§

OwnerGrant

Phase B: an existing owner promotes target_fingerprint to owner. MUST be sent inside WireMessage::Signed — the signer must be on the room’s current owner_fingerprints list for honest receivers to apply the change.

Fields

§room_id: String
§target_fingerprint: String
§

BanMember

Phase B: an existing owner bans target_fingerprint from the room. MUST be sent inside WireMessage::Signed. Honest clients then ignore the banned fingerprint’s MemberAnnounce + messages. The cryptographic enforcement is the immediate RotateRoomKey that the banning owner sends right after.

Fields

§room_id: String
§target_fingerprint: String
§

SasInit

Phase G: SAS verification step 1. The initiator picks a random tx_id and an ephemeral X25519 keypair, sends the pubkey. MUST be sent inside WireMessage::Signed so the receiver can bind this ephemeral key to the initiator’s Ed25519 identity.

Fields

§tx_id: String
§ephemeral_x25519_pubkey_b64: String
§target_fingerprint: String
§

SasResponse

Phase G: SAS step 2 — responder’s ephemeral X25519 pubkey. Both sides now have what they need to compute the shared secret and derive the SAS code locally. Signed.

Fields

§tx_id: String
§ephemeral_x25519_pubkey_b64: String
§

SasConfirm

Phase G: SAS step 3 — once both sides have OOB-compared the derived code and pressed “Match”, each broadcasts this. On receiving the partner’s matched=true, the local side flips verified=1 for the partner’s fingerprint. Signed.

Fields

§tx_id: String
§matched: bool
§

JoinRefused

Phase E: an existing owner of a verified_only room is telling target_fingerprint (an unverified joiner) why their announce went unanswered. Replaces a silent hang on the joiner’s side. Signed.

Fields

§room_id: String
§target_fingerprint: String
§reason: String
§

CodeJoinRequest

Phase F: a joiner is asking to enter a room using a short-lived owner-issued code (no passphrase). Includes the joiner’s ephemeral X25519 pubkey for ECDH key delivery. Signed (so the owner knows who’s asking).

Fields

§room_id: String
§joiner_x25519_pubkey_b64: String
§code: String
§

CodeJoinResponse

Phase F: an issuing owner’s response to a valid CodeJoinRequest. Carries the owner’s ephemeral X25519 pubkey + the current Megolm session key wrapped under the ECDH-derived key. Joiner does X25519 the other direction, derives the same wrap key, unwraps the session key. Signed.

Fields

§room_id: String
§target_fingerprint: String
§owner_x25519_pubkey_b64: String
§owner_session_id: String
§wrapped_session_key_b64: String
§nonce_b64: String
§

ProfileUpdate

Phase 0.5: a peer is announcing (or clearing) their self-declared username. MUST be sent inside WireMessage::Signed — receivers require verified_signer == sender_fingerprint. Last-write-wins by updated_at (monotonic ms). username = None clears the previously-set username and the peer renders as [anonymous].

Fields

§sender_fingerprint: String
§username: Option<String>
§updated_at: i64
§

ContactRequest

huddle 1.0: a contact/DM request delivered to the target’s relay inbox (inbox_room_id). MUST be sent inside WireMessage::Signed — the signer’s fingerprint IS the requester’s identity (the whole point: it proves who’s asking). Carries the requester’s Ed25519 pubkey so the recipient can TOFU-pin it and later derive the DM ECDH key without a round-trip.

Fields

§requester_fingerprint: String
§display_name: Option<String>
§sender_ed25519_pubkey: Option<String>

Trait Implementations§

Source§

impl Clone for RoomMessage

Source§

fn clone(&self) -> RoomMessage

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RoomMessage

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for RoomMessage

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for RoomMessage

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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<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
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,