upleb.uk

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

summaryrefslogtreecommitdiff
path: root/51.md
blob: b184f4285d1fa792f9b8ea4f396774c3d61a7158 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
```