upleb.uk

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

summaryrefslogtreecommitdiff
path: root/26.md
diff options
context:
space:
mode:
Diffstat (limited to '26.md')
-rw-r--r--26.md42
1 files changed, 31 insertions, 11 deletions
diff --git a/26.md b/26.md
index 7ccf453..658a6ea 100644
--- a/26.md
+++ b/26.md
@@ -10,21 +10,41 @@ A special event with kind `10001`, meaning "relay list" is defined as having a l
10 10
11The content is not used. 11The content is not used.
12 12
13The 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. 13The 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.
14 14
15The "read" condition consists of a string containing a rule that follows a subset of the [runes](https://pypi.org/project/runes/) language. Specifically only the `|`, `&`, `!`, `>`, `<`, and `=` operators are allowed. When the rule is an empty string it evaluates to `true`. When it consists of a single naked `"!"` it evaluates to `false`. The `#` specifically must not be interpreted as a comment, but always as a tag attribute. All the operatores 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. In the case of events tags must also be identified by the `#` prefix, just like in filters. 15The _read_ condition consists of a string containing a rule that follows a subset of the [runes](https://pypi.org/project/runes/) language. Specifically only the `|`, `&`, `!`, `>`, `<`, `/` and `=` operators are allowed. When the rule is an empty string it evaluates to `true`. When it consists of a single naked `"!"` it evaluates to `false`. All the operatores 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.
16 16
17The `read` rule operates on the values of the [NIP-01](01.md) **filter** object, while the `write` rule operates on the values of the **event** object. 17The `read` rule operates on the values of the [NIP-01](01.md) **filter** object, while the `write` rule operates on the values of the **event** object.
18 18
19When a `read` rule evaluates to `true` for a given **filter** the client SHOULD send a `REQ` message to the relay, otherwise it SHOULD NOT. When a `write` rule evaluates to `true` for a given **event** the client SHOULD send that event (in a `EVENT` message) to the relay, otherwise it MUST NOT. 19When a `read` rule evaluates to `true` for a given **filter** the client SHOULD send a `REQ` message to the relay, otherwise it SHOULD NOT. When a `write` rule evaluates to `true` for a given **event** the client SHOULD send that event (in a `EVENT` message) to the relay, otherwise it MUST NOT.
20 20
21When 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.
22
23### Purposes
24
25This 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.
26
27The 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 coon global relay and start using their relays list without having to set everything up again.
28
29For 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.
30
31### Use cases
32
33A 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:
34
35 - "do not use this relay for DMs": sets _write_ to `kind/4`
36 - "only use this relay for DMs": sets _write_ to `kind=4` and _read_ to `kinds=4`
37 - "this is Bob's personal relay, only use it to fetch Bob's events": sets _write_ to `!` and _read_ to `authors=<bob-pubkey>`
38 - "this relay is full of spambots, do not get note replies from this relay": sets _read_ to `(kinds=1&e!)|kinds/1`
39 - "this is my personal relay, only store my stuff in it": sets _read_ to `authors=<my-pubkey>` _write_ to `pubkey=<my-pubkey>`
40
21### Examples 41### Examples
22 42
23(Public keys are shortened to 3 characters for readability.) 43(Public keys are shortened to 3 characters for readability.)
24 44
25- Rule evaluation examples: 45- Rule evaluation examples:
26 46
27 - **read** 47 - _read_
28 48
29 - for the filter `{"kinds": [0, 1, 2, 3], "authors": ["abcd", "1234"]}` 49 - for the filter `{"kinds": [0, 1, 2, 3], "authors": ["abcd", "1234"]}`
30 50
@@ -33,13 +53,13 @@ When a `read` rule evaluates to `true` for a given **filter** the client SHOULD
33 - `authors=7890`: `false` 53 - `authors=7890`: `false`
34 - `authors=7890|authors=1234`: `true` 54 - `authors=7890|authors=1234`: `true`
35 - `authors=7890&authors=1234`: `false` 55 - `authors=7890&authors=1234`: `false`
36 - `#e!`: `true` 56 - `e!`: `true`
37 - `#e=5555`: `false` 57 - `e=5555`: `false`
38 - `kinds=1|kinds=4`: `true` 58 - `kinds=1|kinds=4`: `true`
39 - `kinds<2`: `true` 59 - `kinds<2`: `true`
40 - `kinds>7`: `false` 60 - `kinds>7`: `false`
41 61
42 - **write** 62 - _write_
43 63
44 - for the event `{"kind": 7, "content": "banana", "tags": ["p", "6677"], "created_at": 123456789, "pubkey": "e3e3"}` 64 - for the event `{"kind": 7, "content": "banana", "tags": ["p", "6677"], "created_at": 123456789, "pubkey": "e3e3"}`
45 65
@@ -47,8 +67,8 @@ When a `read` rule evaluates to `true` for a given **filter** the client SHOULD
47 - `!`: `false` 67 - `!`: `false`
48 - `pubkey=7890`: `false` 68 - `pubkey=7890`: `false`
49 - `pubkey=e3e3`: `true` 69 - `pubkey=e3e3`: `true`
50 - `kind=7&#p=6677`: `true` 70 - `kind=7&p=6677`: `true`
51 - `created_at>999999999|#e=5a5a`: `false` 71 - `created_at>999999999|e=5a5a`: `false`
52 72
53- Full example of a kind 10001 event: 73- Full example of a kind 10001 event:
54 74
@@ -56,9 +76,9 @@ When a `read` rule evaluates to `true` for a given **filter** the client SHOULD
56{ 76{
57 "kind": 10001, 77 "kind": 10001,
58 "tags": [ 78 "tags": [
59 ["wss://alicerelay.com/", "#", ""], 79 ["wss://alicerelay.com/", "", ""],
60 ["wss://bobrelay.com/", "authors=ef87", "#"], 80 ["wss://bobrelay.com/", "authors=ef87", "!"],
61 ["wss://carolrelay.com/", "#", "#"], 81 ["wss://carolrelay.com/", "", ""],
62 ], 82 ],
63 "content": "", 83 "content": "",
64 ...other fields 84 ...other fields