Skip to main content

RoomEvent

Struct RoomEvent 

Source
pub struct RoomEvent<S> {
    pub(crate) state: S,
}
Expand description

A Matrix room event in a specific lifecycle state.

RoomEvent<S> is a generic wrapper that ensures type-safe state transitions throughout the event lifecycle. The type parameter S determines which methods are available and which transitions are permitted.

§Type States

§Design Philosophy

The state-based design enforces correctness at compile-time:

  • You cannot sign an event without first contextualizing it
  • You cannot store an event without first verifying it
  • You cannot send an event to federation without signatures

This prevents entire classes of security bugs by making invalid states unrepresentable.

Fields§

§state: S

The state-specific data

Implementations§

Source§

impl RoomEvent<Draft>

Source

pub fn new( event_type: TimelineEventType, content: Box<RawValue>, state_key: Option<String>, sender: OwnedUserId, redacts: Option<OwnedEventId>, ) -> Result<Self, Error>

Creates a draft event

§Errors

Returns a serde_json::Error if the event content does not have the fields expected of its type.

Source

pub fn contextualize( self, room_id: Option<OwnedRoomId>, room_version: KnownRoomVersionId, depth: u64, auth_events: EventRefs, prev_events: EventRefs, origin_server_ts: MilliSecondsSinceUnixEpoch, ) -> Result<RoomEvent<Contextualized>, EventContextualizationError>

Contextualize the draft into the room DAG to create a Contextualized event.

This method places the draft event in the context of the room’s directed acyclic graph by adding references to auth events and previous events, along with server timestamp and room version information.

§Room Version

The room_version parameter determines:

  • Event ID format (hashed vs. reference-based)
  • Event reference format (V1 hashed vs. V3+ plain)
  • Authorization rules
  • Signature requirements
§Parameters
  • room_id: The ID of the room the event is in. If the event type is m.room.create and the room_version is 12 or above, this should be None.
  • room_version: Room version rules determining event format and authorization.
  • depth: Depth of the event in the DAG.
  • auth_events: Auth event references for authorization chain.
  • prev_events: Previous event references establishing DAG position.
  • origin_server_ts: Server-assigned timestamp for the event.
§Returns

A Contextualized event ready to be signed.

Source§

impl RoomEvent<Contextualized>

Source

pub fn sign_and_verify( self, server_name: &ServerName, signing_key: &Ed25519KeyPair, previous_state: &HashMap<(StateEventType, String), RoomEvent<Verified>>, auth_events: &HashMap<(StateEventType, String), RoomEvent<Verified>>, current_state: &HashMap<(StateEventType, String), RoomEvent<Verified>>, ) -> Result<RoomEvent<Verified>, SigningValidationError>

Sign the event to produce a Verified event.

Check VerificationMetadata::soft_failed to determine whether the event should be excluded from leaf events and client relay.

This method performs the following operations:

  1. Canonicalizes the event JSON according to Matrix specification
  2. Computes the reference hash to generate the event ID
  3. Signs the canonical JSON with the provided key pair
  4. Attaches the signature to the event
  5. Verifies that the event follows authorization rules
  6. Returns a Verified event (signing implicitly verifies)
§Implicit Verification

Events signed by our own server are implicitly verified - we trust our own signing process. This is why sign() returns Verified rather than Signed.

§Parameters
  • server_name: The origin server name (e.g., “avastar.example.com”) used to namespace the signature in the signatures field.
  • signing_key: The Ed25519 key pair used to generate and verify the cryptographic signature.
  • previous_state: The room state corresponding to the resolution of the state of this event’s prev_events.
  • auth_events: The specific auth events referenced by this event.
  • current_state: The room state at the time the event is being verified. If the event fails this auth check, it will be soft-failed: the returned RoomEvent<Verified> will have VerificationMetadata::soft_failed set to true. See https://spec.matrix.org/v1.17/server-server-api/#soft-failure for more information.
§Returns

A RoomEvent<Verified> with event ID and signatures, ready for persistence or federation.

§Errors

