mirror of https://github.com/status-im/specs.git
Add timestamp to contact signature object
This commit is contained in:
parent
be5c05b663
commit
1ce18bfa64
|
@ -39,7 +39,7 @@ as various clients created using different technologies.
|
||||||
- [Audio content type](#audio-content-type)
|
- [Audio content type](#audio-content-type)
|
||||||
- [Message types](#message-types)
|
- [Message types](#message-types)
|
||||||
- [Clock vs Timestamp and message ordering](#clock-vs-timestamp-and-message-ordering)
|
- [Clock vs Timestamp and message ordering](#clock-vs-timestamp-and-message-ordering)
|
||||||
- [Signature](#signature)
|
- [ContactRequestSignature](#contact-request-signature)
|
||||||
- [Chats](#chats)
|
- [Chats](#chats)
|
||||||
- [Contact Update](#contact-update)
|
- [Contact Update](#contact-update)
|
||||||
- [Payload](#payload-2)
|
- [Payload](#payload-2)
|
||||||
|
@ -48,8 +48,6 @@ as various clients created using different technologies.
|
||||||
- [Payload](#payload-3)
|
- [Payload](#payload-3)
|
||||||
- [Contact Request](#contact-request)
|
- [Contact Request](#contact-request)
|
||||||
- [Backwards compatibility](#backwards-compatibility)
|
- [Backwards compatibility](#backwards-compatibility)
|
||||||
- [Contacts persistence](#contacts-persistence)
|
|
||||||
- [Contacts Sync](#contacts-sync)
|
|
||||||
- [EmojiReaction](#emojireaction)
|
- [EmojiReaction](#emojireaction)
|
||||||
- [SyncInstallationContact](#syncinstallationcontact)
|
- [SyncInstallationContact](#syncinstallationcontact)
|
||||||
- [Payload](#payload-4)
|
- [Payload](#payload-4)
|
||||||
|
@ -126,10 +124,9 @@ message ChatMessage {
|
||||||
AudioMessage audio = 11;
|
AudioMessage audio = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature of the receiving user. Only sent in one on one messages.
|
// ContactRequestSignature is a signature that proves that the receiving user
|
||||||
// That signature is received when teh other user sends a contact request.
|
// has added us in the contacts
|
||||||
// It is used to prove that we were once contacts
|
ContactRequestSignature contact_request_signature = 12;
|
||||||
string signature = 12;
|
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
UNKNOWN_CONTENT_TYPE = 0;
|
UNKNOWN_CONTENT_TYPE = 0;
|
||||||
|
@ -159,7 +156,7 @@ message ChatMessage {
|
||||||
| 7 | message_type | `MessageType` | The type of message, different for one-to-one, public or group chats |
|
| 7 | message_type | `MessageType` | The type of message, different for one-to-one, public or group chats |
|
||||||
| 8 | content_type | `ContentType` | The type of the content of the message |
|
| 8 | content_type | `ContentType` | The type of the content of the message |
|
||||||
| 9 | payload | `Sticker` I `Image` I `Audio` I `nil` | The payload of the message based on the content type |
|
| 9 | payload | `Sticker` I `Image` I `Audio` I `nil` | The payload of the message based on the content type |
|
||||||
| 10 | signature | `string` | Signature of the receiving user |
|
| 10 | contact_request_signature | `ContactRequestSignature` | Signature of the receiving user |
|
||||||
|
|
||||||
#### Content types
|
#### Content types
|
||||||
|
|
||||||
|
@ -289,15 +286,33 @@ Messages with a `clock` less than `120` seconds under the Whisper/Waku timestamp
|
||||||
|
|
||||||
The node uses `clock` value for the message ordering. The algorithm used, and the distributed nature of the system produces casual ordering, which might produce counter-intuitive results in some edge cases. For example, when a user joins a public chat and sends a message before receiving the exist messages, their message `clock` value might be lower and the message will end up in the past when the historical messages are fetched.
|
The node uses `clock` value for the message ordering. The algorithm used, and the distributed nature of the system produces casual ordering, which might produce counter-intuitive results in some edge cases. For example, when a user joins a public chat and sends a message before receiving the exist messages, their message `clock` value might be lower and the message will end up in the past when the historical messages are fetched.
|
||||||
|
|
||||||
#### Signature
|
#### ContactRequestSignature
|
||||||
|
|
||||||
The `signature` in a message is only present in `ONE_TO_ONE` message type.
|
The `contact_request_signature` in a message is only present in `ONE_TO_ONE` message type.
|
||||||
|
|
||||||
It is used to prove that the sender was once a contact with the receiver. The reason for its presence is because, when an account is reset and re-imported, Contacts are lost.
|
It is used to prove that the sender was once a contact with the receiver. The reason for its presence is because, when an account is reset and re-imported, Contacts are lost.
|
||||||
|
|
||||||
To make sure the message is not ignored, the sender sends this `signature` as proof, so the receiver can know that it once had the sender as a contact.
|
To make sure the message is not ignored, the sender sends this `contact_request_signature` as proof, so the receiver can know that it once had the sender as a contact.
|
||||||
|
|
||||||
If the receiver puts the sender as blocked, teh `signature` is then ignored, as well as the message.
|
```
|
||||||
|
message ContactRequestSignature {
|
||||||
|
bytes signature = 1;
|
||||||
|
uint64 timestamp = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`signature` is constructed as follow:
|
||||||
|
|
||||||
|
```
|
||||||
|
Keccak256(contactSignaturePrefix+PublicKey1+PublicKey2+Timestamp)
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `PublicKey1` and `PublicKey2` are the public keys of the two users, ordered by `X` first and `Y` in order to break ties, in ascending order.
|
||||||
|
`Timestamp` is the `uint64` representation in bytes of the unix timestamp in seconds when the signature was generated, in Little Endian order.
|
||||||
|
|
||||||
|
The signature should be periodically refreshed and sent over to contacts, as old signatures MIGHT be discarded by peers and considered invalid after an arbitrary amount of time.
|
||||||
|
|
||||||
|
`contactSignaturePrefix` is the bytes `[]byte{0x12,0x13}`, and it's used to avoid clashes in signatures schemes.
|
||||||
|
|
||||||
#### Chats
|
#### Chats
|
||||||
|
|
||||||
|
@ -323,6 +338,7 @@ message ContactUpdate {
|
||||||
uint64 clock = 1;
|
uint64 clock = 1;
|
||||||
string ens_name = 2;
|
string ens_name = 2;
|
||||||
string profile_image = 3;
|
string profile_image = 3;
|
||||||
|
ContactRequestSignature contact_request_signature = 4;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -333,6 +349,7 @@ message ContactUpdate {
|
||||||
| 1 | clock | `uint64` | The clock of the chat with the user |
|
| 1 | clock | `uint64` | The clock of the chat with the user |
|
||||||
| 2 | ens_name | `string` | The ENS name if set |
|
| 2 | ens_name | `string` | The ENS name if set |
|
||||||
| 3 | profile_image | `string` | The base64 encoded profile picture of the user |
|
| 3 | profile_image | `string` | The base64 encoded profile picture of the user |
|
||||||
|
| 4 | contact_request_signature | `ContactRequestSignature` | Signature of the sending user |
|
||||||
|
|
||||||
#### Contact update
|
#### Contact update
|
||||||
|
|
||||||
|
@ -343,48 +360,17 @@ A client SHOULD send a `ContactUpdate` to all the contacts each time:
|
||||||
|
|
||||||
A client SHOULD also periodically send a `ContactUpdate` to all the contacts, the interval is up to the client, the Status official client sends these updates every 48 hours.
|
A client SHOULD also periodically send a `ContactUpdate` to all the contacts, the interval is up to the client, the Status official client sends these updates every 48 hours.
|
||||||
|
|
||||||
|
`ContactRequestSignature` is MUST be signed by the sending user, the format is described in [ContactRequestSignature](#contact-request-signature)
|
||||||
|
|
||||||
### Contact
|
### Contact
|
||||||
|
|
||||||
`Contact` is a representation of other accounts encountered on the app. They are added through `ContactUpdate`s propagated.
|
|
||||||
A `Contact` does not mean a "friend". Any account from which we receive a `ContactUpdate` is added to the table.
|
|
||||||
|
|
||||||
Users are considered "Friends" when they are **mutual** contacts, meaning that both of them have the `added` and `requestReceived` boolean set as `true`, which then triggers setting `mutualContact` to `true`. This is done through `ContactRequest`s.
|
|
||||||
|
|
||||||
#### Payload
|
|
||||||
|
|
||||||
| Field | Name | Type | Description |
|
|
||||||
| ----- | ---- | ---- | ---- |
|
|
||||||
| 1 | id | `string` | ID of the contact. Hex-encoded public key (prefixed with 0x). |
|
|
||||||
| 2 | address | `string` | Ethereum address of the contact |
|
|
||||||
| 3 | name | `string` | Contact's ENS name |
|
|
||||||
| 4 | ensVerified | `bool` | Whether the name of the contact is verified |
|
|
||||||
| 5 | alias | `string` | Contact's generated username |
|
|
||||||
| 6 | identicon | `string` | Identicon generated from public key |
|
|
||||||
| 7 | lastUpdated | `uint64` | Last time an update was received from the contact |
|
|
||||||
| 8 | blocked | `bool` | Whether the contact is blocked |
|
|
||||||
| 9 | added | `bool` | Whether the contact is added |
|
|
||||||
| 10 | requestReceived | `bool` | Whether the contact requested us to add them |
|
|
||||||
| 11 | mutualContact | `bool` | Whether the contact is mutual |
|
|
||||||
| 12 | deviceInfo | `[]ContactDeviceInfo` | |
|
|
||||||
| 13 | localNickname | `string` | Nickname set by the user for the contact |
|
|
||||||
| 14 | images | `map[string]images.IdentityImage` | Contact's profile images (thumbnail and large) |
|
|
||||||
| 15 | message | `Message` | Message sent with a contact request |
|
|
||||||
| 15 | signature | `string` | User signature proving that the other user added the current user as contact |
|
|
||||||
|
|
||||||
`blocked` acts as a blacklist. If `blocked` is `true`, `added`, `mutualContact` and `requestReceived` are ignored.
|
|
||||||
|
|
||||||
`mutualContact` is set to `true` once `added` is `true` and `requestReceived` is also set to `true`. This is a utility property to simplify the clients' use.
|
|
||||||
|
|
||||||
#### Contact Request
|
#### Contact Request
|
||||||
|
|
||||||
Users can only chat with another in one to one channels while being mutal contacts. To do so, they need to send contact requests.
|
Users can only chat with another in one to one channels while being mutual contacts. To do so, they need to send contact requests.
|
||||||
|
|
||||||
When adding another account as a contact, a `Contact` payload is sent to the other containing the `requestReceived` flag set to `true`, a `message` object and a `signature`.
|
When adding another account as a contact, a `ContactRequestSignature` payload is sent to the other, either on a `ContactRequest` or a `Message` object.
|
||||||
|
|
||||||
That `signature` is kept in the database and is sent in one to one messages to prove that we were once added as a contact. See `Message` payload for more information.
|
That `ContactRequestSignature` is kept in the database and is sent in one to one messages to prove that we were once added as a contact. See `Message` payload for more information.
|
||||||
|
|
||||||
When the other account accepts the contact request, the same `Contact` payload with `requestReceived` set to `true` is sent.
|
|
||||||
When `requestReceived: true` is reeived and `added` was previously set to `true`, `mutualContact` is also set to `true`.
|
|
||||||
|
|
||||||
##### Backwards compatibility
|
##### Backwards compatibility
|
||||||
|
|
||||||
|
@ -394,29 +380,6 @@ Old versions will not understand the contact request, but will still get the mes
|
||||||
|
|
||||||
Newer versions will ignore the message since it is not from a contact, but the contact request will be processed as above.
|
Newer versions will ignore the message since it is not from a contact, but the contact request will be processed as above.
|
||||||
|
|
||||||
#### Contacts persistence
|
|
||||||
|
|
||||||
Contacts are lost when an account is reset and re-imported. To remedy this situation, the contacts will be sent as a payload to the topic bearing the user's public key followed by `-contacts`. eg: `0x0401d01625bba5d6f0e576519ac6c1b4f343b15fdf2916815ab059d18c51ff826bf23fffff0aa33643140aa3762ab627c4718693a9a0dbf4e84f4429a454136856-contacts`.
|
|
||||||
|
|
||||||
This payload is to be sent only once per day on login and only when the `contacts_dirty` field of `contacts_sync` is set to `true`. The last send date will be kept in `contacts_sync` as `last_sent`.
|
|
||||||
|
|
||||||
The last payload is going to be fetched before sending. That payload is going to be compared to the current contacts using the `lastUpdated` field.
|
|
||||||
|
|
||||||
Again, the fetching of the payload is done once per day using `last_fetched` in `contacts_sync`.
|
|
||||||
|
|
||||||
The payload is an array of the Contacts table items, but only containing contacts that have `added` or `blocked` set as `true`.
|
|
||||||
|
|
||||||
##### Contacts Sync
|
|
||||||
|
|
||||||
The `contacts_sync` table is used to keep the last timestamps of when the contacts payload were sent and fetched to and from the topic.
|
|
||||||
|
|
||||||
It has three columns, `last_sent` and `last_fetched`, both containing a `uint64`, and `contacts_dirty` as a `bool`.
|
|
||||||
|
|
||||||
`last_sent` and `last_fetched` are the timestamps for the last time the payload was sent and fetched, and are used to make sure those actions are only done once per day.
|
|
||||||
|
|
||||||
The `contacts_dirty` field is set to `true` whenever a contact is changed by the user. A change is anything that changes the `added`, `blocked` or `mutualContact` properties of a contact.
|
|
||||||
After sending the payload with the updated contacts, the `contacts_dirty` field is set back to `false`.
|
|
||||||
|
|
||||||
### EmojiReaction
|
### EmojiReaction
|
||||||
|
|
||||||
`EmojiReaction`s represents a user's "reaction" to a specific chat message. For more information about the concept of
|
`EmojiReaction`s represents a user's "reaction" to a specific chat message. For more information about the concept of
|
||||||
|
|
Loading…
Reference in New Issue