mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-09 22:09:06 -05:00
6c3eebf510
Co-authored-by: hodlbod <jstaab@protonmail.com>
132 lines
6.8 KiB
Markdown
132 lines
6.8 KiB
Markdown
NIP-51
|
|
======
|
|
|
|
Lists
|
|
-----
|
|
|
|
`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema` `author:gzuuus`
|
|
|
|
This NIP defines lists of things that users can create. Lists can contain references to anything, and these
|
|
references can be **public** or **private**.
|
|
|
|
Public items in a list are specified in the event `tags` array, while private items are specified in a JSON
|
|
array that mimics the structure of the event `tags` array, but stringified and encrypted using the same
|
|
scheme from [NIP-04](04.md) (the shared key is computed using the author's public and private key) and
|
|
stored in the `.content`.
|
|
|
|
## Types of lists
|
|
|
|
### Generic lists
|
|
|
|
|
|
## Standard lists
|
|
|
|
Standard lists use non-parameterized replaceable events, meaning users may only have a single list
|
|
of each kind. They have special meaning and clients may rely on them to augment a user's profile or
|
|
browsing experience.
|
|
|
|
For example, _mute lists_ can contain the public keys of spammers and bad actors users don't want to see in
|
|
their feeds or receive annoying notifications from.
|
|
|
|
| name | kind | description | expected tag items |
|
|
| --- | --- | --- | --- |
|
|
| Mute list | 10000 | things the user doesn't want to see in their feeds | `"p"` (pubkeys), `"t"` (hashtags) |
|
|
| Pin list | 10001 | events the user intends to showcase in their profile page | `"e"` (kind:1 notes) |
|
|
| Bookmarks list | 10003 | things the user intends to save for the future | `"e"` (kind:1 notes), `"a"` (kind:30023 articles) |
|
|
| Communities list | 10004 | [NIP-72](72.md) communities the user belongs to | `"a"` (kind:34550 community definitions) |
|
|
|
|
## Sets
|
|
|
|
Sets are lists with well-defined meaning that can enhance the functionality and the UI of clients that rely
|
|
on them. Unlike standard lists, users are expected to have more than one set of each kind, therefore each of
|
|
them must be assigned a different `"d"` identifier.
|
|
|
|
For example, _relay sets_ can be displayed in a dropdown UI to give users the option to switch to which
|
|
relays they will publish an event or from which relays they will read the replies to an event; _curation sets_
|
|
can be used by apps to showcase curations made by others tagged to different topics.
|
|
|
|
Aside from their main identifier, the `"d"` tag, sets can optionally have a `"title"`, an `"image"` and a
|
|
`"description"` tag that can be used to enhance their UI.
|
|
|
|
| name | kind | description | expected tag items |
|
|
| --- | --- | --- | --- |
|
|
| Follow sets | 30000 | categorized groups of users a client may choose to check out in different circumstances | `"p"` (pubkeys) |
|
|
| Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during variadic operations | `"relay"` (relay URLs) |
|
|
| Curation sets | 30004 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles), `"e"` (kind:1 notes) |
|
|
|
|
## Deprecated standard lists
|
|
|
|
Some clients have used these lists in the past, but they should work on transitioning to the [standard formats](#standard-lists) above:
|
|
|
|
| kind | "d" tag | use instead |
|
|
| --- | --- | --- |
|
|
| 30000 | `"mute"` | kind 10000 _mute list_ |
|
|
| 30001 | `"pin"` | kind 10001 _pin list_ |
|
|
| 30001 | `"bookmark"` | kind 10003 _bookmarks list_ |
|
|
| 30001 | `"communities"` | kind 10004 _communities list_ |
|
|
|
|
## Examples
|
|
|
|
### A _mute list_ with some public items and some encrypted items
|
|
|
|
```json
|
|
{
|
|
"id": "a92a316b75e44cfdc19986c634049158d4206fcc0b7b9c7ccbcdabe28beebcd0",
|
|
"pubkey": "854043ae8f1f97430ca8c1f1a090bdde6488bd5115c7a45307a2a212750ae4cb",
|
|
"created_at": 1699597889,
|
|
"kind": 10000,
|
|
"tags": [
|
|
["p", "07caba282f76441955b695551c3c5c742e5b9202a3784780f8086fdcdc1da3a9"],
|
|
["p", "a55c15f5e41d5aebd236eca5e0142789c5385703f1a7485aa4b38d94fd18dcc4"]
|
|
],
|
|
"content": "TJob1dQrf2ndsmdbeGU+05HT5GMnBSx3fx8QdDY/g3NvCa7klfzgaQCmRZuo1d3WQjHDOjzSY1+MgTK5WjewFFumCcOZniWtOMSga9tJk1ky00tLoUUzyLnb1v9x95h/iT/KpkICJyAwUZ+LoJBUzLrK52wNTMt8M5jSLvCkRx8C0BmEwA/00pjOp4eRndy19H4WUUehhjfV2/VV/k4hMAjJ7Bb5Hp9xdmzmCLX9+64+MyeIQQjQAHPj8dkSsRahP7KS3MgMpjaF8nL48Bg5suZMxJayXGVp3BLtgRZx5z5nOk9xyrYk+71e2tnP9IDvSMkiSe76BcMct+m7kGVrRcavDI4n62goNNh25IpghT+a1OjjkpXt9me5wmaL7fxffV1pchdm+A7KJKIUU3kLC7QbUifF22EucRA9xiEyxETusNludBXN24O3llTbOy4vYFsq35BeZl4v1Cse7n2htZicVkItMz3wjzj1q1I1VqbnorNXFgllkRZn4/YXfTG/RMnoK/bDogRapOV+XToZ+IvsN0BqwKSUDx+ydKpci6htDRF2WDRkU+VQMqwM0CoLzy2H6A2cqyMMMD9SLRRzBg==?iv=S3rFeFr1gsYqmQA7bNnNTQ==",
|
|
"sig": "1173822c53261f8cffe7efbf43ba4a97a9198b3e402c2a1df130f42a8985a2d0d3430f4de350db184141e45ca844ab4e5364ea80f11d720e36357e1853dba6ca"
|
|
}
|
|
```
|
|
|
|
### A _curation set_ of articles and notes about yaks
|
|
|
|
```
|
|
{
|
|
"id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef",
|
|
"pubkey": "d6dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c",
|
|
"created_at": 1695327657,
|
|
"kind": 30004,
|
|
"tags": [
|
|
[
|
|
"d",
|
|
"jvdy9i4"
|
|
],
|
|
[
|
|
"title",
|
|
"Yaks"
|
|
],
|
|
[
|
|
"summary",
|
|
"The domestic yak, also known as the Tartary ox, grunting ox, or hairy cattle, is a species of long-haired domesticated cattle found throughout the Himalayan region of the Indian subcontinent, the Tibetan Plateau, Gilgit-Baltistan, Tajikistan and as far north as Mongolia and Siberia."
|
|
],
|
|
[
|
|
"image",
|
|
"https://cdn.britannica.com/40/188540-050-9AC748DE/Yak-Himalayas-Nepal.jpg"
|
|
],
|
|
["a", "30023:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:95ODQzw3ajNoZ8SyMDOzQ"],
|
|
["a", "30023:54af95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:1-MYP8dAhramH9J5gJWKx"],
|
|
["a", "30023:f8fe95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:D2Tbd38bGrFvU0bIbvSMt"],
|
|
["e", "d78ba0d5dce22bfff9db0a9e996c9ef27e2c91051de0c4e1da340e0326b4941e"]
|
|
],
|
|
"content": "",
|
|
"sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd"
|
|
}
|
|
```
|
|
|
|
## Encryption process pseudocode
|
|
|
|
```scala
|
|
val private_items = [
|
|
["p", "07caba282f76441955b695551c3c5c742e5b9202a3784780f8086fdcdc1da3a9"],
|
|
["a", "a55c15f5e41d5aebd236eca5e0142789c5385703f1a7485aa4b38d94fd18dcc4"],
|
|
]
|
|
val base64blob = nip04.encrypt(json.encode_to_string(private_items))
|
|
event.content = base64blob
|
|
```
|