Returns SigningValidationError if:

  • Event content is not a valid JSON object
  • Canonical JSON generation fails
  • Reference hash computation fails
  • Cryptographic signing fails
  • Event ID parsing fails
  • Event fails authorization rules
Source

pub fn sign_join_event( self, server_name: &ServerName, signing_key: &Ed25519KeyPair, ) -> Result<Pdu, SigningError>

Sign a membership event, producing a PDU to send over federation This method only accepts membership events. It’s intended for use when joining rooms over federation, as specified in https://spec.matrix.org/v1.18/server-server-api/#joining-rooms

The events produced by this method should NOT be persisted directly in the database. Instead, they should be sent over federation with the /send_join request, where we as a response will get the state events required to check the authorization rules.

This method performs the following operations:

  1. Canonicalizes the event JSON according to Matrix specification
  2. Computes the reference hash to generate the event ID
  3. Signs the canonical JSON with the provided key pair
  4. Attaches the signature to the event
  5. Returns a Pdu
§Parameters
  • server_name: The origin server name (e.g., “avastar.example.com”) used to namespace the signature in the signatures field.
  • signing_key: The Ed25519 key pair used to generate and verify the cryptographic signature.
§Returns

A Pdu to be sent to another homeserver to counter-sign

§Errors

Returns SigningError if:

  • Event content is not a valid JSON object
  • Event is not a membership event
  • Canonical JSON generation fails
  • Reference hash computation fails
  • Cryptographic signing fails
  • Event ID parsing fails
Source

fn sign_event( self, server_name: &ServerName, signing_key: &Ed25519KeyPair, ) -> Result<RoomEvent<Verified>, SigningError>

Signs the event

Source§

impl RoomEvent<Signed>

Source

pub fn new_signed( content: Box<RawValue>, depth: u64, event_type: TimelineEventType, room_id: Option<OwnedRoomId>, sender: OwnedUserId, state_key: Option<String>, redacts: Option<OwnedEventId>, room_version: KnownRoomVersionId, auth_events: EventRefs, prev_events: EventRefs, prev_state: Option<EventRefs>, membership: Option<MembershipState>, origin: Option<OwnedServerName>, origin_server_ts: MilliSecondsSinceUnixEpoch, event_id: Option<OwnedEventId>, signatures: ServerSignatures, hashes: EventHash, ) -> Result<Self, FromPduError>

Create a new signed event (e.g. from federation)

§Parameters
  • content: Raw JSON content of the event.
  • depth: Depth of the event in the DAG.
  • event_type: Matrix event type.
  • room_id: Room ID the event belongs to.
  • sender: User ID that sent the event.
  • state_key: State key for state events.
  • redacts: Event ID that is redacted, if applicable.
  • room_version: Room version for the event.
  • auth_events: Auth event references required for authorization.
  • prev_events: Previous event references preceding the event.
  • origin_server_ts: Timestamp server assigned to the event.
  • event_id: Event ID of the signed event, if known.
  • signatures: Signature map of the event.
  • hashes: Content hashes of the event.
§Errors

Returns FromPduError if:

  • Event content fails draft validation
  • Event refs contextualization fails
  • Event ID generation fails
Source

pub fn into_draft(self) -> Result<RoomEvent<Draft>, Error>

Recovers the authored Draft from a signed event, discarding its DAG context, signatures and hashes.

Re-validates through Draft::new, the same gate client events pass, so content the tolerant federation parser accepted (e.g. a redacted event stripped to {}) cannot be re-signed under our own key.

§Errors

Returns a serde_json::Error if the content does not pass Draft::new validation for its event type.

Source

pub fn sign_member_event( self, server_name: &ServerName, signing_key: &Ed25519KeyPair, ) -> Result<Pdu, SigningError>

Sign an already signed membership event, producing a PDU to send over federation.

§Errors

Returns SigningError if the event is not a membership event or signing fails.

Source

pub fn signed_from_pdu( pdu: &RawValue, room_version: KnownRoomVersionId, ) -> Result<Self, FromPduError>

