mirror of https://github.com/status-im/specs.git
205 lines
6.3 KiB
Markdown
205 lines
6.3 KiB
Markdown
# Status Group Chat Specification
|
|
|
|
> Version: 0.1 (Draft)
|
|
>
|
|
> Authors: Andrea Maria Piana <andreap@status.im>
|
|
>
|
|
|
|
|
|
## Table of Contents
|
|
|
|
- [Abstract](#abstract)
|
|
- [Membership updates](#membership-updates)
|
|
- [Chat ID](#chat-id)
|
|
- [Signature](#signature)
|
|
- [Group membership event](#group-membership-event)
|
|
- [chat-created](#chat-created)
|
|
- [name-changed](#name-changed)
|
|
- [members-added](#members-added)
|
|
- [members-joined](#members-joined)
|
|
- [admins-added](#admins-added)
|
|
- [members-removed](#members-removed)
|
|
- [admin-removed](#admin-removed)
|
|
|
|
|
|
## Abstract
|
|
|
|
This documents describes the group chat protocol used by the status application. Pairwise encryption is used among member so a message is exchanged between each participants, similarly to a one-to-one message.
|
|
|
|
## Membership updates
|
|
|
|
Membership updates messages are used to propagate group chat membership changes. The transit format is described in the [Status Payload Specs](status-payload-specs.md). Here we will be describing each specific field.
|
|
|
|
The format is:
|
|
|
|
```
|
|
{
|
|
"events": [struct {"type": string, "member": string, "members": [string], "clock-value": uint, "name": string],
|
|
"signature": string,
|
|
"chat-id": string
|
|
}
|
|
```
|
|
|
|
### Chat ID
|
|
|
|
Each membership update MUST be sent with a corresponding `chat-id`.
|
|
The format of this chat id MUST be a string, [UUID](https://tools.ietf.org/html/rfc4122 ), concatenated with the hex-encoded public key of the creator of the chat. This chat-id MUST be validated by all clients, and MUST be discarded if it does not follow these rules.
|
|
|
|
### Signature
|
|
|
|
The signature for each event is calculated by creating a JSON array of all the `events` sorted by `clock-value` in ascending order, where each event is transformed in an array of tuples `field-name`, `value`, sorted by `field-name` in ascending alphabetical order. The last element of the array MUST be the `chat-id`.
|
|
Empty fields MUST be removed.
|
|
|
|
For example the event:
|
|
|
|
```
|
|
{
|
|
"chat-id": "chat-id",
|
|
"events": [
|
|
{"b": "b-value"
|
|
"clock-value": 1,
|
|
"a": "a-value"
|
|
},
|
|
{
|
|
"e": "e-value",
|
|
"clock-value": 0,
|
|
"a": "a-value"
|
|
}
|
|
]
|
|
}
|
|
|
|
```
|
|
|
|
Results in the structure:
|
|
|
|
```
|
|
[
|
|
[
|
|
[
|
|
["a" "a-value"],
|
|
["clock-value", 0],
|
|
["e" "e-value"]
|
|
],
|
|
[
|
|
["a", "a-value"],
|
|
["b", "b-value"],
|
|
["clock-value", 1]
|
|
]
|
|
],
|
|
"chat-id"
|
|
]
|
|
```
|
|
|
|
This structure is then stringified collapsing all whitespaces and the `Keccak256` of the string is then signed using its private key by the author and added to the payload.
|
|
|
|
|
|
### Group membership event
|
|
|
|
Any group membership event received MUST be verified by calculating the signature as per the method described above.
|
|
The author MUST be extracted from it, if the verification fails the event MUST be discarded.
|
|
|
|
#### chat-created
|
|
|
|
```
|
|
{
|
|
"type": "chat-created",
|
|
"name": string
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
|
|
Chat created event is the first event that needs to be sent. Any event with a clock value lower then this MUST be discarded.
|
|
Upon receiving this event a client MUST validate the `chat-id` provided with the updates and create a chat with identified by `chat-id` and named `name`.
|
|
|
|
#### name-changed
|
|
|
|
```
|
|
{
|
|
"type": "name-changed"
|
|
"name": string
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
A name changed event is used by admins to change the name of the group chat.
|
|
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 to `name`.
|
|
|
|
|
|
#### members-added
|
|
|
|
```
|
|
{
|
|
"type": "members-added"
|
|
"members": [string]
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
A members added event is used by admins to add members to the chat.
|
|
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 a client MUST update the list of members of the chat who have not joined, adding the `members` received.
|
|
`members` is an array of hex encoded public keys.
|
|
|
|
#### member-joined
|
|
|
|
```
|
|
{
|
|
"type": "member-joined"
|
|
"member": string
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
A members joined event is used by a member of the chat to signal that they want to start receiving messages from this chat.
|
|
Upon receiving this event a client MUST validate the `chat-id` provided with the updates and MUST ensure the author of the event is the same as the one specified by the `member` field.
|
|
If the event is valid a client MUST update the list of members of the chat who joined, adding `member`. Any `message` sent to the group chat should now include the newly joined member.
|
|
|
|
#### admins-added
|
|
|
|
```
|
|
{
|
|
"type": "admins-added"
|
|
"members": [string]
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
An admins added event is used by admins to add make other admins in the chat.
|
|
Upon receiving this event a client MUST validate the `chat-id` provided with the updates, MUST ensure the author of the event is an admin of the chat and MUST ensure all `members` are already `members` of the chat, otherwise the event MUST be ignored.
|
|
If the event is valid a client MUST update the list of admins of the chat, adding the `members` received.
|
|
`members` is an array of hex encoded public keys.
|
|
|
|
#### member-removed
|
|
|
|
```
|
|
{
|
|
"type": "member-removed"
|
|
"member": string
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
A member-removed event is used to leave or kick members of the chat.
|
|
Upon receiving this event a client MUST validate the `chat-id` provided with the updates, MUST ensure that:
|
|
- If the author of the event is an admin, target can only be themselves or a non-admin member.
|
|
- If the author of the event is not an admin, the target of the event can only be themselves.
|
|
-
|
|
If the event is valid a client MUST remove the member from the list of `members`/`admins` of the chat, and no further message should be sent to them.
|
|
|
|
#### admin-removed
|
|
|
|
```
|
|
{
|
|
"type": "admin-removed"
|
|
"member": string
|
|
"clock-value": uint
|
|
}
|
|
```
|
|
|
|
An admin-removed event is used to drop admin privileges.
|
|
Upon receiving this event a client MUST validate the `chat-id` provided with the updates, MUST ensure that the author of the event is also the target of the event.
|
|
|
|
If the event is valid a client MUST remove the member from the list of `admins` of the chat.
|