Messaging Data Structures
Messaging Data Structures
The core application supported by River Protocol is messaging. River Stream Nodes are tasked with serving stream events, which are represented as data using protobufs. Stream events themselves may contain message-like events or metadata to support event validation.
Protocol Messaging Protobuf
The data schema of the River protocol can be defined declaratively by protobuf.proto. Below is an elided snapshot of protocol.proto
as of January 2024 containing only schema definitions used in a messaging context within the River protocol.
SpacePayload
StreamEvent
messages encapsulate all message types handled by River Nodes. The primary unit of account for messaging is described in SpacePayload
. A newly minted Space is represented on-chain with the SpaceFactory contract as well of in River Nodes and the River Chain, which stores the streamId
of the Space.
There exists a 1-to-many relation between Spaces as defined in data by the SpacePayload
message and Channels
. Furthermore, Memberships
, usernames
, and display_names
are stored and snapshotted within the streamId
of a Space.
SpacePayload
is made polymorphic using oneof
in the above definition. River Nodes apply rules to each message after unpacking the payload
field from the StreamEvent
, which is the message transmitted to the River Node over the wire. These rules validate the legality of the event
for writes that addEvent
to the stream.
Channel messages
Channel messages are the primary messages used to facilitate group chat within Spaces. They are defined in ChannelPayload
in protocol.proto
. Each ChannelPayload
message is typed as EncryptedData
, which is a message that defines the payload of ciphertext.
Remember, River nodes never see plain text of messages. The protocol defines any message-like event or event that requires encryption with an
EncryptedData
orWrappedEncryptedData
message type inprotocol.proto
.
DM Channel messages
Direct messages are the second messaging primitive supported by the River protocol. The data structure representing direct messaging is defined by the DmChannelPayload
protobuf. Each DM is created with the pair of users privy to the DM conversation. Note that just like with channel messages, DM’s are EncryptedData
messages from the node’s vantage point.
GDM Channel messages
Group direct message messages are supported by the River protocol as their own streams as well. Each Group DM is created with the list of members that forms the initial Membership roster. Though outside the specification of the protocol, the membership roster is meant to convey entitlement to encryption keys, such that clients can implement logic to share keys only with members of the same group dm.
DM’s, and GDM’s are all created as new streams in the RiverNode using the
createStream
rpc client method. Unlike Spaces and Channels though, there exists no on-chain record of these streams.
Media messages
Media files are supported as separate streams in River protocol associated with a parent channel_id
. Messages added to a River node containing media must pass validation criteria that proves the creator
is a member of that channel_id
to prevent man-in-the-middle type attacks.
Media files can be quite large in size and as such are chunked in byte arrays on nodes and therefore support pagination by clients.
Was this page helpful?