Deserializes a federation PDU and constructs a RoomEvent<Signed>.

§Parameters
  • pdu: Raw JSON PDU bytes.
  • room_version: Room version used to validate auth_events and prev_events format in Contextualized::new.
§Errors

Returns FromPduError if:

  • The PDU JSON cannot be deserialized
  • Event refs do not match the room version, or exceed allowed counts
  • Event content fails draft validation
  • Event ID generation fails
Source

pub fn validate_signature( &self, required_verify_keys: &PublicKeyMap, ) -> Result<(), ValidationError>

Validate the signature of the event, without checking auth rules

Source

pub fn verify( self, previous_state: &HashMap<(StateEventType, String), RoomEvent<Verified>>, auth_events: &HashMap<(StateEventType, String), RoomEvent<Verified>>, current_state: &HashMap<(StateEventType, String), RoomEvent<Verified>>, required_verify_keys: &PublicKeyMap, ) -> Result<RoomEvent<Verified>, ValidationError>

Verify a Signed event from federation or other external source. Yields a RoomEvent<Verified>.

This method performs the following steps:

  1. Signature Verification: Cryptographically verifies all signatures in the event against the provided required_verify_keys.
  2. Authorization Check: Validates the event against room state using ruma’s state_res::check_state_dependent_auth_rules.
§Parameters
  • previous_state: The room state corresponding to the resolution of the state of this event’s prev_events.
  • auth_events: The specific auth events referenced by this event.
  • current_state: The room state at the time the event is being verified. If the event fails this auth check, it will be soft-failed: the returned RoomEvent<Verified> will have VerificationMetadata::soft_failed set to true.
  • required_verify_keys: Pre-fetched public keys used to verify the event signatures.
§Errors

Returns ValidationError if:

  • Invalid signature: Cryptographic signature verification fails
  • Event ID mismatch: Computed reference hash doesn’t match event ID
  • Authorization fails: Event fails room authorization rules
  • Canonical JSON error: Cannot canonicalize the event
Source

pub fn build_pdu_for_auth(&self) -> Pdu

Builds a PDU representation for use in authorization checks.

Source

fn check_auth( &self, context_events: &HashMap<(StateEventType, String), RoomEvent<Verified>>, ) -> Result<(), AuthorizationError>

Checks authorization rules for the current event

Source§

impl RoomEvent<Verified>

Source

pub fn format_as( &self, event_format: &EventFormat, ctx: ClientContext, ) -> Box<RawJsonValue>

Formats the event into a Box<RawJsonValue> representation based on the requested formatting.

This method adapts the internal event state to match the required JSON schema of the target consumer. Depending on the event_format provided, it generates either:

  • A Client-formatted event: Strips out federation-specific metadata and injects client-specific context (such as room state or user relations) using the provided ClientContext. Suitable for the Matrix Client-Server API. For more specific context check to_client_event method.
  • A Federation-formatted event: Retains all cryptographic data (signatures, hashes) and DAG context (prev_events, auth_events)
§Parameters
  • event_format - The target format (filter::EventFormat::Client or filter::EventFormat::Federation).
  • ctx - The client context required for resolving client-specific fields. Unused if event_format is set to Federation.
Source

pub fn verified_from_pdu( pdu: &RawValue, metadata: VerificationMetadata, ) -> Result<Self, FromPduError>

Create a new verified event from a PDU

As this creates a new Verified event, this function is somewhat dangerous, since it technically lets you bypass verification. Therefore, care should be taken only to use this function on events from the database

§Parameters
  • pdu: The PDU we’re loading
  • metadata: Verification metadata, stored from earlier
Source

pub fn to_pdu(&self) -> Pdu

Convert the verified event to a PDU (Persistent Data Unit) for federation.

This method serializes the event into the PDU format required by the Matrix federation protocol. The output format varies by room version.

Source

pub fn to_client_event(&self, ctx: ClientContext) -> ClientEvent

Convert the verified event to a client event for the Matrix client-server API.

This method transforms the event into the format expected by Matrix clients, removing federation-only fields and adding client-specific metadata.

