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](/spec/53/)
2. [35/WAKU2-NOISE](/spec/35/)
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 [2/ACCOUNT](https://specs.status.im/spec/2)
### 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](/spec/53/), the session management is described in [54/WAKU2-X3DH-SESSIONS](/spec/54/)
2. [35/WAKU2-NOISE](/spec/35/), the session management is described in [37/WAKU2-NOISE-SESSIONS](/spec/37/)
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)
}
}
```
<!-- Note: I don't like defining wire formats which are out of the scope of the rfc this way. Should explore alternatives -->
Note that the definitions for `ChatMessage` and `EmojiReaction` can be found in [chat_message.proto](https://github.com/status-im/status-go/blob/5fd9e93e9c298ed087e6716d857a3951dbfb3c1e/protocol/protobuf/chat_message.proto#L1) and [emoji_reaction.proto](https://github.com/status-im/status-go/blob/5fd9e93e9c298ed087e6716d857a3951dbfb3c1e/protocol/protobuf/emoji_reaction.proto).
##### Chat Created
When creating a group chat, this is the first event that MUST be sent.
Any event with a clock value lower than this MUST be discarded.
Upon receiving this event a client MUST validate the `chat_id` provided with the update and create a chat with identified by `chat_id`.
By default, the creator of the group chat is the only group admin.
##### Name Changed
To change the name of the group chat, group admins MUST use a `NAME_CHANGED` event.
Upon receiving this event a client MUST validate the `chat_id` provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored.
If the event is valid the chat name SHOULD be changed according to the provided message.
##### Members Added
To add members to the chat, group admins MUST use a `MEMBERS_ADDED` event.
Upon receiving this event a participant MUST validate the `chat_id` provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored.
If the event is valid, a participant MUST update the list of members of the chat who have not joined, adding the members received.
##### Member Joined
To signal the intent to start receiving messages from a given chat, new participants MUST use a `MEMBER_JOINED` event.
Upon receiving this event a participant MUST validate the `chat_id` provided with the updates.
If the event is valid a participant MUST add the new participant to the list of participants stored locally.
Any message sent to the group chat MUST now include the new participant.
##### Member Removed
There are two ways in which a member MAY be removed from a group chat:
- A member MAY leave the chat by sending a `MEMBER_REMOVED` event, with the `members` field containing their own public key.
- An admin MAY remove a member by sending a `MEMBER_REMOVED` event, with the `members` field containing the public key of the member to be removed.
Each participant MUST validate the `chat_id` provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored.
If the event is valid, a participant MUST update the local list of members accordingly.
##### Admins Added
To promote participants to group admin, group admins MUST use an `ADMINS_ADDED` event.
Upon receiving this event, a participant MUST validate the `chat_id` provided with the updates, MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored.
If the event is valid, a participant MUST update the list of admins of the chat accordingly.
##### Admin Removed
Group admins MUST NOT be able to remove other group admins.
An admin MAY remove themselves by sending an `ADMIN_REMOVED` event, with the `members` field containing their own public key.
Each participant MUST validate the `chat_id` provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored.
If the event is valid, a participant MUST update the list of admins of the chat accordingly.
##### Color Changed
To change the text color of the group chat name, group admins MUST use a `COLOR_CHANGED` event.
##### Image Changed
To change the display image of the group chat, group admins MUST use an `IMAGE_CHANGED` event.