--- title: 55/STATUS-1TO1-CHAT name: Status 1-to-1 Chat status: draft category: Standards Track description: A chat protocol to send public and private messages to a single recipient by the Status app. editor: Aaryamann Challani \ contributors: - Andrea Piana \ - Pedro Pombeiro \ - Corey Petty \ - Oskar Thorén \ - Dean Eigenmann \ sidebar_position: 1 --- ## Abstract This specification describes how the Status 1-to-1 chat protocol is implemented on top of the Waku v2 protocol. This protocol can be used to send messages to a single recipient. ## Terminology - **Participant**: A participant is a user that is able to send and receive messages. - **1-to-1 chat**: A chat between two participants. - **Public chat**: A chat where any participant can join and read messages. - **Private chat**: A chat where only invited participants can join and read messages. - **Group chat**: A chat where multiple select participants can join and read messages. - **Group admin**: A participant that is able to add/remove participants from a group chat. ## Background This document describes how 2 peers communicate with each other to send messages in a 1-to-1 chat, with privacy and authenticity guarantees. ## Specification ### Overview This protocol MAY use any key-exchange mechanism previously discussed - 1. [53/WAKU2-X3DH](../../waku/standards/application/53/x3dh.md) 2. [WAKU2-NOISE](https://github.com/waku-org/specs/blob/waku-RFC/standards/core/noise.md) This protocol can provide end-to-end encryption to give peers a strong degree of privacy and security. Public chat messages are publicly readable by anyone since there's no permission model for who is participating in a public chat. ## Flow ### Negotiation of a 1:1 chat There are two phases in the initial negotiation of a 1:1 chat: 1. **Identity verification** (e.g., face-to-face contact exchange through QR code, Identicon matching). A QR code serves two purposes simultaneously - identity verification and initial key material retrieval; 1. **Asynchronous initial key exchange** For more information on account generation and trust establishment, see [65/ACCOUNT-ADDRESS](../65/account-address.md) ### Post Negotiation After the peers have shared their public key material, a 1:1 chat can be established using the methods described in the key-exchange protocols mentioned above. ### Session management The 1:1 chat is made robust by having sessions between peers. It is handled by the key-exchange protocol used. For example, 1. [53/WAKU2-X3DH](../../waku/standards/application/53/x3dh.md), the session management is described in [54/WAKU2-X3DH-SESSIONS](../../waku/standards/application/54/x3dh-sessions.md) 2. [WAKU2-NOISE](https://github.com/waku-org/specs/blob/waku-RFC/standards/core/noise.md), the session management is described in [WAKU2-NOISE-SESSIONS](https://github.com/waku-org/specs/blob/waku-RFC/standards/core/noise-sessions/noise-sessions.md) ## Negotiation of a 1:1 chat amongst multiple participants (group chat) A small, private group chat can be constructed by having multiple participants negotiate a 1:1 chat amongst each other. Each participant MUST maintain a session with all other participants in the group chat. This allows for a group chat to be created with a small number of participants. However, this method does not scale as the number of participants increases, for the following reasons - 1. The number of messages sent over the network increases with the number of participants. 2. Handling the X3DH key exchange for each participant is computationally expensive. The above issues are addressed in [56/STATUS-COMMUNITIES](../56/communities.md), with other trade-offs. ### Flow The following flow describes how a group chat is created and maintained. #### Membership Update Flow Membership updates have the following wire format: ```protobuf message MembershipUpdateMessage { // The chat id of the private group chat // derived in the following way: // chat_id = hex(chat_creator_public_key) + "-" + random_uuid // This chat_id MUST be validated by all participants string chat_id = 1; // A list of events for this group chat, first 65 bytes are the signature, then is a // protobuf encoded MembershipUpdateEvent repeated bytes events = 2; oneof chat_entity { // An optional chat message ChatMessage message = 3; // An optional reaction to a message EmojiReaction emoji_reaction = 4; } } ``` Note that in `events`, the first element is the signature, and all other elements after are encoded `MembershipUpdateEvent`'s. where `MembershipUpdateEvent` is defined as follows: ```protobuf message MembershipUpdateEvent { // Lamport timestamp of the event uint64 clock = 1; // Optional list of public keys of the targets of the action repeated string members = 2; // Name of the chat for the CHAT_CREATED/NAME_CHANGED event types string name = 3; // The type of the event EventType type = 4; // Color of the chat for the CHAT_CREATED/COLOR_CHANGED event types string color = 5; // Chat image bytes image = 6; enum EventType { UNKNOWN = 0; CHAT_CREATED = 1; // See [CHAT_CREATED](#chat-created) NAME_CHANGED = 2; // See [NAME_CHANGED](#name-changed) MEMBERS_ADDED = 3; // See [MEMBERS_ADDED](#members-added) MEMBER_JOINED = 4; // See [MEMBER_JOINED](#member-joined) MEMBER_REMOVED = 5; // See [MEMBER_REMOVED](#member-removed) ADMINS_ADDED = 6; // See [ADMINS_ADDED](#admins-added) ADMIN_REMOVED = 7; // See [ADMIN_REMOVED](#admin-removed) COLOR_CHANGED = 8; // See [COLOR_CHANGED](#color-changed) IMAGE_CHANGED = 9; // See [IMAGE_CHANGED](#image-changed) } } ``` \