Returns a ClientEvent (boxed raw JSON) ready to be sent to a Matrix client via sync, /rooms/{roomId}/messages, or other client API endpoints.

§Transformations

The conversion:

  • Removes federation-only fields: auth_events, prev_events
  • Always includes event_id (regardless of room version)
  • Adds unsigned object with client context:
    • transaction_id: Local transaction ID if this was sent by the client
    • age: Event age in milliseconds (for sync responses)
  • Removes depth field (not used in client API)
§Client Context

The ClientContext parameter provides client-specific metadata:

  • transaction_id: Set when the client sent this event, allowing them to correlate their send with the resulting event
  • age: Time since the event was created, useful for clients to show relative timestamps

Both fields are optional - omit them when not applicable.

§Parameters
  • ctx: Client-specific context containing optional transaction ID and age.
Source

pub fn to_stripped_state_event( &self, ) -> Result<Raw<AnyStrippedStateEvent>, EventIsNotStateEvent>

Convert the verified event to a stripped state event for the client-server API.

Specifically, we are following the specification here: https://spec.matrix.org/v1.18/client-server-api/#stripped-state

The event contains the fields content, sender, state_key and type

§Errors

This function will return an error if it’s called on a non-state event

Source

pub fn sign( self, server_name: &ServerName, signing_key: &Ed25519KeyPair, ) -> Result<Self, SigningError>

Add an additional signature to this already verified event.

§Rationale

This is used when joining a federated room. The joining server signs the event, after which the resident server counter-signs it before persisting and federating it.

§Errors

Returns a SigningError if canonical JSON construction or signing fails for any reason

Trait Implementations§

Source§

impl<S: Clone> Clone for RoomEvent<S>

Source§

fn clone(&self) -> RoomEvent<S>

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 ContextualizedFields for RoomEvent<Contextualized>

Source§

fn auth_events(&self) -> &EventRefs

Get the auth_events field of the event
Source§

fn prev_events(&self) -> &EventRefs

Get the prev_events field of the event
Source§

fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch

Get the origin_server_ts field of the event
Source§

fn room_version(&self) -> KnownRoomVersionId

Get the room_version field of the event
Source§

fn depth(&self) -> u64

Get the depth field of the event
Source§

fn event_id(&self) -> &EventId

Get the ID of the event
Source§

fn room_id(&self) -> &RoomId

Get the ID of the room
Source§

fn hashes(&self) -> &EventHash

Get the content hash of the event
Source§

impl ContextualizedFields for RoomEvent<Signed>

Source§

fn auth_events(&self) -> &EventRefs

Get the auth_events field of the event
Source§

fn prev_events(&self) -> &EventRefs

Get the prev_events field of the event
Source§

fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch

Get the origin_server_ts field of the event
Source§

fn room_version(&self) -> KnownRoomVersionId

Get the room_version field of the event
Source§

fn depth(&self) -> u64

Get the depth field of the event
Source§

fn event_id(&self) -> &EventId

Get the ID of the event
Source§

fn room_id(&self) -> &RoomId

Get the ID of the room
Source§

fn hashes(&self) -> &EventHash

Get the content hash of the event
Source§

impl ContextualizedFields for RoomEvent<Verified>

Source§

fn auth_events(&self) -> &EventRefs

Get the auth_events field of the event
Source§

fn prev_events(&self) -> &EventRefs

Get the prev_events field of the event
Source§

fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch

Get the origin_server_ts field of the event
Source§

fn room_version(&self) -> KnownRoomVersionId

Get the room_version field of the event
Source§

fn depth(&self) -> u64

Get the depth field of the event
Source§

fn event_id(&self) -> &EventId

Get the ID of the event
Source§

fn room_id(&self) -> &RoomId

Get the ID of the room
Source§

fn hashes(&self) -> &EventHash

Get the content hash of the event
Source§

impl<S: Debug> Debug for RoomEvent<S>

Source§

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

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

impl<'de, S> Deserialize<'de> for RoomEvent<S>
where S: Deserialize<'de>,

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 DraftFields for RoomEvent<Draft>

