second proposal with full runes-like language specification.

This commit is contained in:
fiatjaf 2022-08-13 20:32:41 -03:00
parent dbbb66c6de
commit 418cd859fc

50
26.md
View File

@ -4,25 +4,61 @@ NIP-26
Relays List
-----------
`draft` `optional` `author:fiatjaf`
`draft` `optional` `author:fiatjaf` `author:cameri`
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 -- which if set `"true"` means the client is reading events from that relay --, the third is the "write" condition -- which if set to `"true"` means the user is writing events to that relay.
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.
In the future this NIP will be modified with more fine-grained conditions for writing and reading from relays, based on properties of the filter or of the event respectively, written as strings in a simple language.
The "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.
Example:
The `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.
When 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.
### Examples
(Public keys are shortened to 3 characters for readability.)
- Rule evaluation examples:
- **read**
- for the filter `{"kinds": [0, 1, 2, 3], "authors": ["abcd", "1234"]}`
- `<empty>`: `true`
- `!`: `false`
- `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`
- **write**
- for the event `{"kind": 7, "content": "banana", "tags": ["p", "6677"], "created_at": 123456789, "pubkey": "e3e3"}`
- `<empty>`: `true`
- `!`: `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:
```json
{
"kind": 10001,
"tags": [
["wss://alicerelay.com/", "true", "false"],
["wss://bobrelay.com/", "true", "true"],
["wss://carolrelay.com/", "false", "true"],
["wss://alicerelay.com/", "#", ""],
["wss://bobrelay.com/", "authors=ef87", "#"],
["wss://carolrelay.com/", "#", "#"],
],
"content": "",
...other fields