diff options
| author | Vitor Pamplona <vitor@vitorpamplona.com> | 2025-05-05 09:36:20 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-05 06:36:20 -0700 |
| commit | 86f0da716f15b1f1a5a19a9f900ace499c7bc4e2 (patch) | |
| tree | c6e2128a4a2ffc2be4ebb987ccf2e1a81812e157 | |
| parent | 5b7d3382009332f737bca8fdffce291e8d7935b9 (diff) | |
NIP-17 json formatting fix, text cleanup and more precise language (#1909)
| -rw-r--r-- | 17.md | 79 |
1 files changed, 40 insertions, 39 deletions
| @@ -15,17 +15,17 @@ Kind `14` is a chat message. `p` tags identify one or more receivers of the mess | |||
| 15 | ```jsonc | 15 | ```jsonc |
| 16 | { | 16 | { |
| 17 | "id": "<usual hash>", | 17 | "id": "<usual hash>", |
| 18 | "pubkey": "<sender-pubkey>", | 18 | "pubkey": "<sender-pubkey>", |
| 19 | "created_at": "<current-time>", | 19 | "created_at": "<current-time>", |
| 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>"] // if this is a reply | 24 | ["e", "<kind-14-id>", "<relay-url>"] // if this is a reply |
| 25 | ["subject", "<conversation-title>"], | 25 | ["subject", "<conversation-title>"], |
| 26 | // rest of tags... | 26 | // rest of tags... |
| 27 | ], | 27 | ], |
| 28 | "content": "<message-in-plain-text>", | 28 | "content": "<message-in-plain-text>", |
| 29 | } | 29 | } |
| 30 | ``` | 30 | ``` |
| 31 | 31 | ||
| @@ -65,21 +65,22 @@ Kind `14`s MUST never be signed. If it is signed, the message might leak to rela | |||
| 65 | } | 65 | } |
| 66 | ``` | 66 | ``` |
| 67 | 67 | ||
| 68 | Kind 15 is used for sending encrypted file event messages: | 68 | Kind `15` is used for sending encrypted file event messages: |
| 69 | 69 | ||
| 70 | - `file-type`: Specifies the MIME type of the attached file (e.g., `image/jpeg`, `audio/mpeg`, etc.). | 70 | - `file-type`: Specifies the MIME type of the attached file (e.g., `image/jpeg`, `audio/mpeg`, etc.) before encryption. |
| 71 | - `encryption-algorithm`: Indicates the encryption algorithm used for encrypting the file. Supported algorithms may include `aes-gcm`, `chacha20-poly1305`,`aes-cbc` etc. | 71 | - `encryption-algorithm`: Indicates the encryption algorithm used for encrypting the file. Supported algorithms: `aes-gcm`. |
| 72 | - `decryption-key`: The decryption key that will be used by the recipient to decrypt the file. | 72 | - `decryption-key`: The decryption key that will be used by the recipient to decrypt the file. |
| 73 | - `decryption-nonce`: The decryption nonce that will be used by the recipient to decrypt the file. | 73 | - `decryption-nonce`: The decryption nonce that will be used by the recipient to decrypt the file. |
| 74 | - `content`: The URL of the file (`<file-url>`). | 74 | - `content`: The URL of the file (`<file-url>`). |
| 75 | - `x` containing the SHA-256 hexencoded string of the file. | 75 | - `x` containing the SHA-256 hexencoded string of the encrypted file. |
| 76 | - `size` (optional) size of file in bytes | 76 | - `ox` containing the SHA-256 hexencoded string of the file before encryption. |
| 77 | - `dim` (optional) size of the file in pixels in the form `<width>x<height>` | 77 | - `size` (optional) size of the encrypted file in bytes |
| 78 | - `dim` (optional) size in pixels in the form `<width>x<height>` | ||
| 78 | - `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the client is loading the file | 79 | - `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the client is loading the file |
| 79 | - `thumb` (optional) URL of thumbnail with same aspect ratio (encrypted with the same key, nonce) | 80 | - `thumb` (optional) URL of thumbnail with same aspect ratio (encrypted with the same key, nonce) |
| 80 | - `fallback` (optional) zero or more fallback file sources in case `url` fails | 81 | - `fallback` (optional) zero or more fallback file sources in case `url` fails (encrypted with the same key, nonce) |
| 81 | 82 | ||
| 82 | Just like kind 14, kind `15`s MUST never be signed. | 83 | Just like kind `14`, kind `15`s MUST never be signed. |
| 83 | 84 | ||
| 84 | ## Chat Rooms | 85 | ## Chat Rooms |
| 85 | 86 | ||
| @@ -87,34 +88,34 @@ The set of `pubkey` + `p` tags defines a chat room. If a new `p` tag is added or | |||
| 87 | 88 | ||
| 88 | Clients SHOULD render messages of the same room in a continuous thread. | 89 | Clients SHOULD render messages of the same room in a continuous thread. |
| 89 | 90 | ||
| 90 | An 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. | 91 | An 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 chat room is the subject of the conversation. |
| 91 | 92 | ||
| 92 | ## Encrypting | 93 | ## Encrypting |
| 93 | 94 | ||
| 94 | Following [NIP-59](59.md), the **unsigned** `kind:14` & `kind:15` chat messages must be sealed (`kind:13`) and then gift-wrapped (`kind:1059`) to each receiver and the sender individually. | 95 | Following [NIP-59](59.md), the **unsigned** `kind:14` & `kind:15` chat messages must be sealed (`kind:13`) and then gift-wrapped (`kind:1059`) to each receiver and the sender individually. |
| 95 | 96 | ||
| 96 | ```jsonc | 97 | ```js |
| 97 | { | 98 | { |
| 98 | "id": "<usual hash>", | 99 | "id": "<usual hash>", |
| 99 | "pubkey": randomPublicKey, | 100 | "pubkey": randomPublicKey, |
| 100 | "created_at": randomTimeUpTo2DaysInThePast(), | 101 | "created_at": randomTimeUpTo2DaysInThePast(), |
| 101 | "kind": 1059, // gift wrap | 102 | "kind": 1059, // gift wrap |
| 102 | "tags": [ | 103 | "tags": [ |
| 103 | ["p", receiverPublicKey, "<relay-url>"] // receiver | 104 | ["p", receiverPublicKey, "<relay-url>"] // receiver |
| 104 | ], | 105 | ], |
| 105 | "content": nip44Encrypt( | 106 | "content": nip44Encrypt( |
| 106 | { | 107 | { |
| 107 | "id": "<usual hash>", | 108 | "id": "<usual hash>", |
| 108 | "pubkey": senderPublicKey, | 109 | "pubkey": senderPublicKey, |
| 109 | "created_at": randomTimeUpTo2DaysInThePast(), | 110 | "created_at": randomTimeUpTo2DaysInThePast(), |
| 110 | "kind": 13, // seal | 111 | "kind": 13, // seal |
| 111 | "tags": [], // no tags | 112 | "tags": [], // no tags |
| 112 | "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey), | 113 | "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey), |
| 113 | "sig": "<signed by senderPrivateKey>" | 114 | "sig": "<signed by senderPrivateKey>" |
| 114 | }, | 115 | }, |
| 115 | randomPrivateKey, receiverPublicKey | 116 | randomPrivateKey, receiverPublicKey |
| 116 | ), | 117 | ), |
| 117 | "sig": "<signed by randomPrivateKey>" | 118 | "sig": "<signed by randomPrivateKey>" |
| 118 | } | 119 | } |
| 119 | ``` | 120 | ``` |
| 120 | 121 | ||
| @@ -124,7 +125,7 @@ Clients MUST verify if pubkey of the `kind:13` is the same pubkey on the `kind:1 | |||
| 124 | 125 | ||
| 125 | Clients 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. | 126 | Clients 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. |
| 126 | 127 | ||
| 127 | The 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. | 128 | The 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. |
| 128 | 129 | ||
| 129 | Clients 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 | 130 | Clients 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 |
| 130 | 131 | ||
| @@ -188,7 +189,7 @@ The two final GiftWraps, one to the receiver and the other to the sender, respec | |||
| 188 | "created_at":1703128320, | 189 | "created_at":1703128320, |
| 189 | "kind":1059, | 190 | "kind":1059, |
| 190 | "tags":[ | 191 | "tags":[ |
| 191 | [ "p", "918e2da906df4ccd12c8ac672d8335add131a4cf9d27ce42b3bb3625755f0788"] | 192 | ["p", "918e2da906df4ccd12c8ac672d8335add131a4cf9d27ce42b3bb3625755f0788"] |
| 192 | ], | 193 | ], |
| 193 | "content":"AsqzdlMsG304G8h08bE67dhAR1gFTzTckUUyuvndZ8LrGCvwI4pgC3d6hyAK0Wo9gtkLqSr2rT2RyHlE5wRqbCOlQ8WvJEKwqwIJwT5PO3l2RxvGCHDbd1b1o40ZgIVwwLCfOWJ86I5upXe8K5AgpxYTOM1BD+SbgI5jOMA8tgpRoitJedVSvBZsmwAxXM7o7sbOON4MXHzOqOZpALpS2zgBDXSAaYAsTdEM4qqFeik+zTk3+L6NYuftGidqVluicwSGS2viYWr5OiJ1zrj1ERhYSGLpQnPKrqDaDi7R1KrHGFGyLgkJveY/45y0rv9aVIw9IWF11u53cf2CP7akACel2WvZdl1htEwFu/v9cFXD06fNVZjfx3OssKM/uHPE9XvZttQboAvP5UoK6lv9o3d+0GM4/3zP+yO3C0NExz1ZgFmbGFz703YJzM+zpKCOXaZyzPjADXp8qBBeVc5lmJqiCL4solZpxA1865yPigPAZcc9acSUlg23J1dptFK4n3Tl5HfSHP+oZ/QS/SHWbVFCtq7ZMQSRxLgEitfglTNz9P1CnpMwmW/Y4Gm5zdkv0JrdUVrn2UO9ARdHlPsW5ARgDmzaxnJypkfoHXNfxGGXWRk0sKLbz/ipnaQP/eFJv/ibNuSfqL6E4BnN/tHJSHYEaTQ/PdrA2i9laG3vJti3kAl5Ih87ct0w/tzYfp4SRPhEF1zzue9G/16eJEMzwmhQ5Ec7jJVcVGa4RltqnuF8unUu3iSRTQ+/MNNUkK6Mk+YuaJJs6Fjw6tRHuWi57SdKKv7GGkr0zlBUU2Dyo1MwpAqzsCcCTeQSv+8qt4wLf4uhU9Br7F/L0ZY9bFgh6iLDCdB+4iABXyZwT7Ufn762195hrSHcU4Okt0Zns9EeiBOFxnmpXEslYkYBpXw70GmymQfJlFOfoEp93QKCMS2DAEVeI51dJV1e+6t3pCSsQN69Vg6jUCsm1TMxSs2VX4BRbq562+VffchvW2BB4gMjsvHVUSRl8i5/ZSDlfzSPXcSGALLHBRzy+gn0oXXJ/447VHYZJDL3Ig8+QW5oFMgnWYhuwI5QSLEyflUrfSz+Pdwn/5eyjybXKJftePBD9Q+8NQ8zulU5sqvsMeIx/bBUx0fmOXsS3vjqCXW5IjkmSUV7q54GewZqTQBlcx+90xh/LSUxXex7UwZwRnifvyCbZ+zwNTHNb12chYeNjMV7kAIr3cGQv8vlOMM8ajyaZ5KVy7HpSXQjz4PGT2/nXbL5jKt8Lx0erGXsSsazkdoYDG3U", | 194 | "content":"AsqzdlMsG304G8h08bE67dhAR1gFTzTckUUyuvndZ8LrGCvwI4pgC3d6hyAK0Wo9gtkLqSr2rT2RyHlE5wRqbCOlQ8WvJEKwqwIJwT5PO3l2RxvGCHDbd1b1o40ZgIVwwLCfOWJ86I5upXe8K5AgpxYTOM1BD+SbgI5jOMA8tgpRoitJedVSvBZsmwAxXM7o7sbOON4MXHzOqOZpALpS2zgBDXSAaYAsTdEM4qqFeik+zTk3+L6NYuftGidqVluicwSGS2viYWr5OiJ1zrj1ERhYSGLpQnPKrqDaDi7R1KrHGFGyLgkJveY/45y0rv9aVIw9IWF11u53cf2CP7akACel2WvZdl1htEwFu/v9cFXD06fNVZjfx3OssKM/uHPE9XvZttQboAvP5UoK6lv9o3d+0GM4/3zP+yO3C0NExz1ZgFmbGFz703YJzM+zpKCOXaZyzPjADXp8qBBeVc5lmJqiCL4solZpxA1865yPigPAZcc9acSUlg23J1dptFK4n3Tl5HfSHP+oZ/QS/SHWbVFCtq7ZMQSRxLgEitfglTNz9P1CnpMwmW/Y4Gm5zdkv0JrdUVrn2UO9ARdHlPsW5ARgDmzaxnJypkfoHXNfxGGXWRk0sKLbz/ipnaQP/eFJv/ibNuSfqL6E4BnN/tHJSHYEaTQ/PdrA2i9laG3vJti3kAl5Ih87ct0w/tzYfp4SRPhEF1zzue9G/16eJEMzwmhQ5Ec7jJVcVGa4RltqnuF8unUu3iSRTQ+/MNNUkK6Mk+YuaJJs6Fjw6tRHuWi57SdKKv7GGkr0zlBUU2Dyo1MwpAqzsCcCTeQSv+8qt4wLf4uhU9Br7F/L0ZY9bFgh6iLDCdB+4iABXyZwT7Ufn762195hrSHcU4Okt0Zns9EeiBOFxnmpXEslYkYBpXw70GmymQfJlFOfoEp93QKCMS2DAEVeI51dJV1e+6t3pCSsQN69Vg6jUCsm1TMxSs2VX4BRbq562+VffchvW2BB4gMjsvHVUSRl8i5/ZSDlfzSPXcSGALLHBRzy+gn0oXXJ/447VHYZJDL3Ig8+QW5oFMgnWYhuwI5QSLEyflUrfSz+Pdwn/5eyjybXKJftePBD9Q+8NQ8zulU5sqvsMeIx/bBUx0fmOXsS3vjqCXW5IjkmSUV7q54GewZqTQBlcx+90xh/LSUxXex7UwZwRnifvyCbZ+zwNTHNb12chYeNjMV7kAIr3cGQv8vlOMM8ajyaZ5KVy7HpSXQjz4PGT2/nXbL5jKt8Lx0erGXsSsazkdoYDG3U", |
| 194 | "sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480" | 195 | "sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480" |
| @@ -202,7 +203,7 @@ The two final GiftWraps, one to the receiver and the other to the sender, respec | |||
| 202 | "created_at":1702711587, | 203 | "created_at":1702711587, |
| 203 | "kind":1059, | 204 | "kind":1059, |
| 204 | "tags":[ | 205 | "tags":[ |
| 205 | [ "p", "44900586091b284416a0c001f677f9c49f7639a55c3f1e2ec130a8e1a7998e1b"] | 206 | ["p", "44900586091b284416a0c001f677f9c49f7639a55c3f1e2ec130a8e1a7998e1b"] |
| 206 | ], | 207 | ], |
| 207 | "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", | 208 | "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", |
| 208 | "sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab" | 209 | "sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab" |