mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-09 22:09:06 -05:00
Simplify nip 29 even further
This commit is contained in:
parent
37a02e817b
commit
6f2327cb77
6
18.md
6
18.md
|
@ -25,6 +25,12 @@ quote reposted. The `q` tag ensures quote reposts are not pulled and included
|
|||
as replies in threads. It also allows you to easily pull and count all of the
|
||||
quotes for a post.
|
||||
|
||||
Quote tags should have following form:
|
||||
|
||||
`["q", "<event-id>", "<relay-url>", "<author-pubkey>"]`
|
||||
|
||||
Only the event id is REQUIRED, but relay url and author pubkey are RECOMMENDED.
|
||||
|
||||
## Generic Reposts
|
||||
|
||||
Since `kind 6` reposts are reserved for `kind 1` contents, we use `kind 16`
|
||||
|
|
268
29.md
268
29.md
|
@ -6,209 +6,153 @@ Relay-based Groups
|
|||
|
||||
`draft` `optional`
|
||||
|
||||
This NIP defines a standard for groups that are only writable by a closed set of users. They can be public for reading by external users or not.
|
||||
This NIP defines a standard for the simplest version of groups that can work.
|
||||
|
||||
Groups are identified by a random string of any length that serves as an _id_.
|
||||
There are two goals of this NIP:
|
||||
|
||||
There is no way to create a group, what happens is just that relays (most likely when asked by users) will create rules around some specific ids so these ids can serve as an actual group, henceforth messages sent to that group will be subject to these rules.
|
||||
- Define some conventions for how to use standard relays as groups.
|
||||
- Introduces a mechanism for splitting relay content into multiple rooms.
|
||||
|
||||
Normally a group will originally belong to one specific relay, but the community may choose to move the group to other relays or even fork the group so it exists in different forms -- still using the same _id_ -- across different relays.
|
||||
# Relays as groups
|
||||
|
||||
## Relay-generated events
|
||||
## Minus Tag
|
||||
|
||||
Relays are supposed to generate the events that describe group metadata and group admins. These are _addressable_ events signed by the relay keypair directly, with the group _id_ as the `d` tag.
|
||||
To ensure all messages have the appropriate context and/or are not replicated to other relays, a [NIP 70](70.md) `-` tag SHOULD be used when posting to a group relay (if support is indicated per [NIP 11](11.md)). "Follower" relays intended to back up group state MAY bypass this restriction.
|
||||
|
||||
## Group identifier
|
||||
## Relay Migration
|
||||
|
||||
A group may be identified by a string in the format `<host>'<group-id>`. For example, a group with _id_ `abcdef` hosted at the relay `wss://groups.nostr.com` would be identified by the string `groups.nostr.com'abcdef`.
|
||||
|
||||
## The `h` tag
|
||||
|
||||
Events sent by users to groups (chat messages, text notes, moderation events etc) must have an `h` tag with the value set to the group _id_.
|
||||
|
||||
## Timeline references
|
||||
|
||||
In order to not be used out of context, events sent to these groups may contain references to previous events seen from the same relay in the `previous` tag. The choice of which previous events to pick belongs to the clients. The references are to be made using the first 8 characters (4 bytes) of any event in the last 50 events seen by the user in the relay, excluding events by themselves. There can be any number of references (including zero), but it's recommended that clients include at least 3 and that relays enforce this.
|
||||
|
||||
This is a hack to prevent messages from being broadcasted to external relays that have forks of one group out of context. Relays are expected to reject any events that contain timeline references to events not found in their own database. Clients should also check these to keep relays honest about them.
|
||||
|
||||
## Late publication
|
||||
|
||||
Relays should prevent late publication (messages published now with a timestamp from days or even hours ago) unless they are open to receive a group forked or moved from another relay.
|
||||
|
||||
## Event definitions
|
||||
|
||||
- *text root note* (`kind:11`)
|
||||
|
||||
This is the basic unit of a "microblog" root text note sent to a group.
|
||||
|
||||
```jsonc
|
||||
"kind": 11,
|
||||
"content": "hello my friends lovers of pizza",
|
||||
"tags": [
|
||||
["h", "<group-id>"],
|
||||
["previous", "<event-id-first-chars>", "<event-id-first-chars>", /*...*/]
|
||||
]
|
||||
// other fields...
|
||||
```
|
||||
|
||||
- *threaded text reply* (`kind:12`)
|
||||
|
||||
This is the basic unit of a "microblog" reply note sent to a group. It's the same as `kind:11`, except for the fact that it must be used whenever it's in reply to some other note (either in reply to a `kind:11` or a `kind:12`). `kind:12` events SHOULD use NIP-10 markers, leaving an empty relay url:
|
||||
|
||||
* `["e", "<kind-11-root-id>", "", "root"]`
|
||||
* `["e", "<kind-12-event-id>", "", "reply"]`
|
||||
|
||||
- *chat message* (`kind:9`)
|
||||
|
||||
This is the basic unit of a _chat message_ sent to a group.
|
||||
|
||||
```jsonc
|
||||
"kind": 9,
|
||||
"content": "hello my friends lovers of pizza",
|
||||
"tags": [
|
||||
["h", "<group-id>"],
|
||||
["previous", "<event-id-first-chars>", "<event-id-first-chars>", /*...*/]
|
||||
]
|
||||
// other fields...
|
||||
```
|
||||
|
||||
- *chat message threaded reply* (`kind:10`)
|
||||
|
||||
Similar to `kind:12`, this is the basic unit of a chat message sent to a group. This is intended for in-chat threads that may be hidden by default. Not all in-chat replies MUST use `kind:10`, only when the intention is to create a hidden thread that isn't part of the normal flow of the chat (although clients are free to display those by default too).
|
||||
|
||||
`kind:10` SHOULD use NIP-10 markers, just like `kind:12`.
|
||||
|
||||
- *join request* (`kind:9021`)
|
||||
|
||||
Any user can send one of these events to the relay in order to be automatically or manually added to the group. If the group is `open` the relay will automatically issue a `kind:9000` in response adding this user. Otherwise group admins may choose to query for these requests and act upon them.
|
||||
If a group needs to be moved from one relay to another, this can be done by publishing a `kind xxxxx`, with a `from` tag indicating the current relay, and a `to` tag indicating the next relay:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 9021,
|
||||
"content": "optional reason",
|
||||
"kind": "xxxxx",
|
||||
"tags": [
|
||||
["h", "<group-id>"]
|
||||
]
|
||||
["from", "wss://relay.dead.com/"],
|
||||
["to", "wss://relay.live.com/"],
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
- *leave request* (`kind:9022`)
|
||||
These events SHOULD be published to the group's current relay, and MAY be published more broadly if more durability is desired (for example in the case where the relay goes down permanently before the migration is published). Anyone MAY publish these events, but end-users SHOULD be given ultimate discretion as to whether the migration is valid, based on group membership or admin status.
|
||||
|
||||
Any user can send one of these events to the relay in order to be automatically removed from the group. The relay will automatically issue a `kind:9001` in response removing this user.
|
||||
## Policy
|
||||
|
||||
Policy based on which NIPs/kinds are supported by a given relay should be advertised as defined in [NIP 11](11.md).
|
||||
|
||||
## Access Control
|
||||
|
||||
Access control (both read and write) SHOULD be implemented using [NIP 42](42.md) AUTH.
|
||||
|
||||
Access control policy MAY be advertised (but should not be relied upon by clients) using the `auth_required` and `restricted_writes` keys in the `limitations` section of the relay's NIP 11 document.
|
||||
|
||||
After authentication, users MAY request access using a `ACCESS` message sent ONLY to the relay in question. Relay access requests MUST have a `claim` containing an arbitrary string and an optional message to the relay admin.
|
||||
|
||||
```json
|
||||
["ACCESS", "<claim>", "<message>"]
|
||||
```
|
||||
|
||||
Users may also send an empty `ACCESS` message to query their current access:
|
||||
|
||||
```json
|
||||
["ACCESS"]
|
||||
```
|
||||
|
||||
In either case, a relay MUST respond with an `ACCESS` message with a list of user permissions, in addition to the standard `OK` message. Some examples:
|
||||
|
||||
```json
|
||||
["ACCESS"]
|
||||
["ACCESS", "read"]
|
||||
["ACCESS", "read", "write"]
|
||||
```
|
||||
|
||||
Valid permissions are `read` and `write`.
|
||||
|
||||
## Moderation
|
||||
|
||||
Relay-based groups have a single admin, identified by the `pubkey` listed in the relay's [NIP 11](11.md) document.
|
||||
|
||||
Any relay member MAY publish a `kind 1984` report to the relay (including a `-` tag if desired/supported). These reports MAY be used by the relay admin to delete events or ban users, or by clients to implement any moderation algorithm desired. Admins or moderators may also choose to escalate reports without banning content by publishing their own `kind 1984` event with the same tags.
|
||||
|
||||
## Membership
|
||||
|
||||
Users MAY track their own group memberships using a [NIP 51](51.md) kind `1xxxx` event. Tags MAY be either public or encrypted with [NIP 44](44.md), depending on user/client preference.
|
||||
|
||||
Membership lists can contain two types of tags: relay memberships (indicated by `r`), and room memberships (indicated by `h`, and including the relay url):
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 9022,
|
||||
"content": "optional reason",
|
||||
"kind": "1xxxx",
|
||||
"tags": [
|
||||
["h", "<group-id>"]
|
||||
]
|
||||
["r", "wss://relay.example.com/"],
|
||||
["r", "wss://relay.other.com/"],
|
||||
["h", "Marlon Brando", "wss://relay.other.com/"],
|
||||
["h", "James Dean", "wss://relay.other.com/"]
|
||||
],
|
||||
}
|
||||
```
|
||||
## Member lists
|
||||
|
||||
- *moderation events* (`kinds:9000-9020`) (optional)
|
||||
A `kind 3xxxx` event is a member list. Anyone MAY publish one, but clients SHOULD only trust lists published by the relay's own pubkey, or by moderators mentioned in the relay's member list event.
|
||||
|
||||
Clients can send these events to a relay in order to accomplish a moderation action. Relays must check if the pubkey sending the event is capable of performing the given action. The relay may discard the event after taking action or keep it as a moderation log.
|
||||
Lists published by regular members MAY be used for convenience in building member list indexes, but should not be trusted or relied upon.
|
||||
|
||||
Member lists should have the following tags:
|
||||
|
||||
- A `d` tag is required so that member lists can be split into pieces, but is semantically meaningless.
|
||||
- An `r` tag indicates the relay's url.
|
||||
- A `p` tag indicates a member and whether they are a moderator.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 90xx,
|
||||
"content": "optional reason",
|
||||
"kind": "3xxxx",
|
||||
"tags": [
|
||||
["h", "<group-id>"],
|
||||
["previous", /*...*/]
|
||||
]
|
||||
["d", "9ce3f91a937"],
|
||||
["r", "wss://relay.example.com/"],
|
||||
["p", "<pubkey>", "<relay-url>"]
|
||||
["p", "<pubkey>", "<relay-url>", "moderator"]
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Each moderation action uses a different kind and requires different arguments, which are given as tags. These are defined in the following table:
|
||||
These events SHOULD be published only to the group relay, and use a `-` tag if supported.
|
||||
|
||||
| kind | name | tags |
|
||||
| --- | --- | --- |
|
||||
| 9000 | `add-user` | `p` (pubkey hex) |
|
||||
| 9001 | `remove-user` | `p` (pubkey hex) |
|
||||
| 9002 | `edit-metadata` | `name`, `about`, `picture` (string) |
|
||||
| 9003 | `add-permission` | `p` (pubkey), `permission` (name) |
|
||||
| 9004 | `remove-permission` | `p` (pubkey), `permission` (name) |
|
||||
| 9005 | `delete-event` | `e` (id hex) |
|
||||
| 9006 | `edit-group-status` | `public` or `private`, `open` or `closed` |
|
||||
| 9007 | `create-group` | |
|
||||
| 9008 | `delete-group` | |
|
||||
## Content retention
|
||||
|
||||
- *group metadata* (`kind:39000`) (optional)
|
||||
Relays are not obligated to retain any content. Relays MAY choose not to support any part of this NIP, for example refusing host member lists in order to protect member privacy.
|
||||
|
||||
This event defines the metadata for the group -- basically how clients should display it. It must be generated and signed by the relay in which is found. Relays shouldn't accept these events if they're signed by anyone else.
|
||||
# Rooms
|
||||
|
||||
If the group is forked and hosted in multiple relays, there will be multiple versions of this event in each different relay and so on.
|
||||
Rooms are defined by an arbitrary string containing any text. Names SHOULD be human-readable, and less than 30 characters.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"kind": 39000,
|
||||
"content": "",
|
||||
"tags": [
|
||||
["d", "<group-id>"],
|
||||
["name", "Pizza Lovers"],
|
||||
["picture", "https://pizza.com/pizza.png"],
|
||||
["about", "a group for people who love pizza"],
|
||||
["public"], // or ["private"]
|
||||
["open"] // or ["closed"]
|
||||
]
|
||||
// other fields...
|
||||
}
|
||||
```
|
||||
|
||||
`name`, `picture` and `about` are basic metadata for the group for display purposes. `public` signals the group can be _read_ by anyone, while `private` signals that only AUTHed users can read. `open` signals that anyone can request to join and the request will be automatically granted, while `closed` signals that members must be pre-approved or that requests to join will be manually handled.
|
||||
|
||||
- *group admins* (`kind:39001`) (optional)
|
||||
|
||||
Similar to the group metadata, this event is supposed to be generated by relays that host the group.
|
||||
|
||||
Each admin gets a label that is only used for display purposes, and a list of permissions it has are listed afterwards. These permissions can inform client building UI, but ultimately are evaluated by the relay in order to become effective.
|
||||
|
||||
The list of capabilities, as defined by this NIP, for now, is the following:
|
||||
|
||||
- `add-user`
|
||||
- `edit-metadata`
|
||||
- `delete-event`
|
||||
- `remove-user`
|
||||
- `add-permission`
|
||||
- `remove-permission`
|
||||
- `edit-group-status`
|
||||
- `delete-group`
|
||||
Anyone MAY publish `kind xxxxx` index events containing `h` tags and the relay on which they exist. This is only a convenience for helping clients build room lists, and shouldn't be relied upon as being accurate or complete. `h` tags MUST indicate what type the room is. Types of rooms and their corresponding event kinds are defined below.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 39001,
|
||||
"content": "list of admins for the pizza lovers group",
|
||||
"kind": "xxxxx",
|
||||
"tags": [
|
||||
["d", "<group-id>"],
|
||||
["p", "<pubkey1-as-hex>", "ceo", "add-user", "edit-metadata", "delete-event", "remove-user"],
|
||||
["p", "<pubkey2-as-hex>", "secretary", "add-user", "delete-event"]
|
||||
]
|
||||
// other fields...
|
||||
}
|
||||
```
|
||||
|
||||
- *group members* (`kind:39002`) (optional)
|
||||
|
||||
Similar to *group admins*, this event is supposed to be generated by relays that host the group.
|
||||
|
||||
It's a NIP-51-like list of pubkeys that are members of the group. Relays might choose to not to publish this information or to restrict what pubkeys can fetch it.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 39002,
|
||||
"content": "list of members for the pizza lovers group",
|
||||
"tags": [
|
||||
["d", "<group-id>"],
|
||||
["p", "<admin1>"],
|
||||
["p", "<member-pubkey1>"],
|
||||
["p", "<member-pubkey2>"],
|
||||
["h", "salamanders", "wss://relay.froglovers.com", "chat"],
|
||||
["h", "frogs", "wss://relay.froglovers.com", "chat"],
|
||||
["h", "frogs", "wss://relay.catlovers.com", "forum"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Storing the list of groups a user belongs to
|
||||
Events posted to rooms MUST include a simple `h` tag matching the room of the form `["h", "<room-name>"]`. An empty string MAY be used to indicate the "global" namespace.
|
||||
|
||||
A definition for kind `10009` was included in [NIP-51](51.md) that allows clients to store the list of groups a user wants to remember being in.
|
||||
## Chat
|
||||
|
||||
Two kinds of events MAY be posted to a `chat` room:
|
||||
|
||||
- `kind xxx` events are chat root events, and MUST only be used for top-level messages sent to the room.
|
||||
- `kind xxx` events are chat reply events, and MUST only be used for replies to messages in the same room.
|
||||
|
||||
In both cases, conventions for `kind 1` notes outlined in [NIP 10](10.md) and [NIP 18](18.md) should be followed when constructing chat events.
|
||||
|
||||
## Forums
|
||||
|
||||
Two kinds of events MAY be posted to a `forum` room:
|
||||
|
||||
- `kind xxx` events are root thread events, and MUST only be used for the first post in a thread.
|
||||
- `kind xxx` events are thread reply events, and MUST only be used to reply to a _root_ thread event.
|
||||
|
||||
In both cases, conventions for `kind 1` notes outlined in [NIP 10](10.md) and [NIP 18](18.md) should be followed when constructing chat events.
|
||||
|
|
Loading…
Reference in New Issue
Block a user