nip17: "seen" event.

This commit is contained in:
fiatjaf 2025-07-29 08:41:38 -03:00
parent 1afb6da049
commit 3d76da368e
1 changed files with 47 additions and 4 deletions

51
17.md
View File

@ -8,7 +8,11 @@ Private Direct Messages
This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encryption and [NIP-59](59.md) seals and gift wraps.
## Direct Message Kind
## Message kinds
Each of these message kinds can be gift-wrapped as described afterwards. Clients have to first unwrap them to then see their kinds.
### Direct Message Kind
Kind `14` is a chat message. `p` tags identify one or more receivers of the message.
@ -31,7 +35,7 @@ Kind `14` is a chat message. `p` tags identify one or more receivers of the mess
`.content` MUST be plain text. Fields `id` and `created_at` are required.
An `e` tag denotes the direct parent message this post is replying to.
An `e` tag denotes the direct parent message this post is replying to.
`q` tags MAY be used when citing events in the `.content` with [NIP-21](21.md).
@ -41,7 +45,7 @@ An `e` tag denotes the direct parent message this post is replying to.
Kind `14`s MUST never be signed. If it is signed, the message might leak to relays and become **fully public**.
## File Message Kind
### File Message Kind
```jsonc
{
@ -59,7 +63,6 @@ Kind `14`s MUST never be signed. If it is signed, the message might leak to rela
["decryption-key", "<decryption-key>"],
["decryption-nonce", "<decryption-nonce>"],
["x", "<the SHA-256 hexencoded string of the file>"],
// rest of tags...
],
"content": "<file-url>"
}
@ -82,6 +85,46 @@ Kind `15` is used for sending encrypted file event messages:
Just like kind `14`, kind `15`s MUST never be signed.
### "Seen" event
An event of kind `30016` that CAN be emitted automatically by a client whenever a chat window is displayed to the user, even if the user hasn't acted on it.
```jsonc
{
"id": "<usual hash>",
"pubkey": "<sender-pubkey>",
"created_at": "<current-time>",
"kind": 30016,
"tags": [
["d", "<subject>"],
["seen", "<latest_message_id>", "<previous_id>", "<...>"]
],
"content": ""
}
```
- `d` must be set to the conversation subject, or it can be empty or omitted in the most common case of a `<subject>` not existing.
- `seen` must be set to the id of the last messages seen. It can contain any number of ids, ordered from the newest to the oldest.
This event SHOULD be discarded whenever a new event is received for the same conversation.
Any messages with timestamp before the last item in the `seen` array are assumed to have been seen.
If there is a gap in the `seen` array that indicates a message may have been missed for whatever reason.
For example:
- `alice` sends message `aaaa`
- `alice` sends message `bbbb`
- `alice` sends message `cccc`
- `bob` sends event with `["seen", "bbbb", "aaaa"]`
- at this point `alice`'s client should display `aaaa` and `bbbb` as seen, `cccc` as unseen
- `alice` sends message `dddd`
- `alice` sends message `eeee`, which is lost due to relay malfunction
- `alice` sends message `ffff`
- `bob` sends event with `["seen", "ffff", "dddd", "cccc"]`
- at this point `alice`'s client should display all messages as seen, except for `eeee` which should be displayed with an error indicator
## Chat Rooms
The set of `pubkey` + `p` tags defines a chat room. If a new `p` tag is added or a current one is removed, a new room is created with a clean message history.