Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions 17.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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).

Expand All @@ -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
{
Expand All @@ -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>"
}
Expand All @@ -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.
Expand Down