nips/51.md
2023-11-15 07:33:26 -03:00

69 lines
4.6 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`.
## Generic lists
The kinds `30000` and `30001` have been reserved for generic lists. These must be accompanied by a `d` tag identifying the list, but these are generally client-specific, except in the standard cases specified below.
### Standard lists
These are some standards that emerged in the wild:
| name | kind | "d" tag | description | expected tag items |
| --- | --- | --- | --- | --- |
| Mute list | 30000 | `"mute"` | things the user doesn't want to see in their feeds | `"p"` (pubkeys), `"t"` (hashtags) |
| Bookmarks list | 30001 | `"bookmark"` | things the user intends to save for the future | `"e"` (kind:1 notes), `"a"` (kind:30023 articles) |
| Pin list | 30001 | `"pin"` | events the user intends to showcase in their profile page | `"e"` (kind:1 notes) |
| Communities list | 30001 | `"communities"` | [NIP-72](72.md) communities the user belongs to | `"a"` (kind:34550 community definitions) |
## Sets
Sets are lists with well-defined meaning and purpose and user-assigned `d` tags meant to be displayed in the UI. 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; or _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 |
| --- | --- | --- | --- |
| Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during variadic operations | `"relay"` (relay URLs) |
| Article Curation sets | 30003 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles) |
## Examples
### A _mute list_ with some public items and some encrypted items
```json
{
"id": "a92a316b75e44cfdc19986c634049158d4206fcc0b7b9c7ccbcdabe28beebcd0",
"pubkey": "854043ae8f1f97430ca8c1f1a090bdde6488bd5115c7a45307a2a212750ae4cb",
"created_at": 1699597889,
"kind": 30000,
"tags": [
["d", "mute"],
["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"
}
```
## Encryption process pseudocode
```scala
val private_items = [
["p", "07caba282f76441955b695551c3c5c742e5b9202a3784780f8086fdcdc1da3a9"],
["a", "a55c15f5e41d5aebd236eca5e0142789c5385703f1a7485aa4b38d94fd18dcc4"],
]
val base64blob = nip04.encrypt(json.encode_to_string(private_items))
event.content = base64blob
```