upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--17.md52
1 files changed, 31 insertions, 21 deletions
diff --git a/17.md b/17.md
index cc04a88..0f51367 100644
--- a/17.md
+++ b/17.md
@@ -6,7 +6,7 @@ Private Direct Messages
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encryption and [NIP-59](59.md) seals and gift wraps. 9This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encryption and [NIP-59](59.md) seals and gift wraps.
10 10
11## Direct Message Kind 11## Direct Message Kind
12 12
@@ -18,7 +18,7 @@ Kind `14` is a chat message. `p` tags identify one or more receivers of the mess
18  "pubkey": "<sender-pubkey>", 18  "pubkey": "<sender-pubkey>",
19 "created_at": now(), 19 "created_at": now(),
20  "kind": 14, 20  "kind": 14,
21  "tags": [ 21  "tags": [
22    ["p", "<receiver-1-pubkey>", "<relay-url>"], 22    ["p", "<receiver-1-pubkey>", "<relay-url>"],
23    ["p", "<receiver-2-pubkey>", "<relay-url>"], 23    ["p", "<receiver-2-pubkey>", "<relay-url>"],
24    ["e", "<kind-14-id>", "<relay-url>", "reply"] // if this is a reply 24    ["e", "<kind-14-id>", "<relay-url>", "reply"] // if this is a reply
@@ -29,19 +29,19 @@ Kind `14` is a chat message. `p` tags identify one or more receivers of the mess
29} 29}
30``` 30```
31 31
32`.content` MUST be plain text. Fields `id` and `created_at` are required. 32`.content` MUST be plain text. Fields `id` and `created_at` are required.
33 33
34Tags that mention, quote and assemble threading structures MUST follow [NIP-10](10.md). 34Tags that mention, quote and assemble threading structures MUST follow [NIP-10](10.md).
35 35
36Kind `14`s MUST never be signed. If it is signed, the message might leak to relays and become **fully public**. 36Kind `14`s MUST never be signed. If it is signed, the message might leak to relays and become **fully public**.
37 37
38## Chat Rooms 38## Chat Rooms
39 39
40The 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 clean message history. 40The 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 clean message history.
41 41
42Clients SHOULD render messages of the same room in a continuous thread. 42Clients SHOULD render messages of the same room in a continuous thread.
43 43
44An optional `subject` tag defines the current name/topic of the conversation. Any member can change the topic by simply submitting a new `subject` to an existing `pubkey` + `p`-tags room. There is no need to send `subject` in every message. The newest `subject` in the thread is the subject of the conversation. 44An optional `subject` tag defines the current name/topic of the conversation. Any member can change the topic by simply submitting a new `subject` to an existing `pubkey` + `p`-tags room. There is no need to send `subject` in every message. The newest `subject` in the thread is the subject of the conversation.
45 45
46## Encrypting 46## Encrypting
47 47
@@ -51,7 +51,7 @@ Following [NIP-59](59.md), the **unsigned** `kind:14` chat message must be seale
51{ 51{
52 "id": "<usual hash>", 52 "id": "<usual hash>",
53  "pubkey": randomPublicKey, 53  "pubkey": randomPublicKey,
54  "created_at": randomTimeUpTo2DaysInThePast(), 54  "created_at": randomTimeUpTo2DaysInThePast(),
55 "kind": 1059, // gift wrap 55 "kind": 1059, // gift wrap
56  "tags": [ 56  "tags": [
57    ["p", receiverPublicKey, "<relay-url>"] // receiver 57    ["p", receiverPublicKey, "<relay-url>"] // receiver
@@ -60,7 +60,7 @@ Following [NIP-59](59.md), the **unsigned** `kind:14` chat message must be seale
60    { 60    {
61 "id": "<usual hash>", 61 "id": "<usual hash>",
62      "pubkey": senderPublicKey, 62      "pubkey": senderPublicKey,
63      "created_at": randomTimeUpTo2DaysInThePast(), 63      "created_at": randomTimeUpTo2DaysInThePast(),
64      "kind": 13, // seal 64      "kind": 13, // seal
65      "tags": [], // no tags 65      "tags": [], // no tags
66      "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey), 66      "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey),
@@ -72,17 +72,17 @@ Following [NIP-59](59.md), the **unsigned** `kind:14` chat message must be seale
72} 72}
73``` 73```
74 74
75The encryption algorithm MUST use the latest version of [NIP-44](44.md). 75The encryption algorithm MUST use the latest version of [NIP-44](44.md).
76 76
77Clients MUST verify if pubkey of the `kind:13` is the same pubkey on the `kind:14`, otherwise any sender can impersonate others by simply changing the pubkey on `kind:14`. 77Clients MUST verify if pubkey of the `kind:13` is the same pubkey on the `kind:14`, otherwise any sender can impersonate others by simply changing the pubkey on `kind:14`.
78 78
79Clients SHOULD randomize `created_at` in up to two days in the past in both the seal and the gift wrap to make sure grouping by `created_at` doesn't reveal any metadata. 79Clients SHOULD randomize `created_at` in up to two days in the past in both the seal and the gift wrap to make sure grouping by `created_at` doesn't reveal any metadata.
80 80
81The gift wrap's `p`-tag can be the receiver's main pubkey or an alias key created to receive DMs without exposing the receiver's identity. 81The gift wrap's `p`-tag can be the receiver's main pubkey or an alias key created to receive DMs without exposing the receiver's identity.
82 82
83Clients CAN offer disappearing messages by setting an `expiration` tag in the gift wrap of each receiver or by not generating a gift wrap to the sender's public key 83Clients CAN offer disappearing messages by setting an `expiration` tag in the gift wrap of each receiver or by not generating a gift wrap to the sender's public key
84 84
85## Publishing 85## Publishing
86 86
87Kind `10050` indicates the user's preferred relays to receive DMs. The event MUST include a list of `relay` tags with relay URIs. 87Kind `10050` indicates the user's preferred relays to receive DMs. The event MUST include a list of `relay` tags with relay URIs.
88 88
@@ -98,16 +98,22 @@ Kind `10050` indicates the user's preferred relays to receive DMs. The event MUS
98} 98}
99``` 99```
100 100
101Clients SHOULD publish kind `14` events to the `10050`-listed relays, falling back to `read` relays of [NIP-65](65.md) if `kind:10050` is not available. 101Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is not found that indicates the user is not ready to receive messages under this NIP and clients shouldn't try.
102
103## Relays
104
105It's advisable that relays do not serve `kind:14` to clients other than the ones tagged in them.
106
107It's advisable that users choose relays that conform to these practices.
102 108
103Clients SHOULD guide users to keep `kind:10050` lists small (1-3 relays) and SHOULD spread it to as many relays as viable. 109Clients SHOULD guide users to keep `kind:10050` lists small (1-3 relays) and SHOULD spread it to as many relays as viable.
104 110
105## Benefits & Limitations 111## Benefits & Limitations
106 112
107This NIP offers the following privacy and security features: 113This NIP offers the following privacy and security features:
108 114
1091. **No Metadata Leak**: Participant identities, each message's real date and time, event kinds, and other event tags are all hidden from the public. Senders and receivers cannot be linked with public information alone. 1151. **No Metadata Leak**: Participant identities, each message's real date and time, event kinds, and other event tags are all hidden from the public. Senders and receivers cannot be linked with public information alone.
1102. **No Public Group Identifiers**: There is no public central queue, channel or otherwise converging identifier to correlate or count all messages in the same group. 1162. **No Public Group Identifiers**: There is no public central queue, channel or otherwise converging identifier to correlate or count all messages in the same group.
1113. **No Moderation**: There are no group admins: no invitations or bans. 1173. **No Moderation**: There are no group admins: no invitations or bans.
1124. **No Shared Secrets**: No secret must be known to all members that can leak or be mistakenly shared 1184. **No Shared Secrets**: No secret must be known to all members that can leak or be mistakenly shared
1135. **Fully Recoverable**: Messages can be fully recoverable by any client with the user's private key 1195. **Fully Recoverable**: Messages can be fully recoverable by any client with the user's private key
@@ -115,13 +121,17 @@ This NIP offers the following privacy and security features:
1157. **Uses Public Relays**: Messages can flow through public relays without loss of privacy. Private relays can increase privacy further, but they are not required. 1217. **Uses Public Relays**: Messages can flow through public relays without loss of privacy. Private relays can increase privacy further, but they are not required.
1168. **Cold Storage**: Users can unilaterally opt-in to sharing their messages with a separate key that is exclusive for DM backup and recovery. 1228. **Cold Storage**: Users can unilaterally opt-in to sharing their messages with a separate key that is exclusive for DM backup and recovery.
117 123
118The main limitation of this approach is having to send a separate encrypted event to each receiver. Group chats with more than 100 participants should find a more suitable messaging scheme. 124The main limitation of this approach is having to send a separate encrypted event to each receiver. Group chats with more than 100 participants should find a more suitable messaging scheme.
119 125
120---- 126## Implementation
127
128Clients implementing this NIP should by default only connect to the set of relays found in their `kind:10050` list. From that they should be able to load all messages both sent and received as well as get new live updates, making it for a very simple and lightweight implementation that should be fast.
129
130When sending a message to anyone, clients must then connect to the relays in the receiver's `kind:10050` and send the events there, but can disconnect right after unless more messages are expected to be sent (e.g. the chat tab is still selected). Clients should also send a copy of their outgoing messages to their own `kind:10050` relay set.
121 131
122## Examples 132## Examples
123 133
124This example sends the message `Hola, que tal?` from `nsec1w8udu59ydjvedgs3yv5qccshcj8k05fh3l60k9x57asjrqdpa00qkmr89m` to `nsec12ywtkplvyq5t6twdqwwygavp5lm4fhuang89c943nf2z92eez43szvn4dt`. 134This example sends the message `Hola, que tal?` from `nsec1w8udu59ydjvedgs3yv5qccshcj8k05fh3l60k9x57asjrqdpa00qkmr89m` to `nsec12ywtkplvyq5t6twdqwwygavp5lm4fhuang89c943nf2z92eez43szvn4dt`.
125 135
126The two final GiftWraps, one to the receiver and the other to the sender, are: 136The two final GiftWraps, one to the receiver and the other to the sender, are:
127 137
@@ -138,7 +148,7 @@ The two final GiftWraps, one to the receiver and the other to the sender, are:
138 "sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480" 148 "sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480"
139} 149}
140``` 150```
141 151
142```json 152```json
143{ 153{
144 "id":"162b0611a1911cfcb30f8a5502792b346e535a45658b3a31ae5c178465509721", 154 "id":"162b0611a1911cfcb30f8a5502792b346e535a45658b3a31ae5c178465509721",
@@ -151,4 +161,4 @@ The two final GiftWraps, one to the receiver and the other to the sender, are:
151 "content":"AsTClTzr0gzXXji7uye5UB6LYrx3HDjWGdkNaBS6BAX9CpHa+Vvtt5oI2xJrmWLen+Fo2NBOFazvl285Gb3HSM82gVycrzx1HUAaQDUG6HI7XBEGqBhQMUNwNMiN2dnilBMFC3Yc8ehCJT/gkbiNKOpwd2rFibMFRMDKai2mq2lBtPJF18oszKOjA+XlOJV8JRbmcAanTbEK5nA/GnG3eGUiUzhiYBoHomj3vztYYxc0QYHOx0WxiHY8dsC6jPsXC7f6k4P+Hv5ZiyTfzvjkSJOckel1lZuE5SfeZ0nduqTlxREGeBJ8amOykgEIKdH2VZBZB+qtOMc7ez9dz4wffGwBDA7912NFS2dPBr6txHNxBUkDZKFbuD5wijvonZDvfWq43tZspO4NutSokZB99uEiRH8NAUdGTiNb25m9JcDhVfdmABqTg5fIwwTwlem5aXIy8b66lmqqz2LBzJtnJDu36bDwkILph3kmvaKPD8qJXmPQ4yGpxIbYSTCohgt2/I0TKJNmqNvSN+IVoUuC7ZOfUV9lOV8Ri0AMfSr2YsdZ9ofV5o82ClZWlWiSWZwy6ypa7CuT1PEGHzywB4CZ5ucpO60Z7hnBQxHLiAQIO/QhiBp1rmrdQZFN6PUEjFDloykoeHe345Yqy9Ke95HIKUCS9yJurD+nZjjgOxZjoFCsB1hQAwINTIS3FbYOibZnQwv8PXvcSOqVZxC9U0+WuagK7IwxzhGZY3vLRrX01oujiRrevB4xbW7Oxi/Agp7CQGlJXCgmRE8Rhm+Vj2s+wc/4VLNZRHDcwtfejogjrjdi8p6nfUyqoQRRPARzRGUnnCbh+LqhigT6gQf3sVilnydMRScEc0/YYNLWnaw9nbyBa7wFBAiGbJwO40k39wj+xT6HTSbSUgFZzopxroO3f/o4+ubx2+IL3fkev22mEN38+dFmYF3zE+hpE7jVxrJpC3EP9PLoFgFPKCuctMnjXmeHoiGs756N5r1Mm1ffZu4H19MSuALJlxQR7VXE/LzxRXDuaB2u9days/6muP6gbGX1ASxbJd/ou8+viHmSC/ioHzNjItVCPaJjDyc6bv+gs1NPCt0qZ69G+JmgHW/PsMMeL4n5bh74g0fJSHqiI9ewEmOG/8bedSREv2XXtKV39STxPweceIOh0k23s3N6+wvuSUAJE7u1LkDo14cobtZ/MCw/QhimYPd1u5HnEJvRhPxz0nVPz0QqL/YQeOkAYk7uzgeb2yPzJ6DBtnTnGDkglekhVzQBFRJdk740LEj6swkJ", 161 "content":"AsTClTzr0gzXXji7uye5UB6LYrx3HDjWGdkNaBS6BAX9CpHa+Vvtt5oI2xJrmWLen+Fo2NBOFazvl285Gb3HSM82gVycrzx1HUAaQDUG6HI7XBEGqBhQMUNwNMiN2dnilBMFC3Yc8ehCJT/gkbiNKOpwd2rFibMFRMDKai2mq2lBtPJF18oszKOjA+XlOJV8JRbmcAanTbEK5nA/GnG3eGUiUzhiYBoHomj3vztYYxc0QYHOx0WxiHY8dsC6jPsXC7f6k4P+Hv5ZiyTfzvjkSJOckel1lZuE5SfeZ0nduqTlxREGeBJ8amOykgEIKdH2VZBZB+qtOMc7ez9dz4wffGwBDA7912NFS2dPBr6txHNxBUkDZKFbuD5wijvonZDvfWq43tZspO4NutSokZB99uEiRH8NAUdGTiNb25m9JcDhVfdmABqTg5fIwwTwlem5aXIy8b66lmqqz2LBzJtnJDu36bDwkILph3kmvaKPD8qJXmPQ4yGpxIbYSTCohgt2/I0TKJNmqNvSN+IVoUuC7ZOfUV9lOV8Ri0AMfSr2YsdZ9ofV5o82ClZWlWiSWZwy6ypa7CuT1PEGHzywB4CZ5ucpO60Z7hnBQxHLiAQIO/QhiBp1rmrdQZFN6PUEjFDloykoeHe345Yqy9Ke95HIKUCS9yJurD+nZjjgOxZjoFCsB1hQAwINTIS3FbYOibZnQwv8PXvcSOqVZxC9U0+WuagK7IwxzhGZY3vLRrX01oujiRrevB4xbW7Oxi/Agp7CQGlJXCgmRE8Rhm+Vj2s+wc/4VLNZRHDcwtfejogjrjdi8p6nfUyqoQRRPARzRGUnnCbh+LqhigT6gQf3sVilnydMRScEc0/YYNLWnaw9nbyBa7wFBAiGbJwO40k39wj+xT6HTSbSUgFZzopxroO3f/o4+ubx2+IL3fkev22mEN38+dFmYF3zE+hpE7jVxrJpC3EP9PLoFgFPKCuctMnjXmeHoiGs756N5r1Mm1ffZu4H19MSuALJlxQR7VXE/LzxRXDuaB2u9days/6muP6gbGX1ASxbJd/ou8+viHmSC/ioHzNjItVCPaJjDyc6bv+gs1NPCt0qZ69G+JmgHW/PsMMeL4n5bh74g0fJSHqiI9ewEmOG/8bedSREv2XXtKV39STxPweceIOh0k23s3N6+wvuSUAJE7u1LkDo14cobtZ/MCw/QhimYPd1u5HnEJvRhPxz0nVPz0QqL/YQeOkAYk7uzgeb2yPzJ6DBtnTnGDkglekhVzQBFRJdk740LEj6swkJ",
152 "sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab" 162 "sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab"
153} 163}
154``` 164```