nips/23.md
fiatjaf 56cc238a41
text fixes.
Co-authored-by: Leo Wandersleb <leo@leowandersleb.de>
2022-08-14 20:22:16 -03:00

4.7 KiB

NIP-23

Relays List

draft optional author:fiatjaf author:cameri author:monlovesmango author:giszmo

A special event with kind 10001, meaning "relay list" is defined as having a list of tags, one for each relay the author uses.

The content is not used.

The tags consist of arrays of 3 elements: the first is the relay URL, the second is the read condition, the third is the write condition.

The read condition consists of a string containing a rule that follows a subset of the runes language. Specifically only the |, &, !, >, <, / and = operators are allowed. When the rule is an empty string it evaluates to true. All the operators must be tested against all possible values in the case of filter values that consist of lists of values and also in the case of event tags that can have multiple values for the same tag -- in other words, the = may be interpreted as a values.any(v => v == runeValue) instead of an values == runeValue operator; the < may be interpreted as a values.any(v => v < runeValue) and so on. Event tags are identified just by their tag key (for example, e or p) without the # prefix used in filters.

The read rule operates on the values of the NIP-01 filter object, while the write rule operates on the values of the event object.

When a read rule evaluates to false for a given filter the client SHOULD NOT send that filter in a REQ message to that relay.

When a write rule evaluates to false for a given event the client SHOULD NOT send that event in an EVENT message to that relay.

When a rule is malformed or the client is unable to parse it for any reason (for example, for not having implemented all the operators) it SHOULD treat it as true if it is a read rule and false if it is a write rule.

Purposes

This NIP serves two purposes: (1) backup and interoperability of relay lists and relay specific rules between clients; and (2) sharing of relay URLs between users.

The first use case is meant to make it so users can open their client -- or different clients -- in different devices and have their list of relays automatically fetched from a default relay and start using their relays list without having to set everything up again.

For the second purpose, if any client decides to, they can show to the user what relays other users are using, suggest that or automatically add these to the user's relay list, this can take into account the rules or more likely not. The possibility of sharing a list of relays in standardized format is good for spreading information about relays and contributes to the censorship-resistance of the network.

Use cases

A client can expose to the user a set of premade rule templates (the user doesn't have to see the rules) for common relay policies, for example:

  • "do not use this relay for DMs": sets write to kind/4
  • "only use this relay for DMs": sets write to kind=4 and read to kinds=4
  • "this is Bob's personal relay, only use it to fetch Bob's events": sets write to ! and read to authors=<bob-pubkey>
  • "this relay is full of spambots, do not get note replies from this relay": sets read to kinds=1&e!|kinds/1
  • "this is my personal relay, only store my stuff in it": sets read to authors=<my-pubkey> write to pubkey=<my-pubkey>

Examples

(Public keys are shortened to 4 characters for readability.)

  • Rule evaluation examples:

    • read

      • for the filter {"kinds": [0, 1, 2, 3], "authors": ["abcd", "1234"]}

        • <empty>: true
        • !: invalid -> true
        • zjhcxb: invalid -> true
        • false: invalid -> true
        • true: invalid -> true
        • authors=7890: false
        • authors=7890|authors=1234: true
        • authors=7890&authors=1234: false
        • e!: true
        • e=5555: false
        • kinds=1|kinds=4: true
        • kinds<2: true
        • kinds>7: false
        • kinds=1|kinds=7&authors=8543|authors=1234: true
    • write

      • for the event {"kind": 7, "content": "banana", "tags": ["p", "6677"], "created_at": 123456789, "pubkey": "e3e3"}

        • <empty>: true
        • !: invalid -> false
        • 7237237: invalid -> false
        • ****: invalid -> false
        • pubkey=7890: false
        • pubkey=e3e3: true
        • kind=7&p=6677: true
        • created_at>999999999|e=5a5a: false
  • Full example of a kind 10001 event:

{
  "kind": 10001,
  "tags": [
    ["wss://alicerelay.com/", "", ""],
    ["wss://bobrelay.com/", "authors=ef87", "!"],
    ["wss://carolrelay.com/", "", ""],
  ],
  "content": "",
  ...other fields