Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-51 Lists #183

Merged
merged 18 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions 51.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
NIP-51
======

Lists
-------------------------

`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema` `depends:33`

A "list" event is defined as having a list of public and/or private tags. Public tags will be listed in the event `tags`. Private tags will be encrypted in the event `content`. Encryption for private tags will use [NIP-04 - Encrypted Direct Message](04.md) encryption, using the list author's private and public key for the shared secret. A distinct event kind should be used for each list type created.

If a list type should only be defined once per user (like the 'Mute' list), the list type's events should follow the specification for [NIP-16 - Replaceable Events](16.md). These lists may be referred to as 'replaceable lists'.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this part is needed. do we want to implicitly restrict list types here? I think that part should be handled in separate NIPs, and would allow to follow this model with lists that mix multiple kinds of tags by standardizing d tags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the same spirit we could allow other structured types in the encrypted body - and we should. This leads me to question the purpose of this nip. Maybe it should be more prescriptive, not less? Maybe it should be exclusively about follow, mute and block as that might be something the OP could readily implement and experiment with.

The event pinning and bookmarks might belong into the profile and more structured encrypted data respectively.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if this NIP was only limited to follow, I would still want the type. I would want users to be able to create lists of hashtags, people, and events to follow. however putting those all into one event will be a mess for client implementation. there is no situation where hashtags and follows will be processed together, the client will always have to parse them out and handle them separately.

happy to drop pinned and bookmarks entirely. just threw them in bc seemed like people are itching for these.

Otherwise the list type's events should follow the specification for [NIP-33 - Parameterized Replaceable Events](33.md), where the list name will be used as the 'd' parameter. These lists may be referred to as 'parameterized replaceable lists'.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example, each of these ones (or multiple in batches) would be part of a NIP that references this one and NIP33 and standardizes the use of these names in d tags

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but how would the behavior change between the different lists?

## List Event Kinds

| kind | list type | NIP |
|------|-----------------------------|---------------|
| 10000| Mute | [51a](51a.md) |
| 10001| Pin | [51b](51b.md) |
| 30000| Categorized People | [51c](51c.md) |
| 30001| Categorized Bookmarks | [51d](51d.md) |
## Replaceable List Event Example

Lets say a user wants to create a 'Mute' list and has keys:
```
priv: fb505c65d4df950f5d28c9e4d285ee12ffaf315deef1fc24e3c7cd1e7e35f2b1
pub: b1a5c93edcc8d586566fde53a20bdb50049a97b15483cb763854e57016e0fa3d
```
The user wants to publicly include these users:

```json
["p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"]
```
and privately include these users (below is the JSON that would be encrypted and placed in the event content):

```json
[
["p", "9ec7a778167afb1d30c4833de9322da0c08ba71a69e1911d5578d3144bb56437"],
["p", "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168"]
]
```

Then the user would create a 'Mute' list event like below:

```json
{
"kind": 10000,
"tags": [
["p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"],
],
"content": "VezuSvWak++ASjFMRqBPWS3mK5pZ0vRLL325iuIL4S+r8n9z+DuMau5vMElz1tGC/UqCDmbzE2kwplafaFo/FnIZMdEj4pdxgptyBV1ifZpH3TEF6OMjEtqbYRRqnxgIXsuOSXaerWgpi0pm+raHQPseoELQI/SZ1cvtFqEUCXdXpa5AYaSd+quEuthAEw7V1jP+5TDRCEC8jiLosBVhCtaPpLcrm8HydMYJ2XB6Ixs=?iv=/rtV49RFm0XyFEwG62Eo9A==",
...other fields
}
```


## Parameterized Replaceable List Event Example

Lets say a user wants to create a 'Categorized People' list of `nostr` people and has keys:
```
priv: fb505c65d4df950f5d28c9e4d285ee12ffaf315deef1fc24e3c7cd1e7e35f2b1
pub: b1a5c93edcc8d586566fde53a20bdb50049a97b15483cb763854e57016e0fa3d
```
The user wants to publicly include these users:

```json
["p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"]
```
and privately include these users (below is the JSON that would be encrypted and placed in the event content):

```json
[
["p", "9ec7a778167afb1d30c4833de9322da0c08ba71a69e1911d5578d3144bb56437"],
["p", "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168"]
]
```

Then the user would create a 'Categorized People' list event like below:

```json
{
"kind": 30000,
"tags": [
["d", "nostr"],
["p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"],
],
"content": "VezuSvWak++ASjFMRqBPWS3mK5pZ0vRLL325iuIL4S+r8n9z+DuMau5vMElz1tGC/UqCDmbzE2kwplafaFo/FnIZMdEj4pdxgptyBV1ifZpH3TEF6OMjEtqbYRRqnxgIXsuOSXaerWgpi0pm+raHQPseoELQI/SZ1cvtFqEUCXdXpa5AYaSd+quEuthAEw7V1jP+5TDRCEC8jiLosBVhCtaPpLcrm8HydMYJ2XB6Ixs=?iv=/rtV49RFm0XyFEwG62Eo9A==",
...other fields
}
```


9 changes: 9 additions & 0 deletions 51a.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NIP-51a
======

Mute List
-------------------------

`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema`

An event with kind `10000` is defined as a replaceable list event (see [NIP-51 - Lists](51.md) for listing content a user wants to mute. Any standarized tag can be included in a Mute List.
9 changes: 9 additions & 0 deletions 51b.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NIP-51b
======

Pin List
-------------------------

`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema`

An event with kind `10001` is defined as a replaceable list event (see [NIP-51 - Lists](51.md) for listing content a user wants to pin. Any standarized tag can be included in a Pin List.
9 changes: 9 additions & 0 deletions 51c.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NIP-51c
======

Categorized People List
-------------------------

`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema`

An event with kind `30000` is defined as a parameterized replaceable list event (see [NIP-51 - Lists](51.md)) for categorizing people. The 'd' parameter for this event holds the category name of the list. The tags included in these lists MUST follow the format of kind 3 events as defined in [NIP-02 - Contact List and Petnames](02.md).
9 changes: 9 additions & 0 deletions 51d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NIP-51c
======

Categorized Bookmarks List
-------------------------

`draft` `optional` `author:fiatjaf` `author:arcbtc` `author:monlovesmango` `author:eskema`

An event with kind `30001` is defined as a parameterized replaceable list event (see [NIP-51 - Lists](51.md)) for categorizing bookmarks. The 'd' parameter for this event holds the category name of the list. Any standarized tag can be included in a Categorized Bookmarks List.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
- [NIP-40: Expiration Timestamp](40.md)
- [NIP-42: Authentication of clients to relays](42.md)
- [NIP-50: Keywords filter](50.md)
- [NIP-51: Lists](51.md)
- [NIP-56: Reporting](56.md)
- [NIP-57: Lightning Zaps](57.md)
- [NIP-65: Relay List Metadata](65.md)
Expand All @@ -54,8 +55,12 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
| 1984 | Reporting | [56](56.md) |
| 9734 | Zap Request | [57](57.md) |
| 9735 | Zap | [57](57.md) |
| 10000 | Mute List | [51](51.md) |
| 10001 | Pin List | [51](51.md) |
| 10002 | Relay List Metadata | [65](65.md) |
| 22242 | Client Authentication | [42](42.md) |
| 30000 | Categorized People List | [51](51.md) |
| 30001 | Categorized Bookmark List | [51](51.md) |
| 30023 | Long-form Content | [23](23.md) |
| 1000-9999 | Regular Events | [16](16.md) |
| 10000-19999 | Replaceable Events | [16](16.md) |
Expand Down