Source§

fn event_type(&self) -> &TimelineEventType

Get the event type of the event
Source§

fn sender(&self) -> &UserId

Get the sender of the event
Source§

fn state_key(&self) -> Option<&str>

Get the state key of the event
Source§

fn content(&self) -> Cow<'_, RawValue>

Get the content of the event
Source§

fn redacts(&self) -> Option<&EventId>

Get the event redacted, if exists
Source§

impl DraftFields for RoomEvent<Contextualized>

Source§

fn event_type(&self) -> &TimelineEventType

Get the event type of the event
Source§

fn sender(&self) -> &UserId

Get the sender of the event
Source§

fn state_key(&self) -> Option<&str>

Get the state key of the event
Source§

fn content(&self) -> Cow<'_, RawValue>

Get the content of the event
Source§

fn redacts(&self) -> Option<&EventId>

Get the event redacted, if exists
Source§

impl DraftFields for RoomEvent<Signed>

Source§

fn event_type(&self) -> &TimelineEventType

Get the event type of the event
Source§

fn sender(&self) -> &UserId

Get the sender of the event
Source§

fn state_key(&self) -> Option<&str>

Get the state key of the event
Source§

fn content(&self) -> Cow<'_, RawValue>

Get the content of the event
Source§

fn redacts(&self) -> Option<&EventId>

Get the event redacted, if exists
Source§

impl DraftFields for RoomEvent<Verified>

Source§

fn event_type(&self) -> &TimelineEventType

Get the event type of the event
Source§

fn sender(&self) -> &UserId

Get the sender of the event
Source§

fn state_key(&self) -> Option<&str>

Get the state key of the event
Source§

fn content(&self) -> Cow<'_, RawValue>

Get the content of the event
Source§

fn redacts(&self) -> Option<&EventId>

Get the event redacted, if exists
Source§

impl<S: Eq> Eq for RoomEvent<S>

Source§

impl<S: PartialEq> PartialEq for RoomEvent<S>

Source§

fn eq(&self, other: &RoomEvent<S>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Redactable for RoomEvent<Signed>

Source§

fn redact( &mut self, redactor: &UserId, reason: Option<String>, ) -> Result<(), ValidationError>

Redact this event in-place. Read more
Source§

impl Redactable for RoomEvent<Verified>

Source§

fn redact( &mut self, redactor: &UserId, reason: Option<String>, ) -> Result<(), ValidationError>

Redact this event in-place. Read more
Source§

impl<S> Serialize for RoomEvent<S>
where S: Serialize,

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

impl SignedFields for RoomEvent<Signed>

Source§

fn signatures(&self) -> &ServerSignatures

Get the signatures of the event
Source§

impl SignedFields for RoomEvent<Verified>

Source§

fn signatures(&self) -> &ServerSignatures

Get the signatures of the event
Source§

impl<S: PartialEq> StructuralPartialEq for RoomEvent<S>

Source§

impl VerifiedFields for RoomEvent<Verified>

Source§

fn metadata(&self) -> &VerificationMetadata

Get the verification metadata for the event
Source§

fn soft_failed(&self) -> bool

Whether the event was soft-failed during verification. Read more

Auto Trait Implementations§

§

impl<S> Freeze for RoomEvent<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for RoomEvent<S>
where S: RefUnwindSafe,

§

impl<S> Send for RoomEvent<S>
where S: Send,

§

impl<S> Sync for RoomEvent<S>
where S: Sync,

§

impl<S> Unpin for RoomEvent<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for RoomEvent<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for RoomEvent<S>
where S: UnwindSafe,

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> DropFlavorWrapper<T> for T

§

type Flavor = MayDrop

The DropFlavor that [wrap]s T into Self
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

§

const WITNESS: W = W::MAKE

A constant of the type witness
§

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

§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
§

impl<T> Instrument for T

§

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

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

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.

§

impl<T> JsonCastable<CanonicalJsonValue> for T

§

impl<T> JsonCastable<Value> for T

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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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