nips/51.md

7.5 KiB

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 (the shared key is computed using the author's public and private key) and stored in the .content.

Types of lists

Generic lists

The kind 30001 has been reserved for generic lists. These must be accompanied by a d tag identifying the list, but these have no standard meaning and are generally client-specific (except in the standard cases specified below).

Standard lists

Users are expected to have a single list of each of these types. They have special meaning and clients may rely on them to augment the user 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 "d" tag description expected tag items
Mute list 10000 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 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
Relay sets 30002 user-defined relay groups the user can easily pick and choose from during variadic operations "relay" (relay URLs)
Article 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 above:

  • kind:30000 and d "mute"
kind "d" tag use instead
30000 "mute" kind 10000 mute list

Examples

A mute list with some public items and some encrypted items

{
  "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 communities list with just public items

{
  "id": "da6b18c5452b5a60bf49588fc13ae4d1a047519c13e49a77b3184e6188c7bb1c",
  "pubkey": "83fd07de9b763334cc9d46f2785c2558e6c2eabfe7d0c6ec214667cbaec50d47",
  "created_at": 1689082210,
  "kind": 30001,
  "tags": [
    [
      "d",
      "communities"
    ],
    [
      "a",
      "34550:83fd07de9b763334cc9d46f2785c2558e6c2eabfe7d0c6ec214667cbaec50d47:meme"
    ],
    [
      "a",
      "34550:b9a537523bba2fcdae857d90d8a760de4f2139c9f90d986f747ce7d0ec0d173d:NoBullshitBitcoin"
    ]
  ],
  "content": "",
  "sig": "e400cc8bf24955243137e4456b22142fdff400a7950cf0b0ac2ee86ed78671e2fddf9a9b40c77ccf8397f9c21d608b3fab3678ff13713fc3f97a4394cf766079"
}

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

val private_items = [
  ["p", "07caba282f76441955b695551c3c5c742e5b9202a3784780f8086fdcdc1da3a9"],
  ["a", "a55c15f5e41d5aebd236eca5e0142789c5385703f1a7485aa4b38d94fd18dcc4"],
]
val base64blob = nip04.encrypt(json.encode_to_string(private_items))
event.content = base64blob