diff options
| -rw-r--r-- | 66.md | 225 |
1 files changed, 35 insertions, 190 deletions
| @@ -6,137 +6,46 @@ Relay Discovery and Liveness Monitoring | |||
| 6 | 6 | ||
| 7 | `draft` `optional` | 7 | `draft` `optional` |
| 8 | 8 | ||
| 9 | You want to find relays. You may want to discover relays based on criteria that's up to date. You may even want to ensure that you have a complete dataset. You probably want to filter relays based on their reported liveness. | 9 | This NIP defines events for relay discovery and the announcement of relay monitors. |
| 10 | 10 | ||
| 11 | In its purest form: | 11 | ## Relay Discovery Events |
| 12 | 12 | ||
| 13 | ```json | 13 | `30166` relay discovery events document relay characteristics inferred either from a relay's [NIP 11](https://github.com/nostr-protocol/nips/blob/master/11.md) document, or via probing. |
| 14 | { | ||
| 15 | "kind": 30166, | ||
| 16 | "created_at": 1722173222, | ||
| 17 | "content": "{}", | ||
| 18 | "tags": [ | ||
| 19 | [ "d", "wss://somerelay.abc/" ] | ||
| 20 | ], | ||
| 21 | "pubkey": "<pubkey>", | ||
| 22 | "sig": "<signature>", | ||
| 23 | "id": "<eventid>" | ||
| 24 | } | ||
| 25 | ``` | ||
| 26 | |||
| 27 | This event signals that the relay at `wss://somerelay.abc/` was reported "online" by `<pubkey>` at timestamp `1722173222`. This event **MAY** be extended upon to include more information. | ||
| 28 | |||
| 29 | ## Kinds | ||
| 30 | `NIP-66` defines two (2) event kinds, `30166` and `10166` | ||
| 31 | |||
| 32 | | kind | name | description | | ||
| 33 | |-------|----------------------------|-----------------------------------------------------------------------------------------| | ||
| 34 | | [30166](#k30166) | Relay Discovery | An addressable event that is published by a monitor when a relay is online | | ||
| 35 | | [10166](#k10166) | Relay Monitor Announcement | An RE that stores data that signals the intent of a pubkey to monitor relays and publish `30166` events at a regular _frequency_ | | ||
| 36 | |||
| 37 | ## Ontology | ||
| 38 | - `Relay Operator`: someone who operates a relay | ||
| 39 | - `Monitor`: A pubkey that monitors relays and publishes `30166` events at the frequency specified in their `10166` event. | ||
| 40 | - `Ad-hoc Monitor`: A pubkey that monitors relays and publishes `30166` events at an irregular frequency. | ||
| 41 | - `Monitor Service`: A group or individual that monitors relays using one or more `Monitors`. | ||
| 42 | - `Check`: a specific data point that is tested or aggregated by a monitor. | ||
| 43 | |||
| 44 | ## `30166`: "Relay Discovery" <a id="k30166"></a> | ||
| 45 | |||
| 46 | ### Summary | ||
| 47 | `30166` is a `NIP-33` addressable event, referred to as a "Relay Discovery" event. These events are optimized with a small footprint for protocol-level relay Discovery. | ||
| 48 | |||
| 49 | ### Purpose | ||
| 50 | Discovery of relays over nostr. | ||
| 51 | 14 | ||
| 52 | ### Schema | 15 | Information corresponding to field in a relay's NIP 11 document MAY contradict actual values if monitors find that a different policy is implemented than is advertised. |
| 53 | 16 | ||
| 54 | #### Content | 17 | `content` MAY include the stringified JSON of the relay's NIP-11 informational document. |
| 55 | `30166` content fields **SHOULD** include the stringified JSON of the relay's NIP-11 informational document. This data **MAY** be provided for informational purposes only. | ||
| 56 | 18 | ||
| 57 | #### `created_at` | 19 | The only required tag is the `d` tag, which MUST be set to the relay's [normalized](https://datatracker.ietf.org/doc/html/rfc3986#section-6) URL. For relays not accessible via URL, a hex-encoded pubkey MAY be used instead. |
| 58 | The `created_at` field in a NIP-66 event should reflect the time when the relay liveness (and potentially other data points) was checked. | ||
| 59 | 20 | ||
| 60 | #### `tags` | 21 | Other tags include: |
| 61 | 22 | ||
| 62 | ##### Meta Tags (unindexed) | 23 | - `rtt-open` - The relay's open round-trip time in milliseconds. |
| 63 | - `rtt-open` The relay's open **round-trip time** in milliseconds. | 24 | - `rtt-read` - The relay's read round-trip time in milliseconds. |
| 64 | - `rtt-read` The relay's read **round-trip time** in milliseconds. | 25 | - `rtt-write` - The relay's write round-trip time in milliseconds. |
| 65 | - `rtt-write` The relay's write **round-trip time** in milliseconds. | 26 | - `n` - The relay's network type. SHOULD be one of `clearnet`, `tor`, `i2p`, `loki` |
| 27 | - `T` - The relay type. Enumerated [relay type](https://github.com/nostr-protocol/nips/issues/1282) formatted as `PascalCase`, e.g. `PrivateInbox` | ||
| 28 | - `N` - NIPs supported by the relay | ||
| 29 | - `R` - Keys corresponding to requirements per [NIP 11](https://github.com/nostr-protocol/nips/blob/master/11.md)'s `limitations` array, including `auth`, `writes`, `pow`, and `payment`. False values should be specified using a `!` prefix, for example `!auth`. | ||
| 30 | - `t` - A topic associated with this relay | ||
| 31 | - `k` - An event kind accepted by the relay | ||
| 32 | - `!k` - An event kind not accepted by the relay | ||
| 33 | - `g` - A [NIP-52](https://github.com/nostr-protocol/nips/blob/master/52.md) geohash | ||
| 34 | - `l` - A language tag | ||
| 66 | 35 | ||
| 67 | _Other `rtt` values **MAY** be present. This NIP should be updated if there is value found in more `rtt` values._ | 36 | Tags with more than one value should be repeated, rather than putting all values in a single tag, for example `[["t", "cats"], ["t", "dogs"]]`, rather than `[["t", "cats", "dogs"]]`. |
| 68 | 37 | ||
| 69 | ##### Single Letter Tags (indexed) | 38 | Example: |
| 70 | - `d` The relay URL/URI. The `#d` tag **must** be included in the `event.tags[]` array. Index position `1` **must** be the relay websocket URL/URI. If a URL it **SHOULD** be [normalized](https://datatracker.ietf.org/doc/html/rfc3986#section-6). For relays not accessible via conventional means but rather by an npub/pubkey, an npub/pubkey **MAY** be used in place of a URL. | ||
| 71 | ```json | ||
| 72 | [ "d", "wss://somerelay.abc/"] | ||
| 73 | ``` | ||
| 74 | 39 | ||
| 75 | - `n`: Network | ||
| 76 | ```json | ||
| 77 | [ "n", "clearnet" ] | ||
| 78 | ``` | ||
| 79 | |||
| 80 | - `T`: Relay Type. Enumerated [relay type](https://github.com/nostr-protocol/nips/issues/1282) formatted as `PascalCase` | ||
| 81 | ```json | ||
| 82 | ["T", "PrivateInbox" ] | ||
| 83 | ``` | ||
| 84 | |||
| 85 | - `N`: Supported Nips _From NIP-11 "Informational Document" `nip11.supported_nips[]`_ | ||
| 86 | ```json | ||
| 87 | [ "N", "42" ] | ||
| 88 | ``` | ||
| 89 | |||
| 90 | - `R`: Requirements _NIP-11 "Informational Document" `nip11.limitations.payment_required`, `nip11.limitations.auth_required` and/or any other boolean value within `nip11.limitations[]` that is added in the future_ | ||
| 91 | ```json | ||
| 92 | [ "R", "payment" ], | ||
| 93 | [ "R", "auth" ], | ||
| 94 | ``` | ||
| 95 | Since the nostr protocol does not currently support filtering on whether an indexed tag **is** or **is not** set, to make "public" and "no auth" relays discoverable requires a `!` flag | ||
| 96 | |||
| 97 | ```json | ||
| 98 | [ "R", "!payment" ], //no payment required, is public | ||
| 99 | [ "R", "!auth" ], //no authentication required | ||
| 100 | ``` | ||
| 101 | |||
| 102 | - `t`: "Topics" _From NIP-11 "Informational Document" `nip11.tags[]`_ | ||
| 103 | ```json | ||
| 104 | [ "t", "nsfw" ] | ||
| 105 | ``` | ||
| 106 | |||
| 107 | - `k`: Accepted/Blocked Kinds [`NIP-22`] | ||
| 108 | ```json | ||
| 109 | [ "k", "0" ], | ||
| 110 | [ "k", "3" ], | ||
| 111 | [ "k", "10002" ] | ||
| 112 | ``` | ||
| 113 | |||
| 114 | or for blocked kinds | ||
| 115 | |||
| 116 | ```json | ||
| 117 | [ "k", "!0" ] | ||
| 118 | [ "k", "!3" ], | ||
| 119 | [ "k", "!10002" ] | ||
| 120 | ``` | ||
| 121 | |||
| 122 | - `g`: `NIP-52` `g` tags (geohash) | ||
| 123 | ```json | ||
| 124 | [ "g", "9r1652whz" ] | ||
| 125 | ``` | ||
| 126 | |||
| 127 | - `30166` **MAY** be extended with global tags defined by other NIPs that do no collide with locally defined indices, including but not limited to: `p`, `t`, `e`, `a`, `i` and `l/L`. | ||
| 128 | |||
| 129 | #### Robust Example of a `30166` Event | ||
| 130 | _Relay was online, and you can filter on a number of different tags_ | ||
| 131 | ```json | 40 | ```json |
| 132 | { | 41 | { |
| 133 | "id": "<eventid>", | 42 | "id": "<eventid>", |
| 134 | "pubkey": "<monitor's pubkey>", | 43 | "pubkey": "<monitor's pubkey>", |
| 135 | "created_at": "<created_at [some recent date ...]>", | 44 | "created_at": "<created_at [some recent date ...]>", |
| 136 | "signature": "<signature>", | 45 | "signature": "<signature>", |
| 137 | "content": "{}", | 46 | "content": "<optional nip 11 document>", |
| 138 | "kind": 30166, | 47 | "kind": 30166, |
| 139 | "tags": [ | 48 | "tags": [ |
| 140 | ["d","wss://some.relay/"], | 49 | ["d","wss://some.relay/"], |
| 141 | ["n", "clearnet"], | 50 | ["n", "clearnet"], |
| 142 | ["N", "40"], | 51 | ["N", "40"], |
| @@ -144,64 +53,28 @@ _Relay was online, and you can filter on a number of different tags_ | |||
| 144 | ["R", "!payment"], | 53 | ["R", "!payment"], |
| 145 | ["R", "auth"], | 54 | ["R", "auth"], |
| 146 | ["g", "ww8p1r4t8"], | 55 | ["g", "ww8p1r4t8"], |
| 147 | ["p", "somehexkey..."], | ||
| 148 | ["l", "en", "ISO-639-1"], | 56 | ["l", "en", "ISO-639-1"], |
| 149 | ["t", "nsfw" ], | 57 | ["t", "nsfw" ], |
| 150 | ["rtt-open", 234 ] | 58 | ["rtt-open", 234 ] |
| 151 | ] | 59 | ] |
| 152 | } | 60 | } |
| 153 | ``` | 61 | ``` |
| 154 | 62 | ||
| 155 | ## `10166`: "Relay Monitor Announcement" Events <a id="k10166"></a> | 63 | ## Relay Monitor Announcements |
| 156 | |||
| 157 | ### Summary | ||
| 158 | `10166` is a replacable event herein referred to as "Relay Monitor Announcement" events. These events contain information about a publisher's intent to monitor and publish data as `30166` events. This event is optional and is intended for monitors who intend to provide monitoring services at a regular and predictable frequency. | ||
| 159 | |||
| 160 | ### Purpose | ||
| 161 | To provide a directory of monitors, their intent to publish, their criteria and parameters of monitoring activities. Absence of this event implies the monitor is ad-hoc and does not publish events at a predictable frequency, and relies on mechanisms to infer data integrity, such as web-of-trust. | ||
| 162 | |||
| 163 | ### Schema | ||
| 164 | |||
| 165 | #### Standard Tags | ||
| 166 | |||
| 167 | - `frequency` The frequency **in seconds** at which the monitor publishes events. A string-integer at index `1` represents the expected frequency the monitor will publish `30166` events. There should only be `1` frequency per monitor. | ||
| 168 | 64 | ||
| 169 | ```json | 65 | Kind `10166` relay monitor announcements advertise the author's intent to publish `30166` events. This event is optional and is intended for monitors who intend to provide monitoring services at a regular and predictable frequency. |
| 170 | [ "frequency", "3600" ] | ||
| 171 | ``` | ||
| 172 | 66 | ||
| 173 | - `timeout` (optional) The timeout values for various checks conducted by a monitor. Index `1` is the monitor's timeout in milliseconds. Index `2` describes what test the timeout is used for. If no index `2` is provided, it is inferred that the timeout provided applies to all tests. These values can assist relay operators in understanding data signaled by the monitor in _Relay Discovery Events_. | 67 | Tags include: |
| 174 | ```json | ||
| 175 | [ "timeout", "2000", "open" ], | ||
| 176 | [ "timeout", "2000", "read" ], | ||
| 177 | [ "timeout", "3000", "write" ], | ||
| 178 | [ "timeout", "2000", "nip11" ], | ||
| 179 | [ "timeout", "4000", "ssl" ] | ||
| 180 | ``` | ||
| 181 | 68 | ||
| 182 | #### Indexed Tags | 69 | - `frequency` - The frequency in seconds at which the monitor publishes events. |
| 183 | - `c` "Checks" **SHOULD** be a lowercase string describing the check(s) conducted by a monitor. Due to the rapidly evolving nature of relays, enumeration is organic and not strictly defined. But examples of some checks could be websocket `open/read/write/auth`, `nip11` checks, `dns` and `geo` checks, and and any other checks the monitor may deem useful.. Other checks **MAY** be included. New types of checks **SHOULD** be added to this NIP as they are needed. | 70 | - `timeout` (optional) - The timeout values for various checks conducted by a monitor. Index `1` is the monitor's timeout in milliseconds. Index `2` describes what test the timeout is used for. If no index `2` is provided, it is inferred that the timeout provided applies to all tests. |
| 184 | ```json | 71 | - `c` - a lowercase string describing the checks conducted by a monitor. Examples include `open`, `read`, `write`, `auth`, `nip11`, `dns`, and `geo`. |
| 185 | [ "c", "ws" ], | 72 | - `g` - [NIP-52](https://github.com/nostr-protocol/nips/blob/master/11.md) geohash tag |
| 186 | [ "c", "nip11" ], | ||
| 187 | [ "c", "dns" ], | ||
| 188 | [ "c", "geo" ], | ||
| 189 | [ "c", "ssl" ], | ||
| 190 | ``` | ||
| 191 | 73 | ||
| 192 | - `g`: `NIP-52` `g` tags (geohash) | 74 | Monitors SHOULD also publish a `kind 0` profile and a `kind 10002` relay selections event. |
| 193 | ```json | ||
| 194 | [ "g", "9r1652whz" ] | ||
| 195 | ``` | ||
| 196 | 75 | ||
| 197 | - Any other globally defined indexable tags **MAY** be included as found necessary. | 76 | Example: |
| 198 | 77 | ||
| 199 | ### Other Requirements | ||
| 200 | Monitors **SHOULD** have the following | ||
| 201 | - A published `0` (NIP-1) event | ||
| 202 | - A published `10002` (NIP-65) event that defines the relays the monitor publishes to. | ||
| 203 | |||
| 204 | ### Robust Example of a `10166` Event | ||
| 205 | ```json | 78 | ```json |
| 206 | { | 79 | { |
| 207 | "id": "<eventid>", | 80 | "id": "<eventid>", |
| @@ -209,46 +82,18 @@ Monitors **SHOULD** have the following | |||
| 209 | "created_at": "<created_at [some recent date ...]>", | 82 | "created_at": "<created_at [some recent date ...]>", |
| 210 | "signature": "<signature>", | 83 | "signature": "<signature>", |
| 211 | "content": "", | 84 | "content": "", |
| 212 | "tags": [ | 85 | "tags": [ |
| 213 | |||
| 214 | [ "timeout", "open", "5000" ], | 86 | [ "timeout", "open", "5000" ], |
| 215 | [ "timeout", "read", "3000" ], | 87 | [ "timeout", "read", "3000" ], |
| 216 | [ "timeout", "write", "3000" ], | 88 | [ "timeout", "write", "3000" ], |
| 217 | [ "timeout", "nip11", "3000" ], | 89 | [ "timeout", "nip11", "3000" ], |
| 218 | |||
| 219 | [ "frequency", "3600" ], | 90 | [ "frequency", "3600" ], |
| 220 | |||
| 221 | [ "c", "ws" ], | 91 | [ "c", "ws" ], |
| 222 | [ "c", "nip11" ], | 92 | [ "c", "nip11" ], |
| 223 | [ "c", "ssl" ], | 93 | [ "c", "ssl" ], |
| 224 | [ "c", "dns" ], | 94 | [ "c", "dns" ], |
| 225 | [ "c", "geo" ] | 95 | [ "c", "geo" ] |
| 226 | |||
| 227 | [ "g", "ww8p1r4t8" ] | 96 | [ "g", "ww8p1r4t8" ] |
| 228 | ] | 97 | ] |
| 229 | } | 98 | } |
| 230 | ``` | 99 | ``` |
| 231 | |||
| 232 | ## Methodology | ||
| 233 | |||
| 234 | ### Monitors | ||
| 235 | 1. A _Relay Monitor_ checks the liveness and potentially other attributes of a relay. | ||
| 236 | |||
| 237 | 2. _Relay Monitor_ publishes a kind `30166` note when a relay it is monitoring is online. If the monitor has a `10166` event, events should be published at the frequency defined in their `10166` note. | ||
| 238 | |||
| 239 | _Any pubkey that publishes `30166` events **SHOULD** at a minimum be checking that the relay is available by websocket and behaves like a relay_ | ||
| 240 | |||
| 241 | ### Clients | ||
| 242 | 1. In most cases, a client **SHOULD** filter on `30166` events using either a statically or dynamically defined monitor's `pubkey` and a `created_at` value respective of the monitor's published `frequency`. If the monitor has no stated frequency, other mechanisms should be employed to determine data integrity. | ||
| 243 | |||
| 244 | 2. _Relay Liveness_ is subjectively determined by the client, starting with the `frequency` value of a monitor. | ||
| 245 | |||
| 246 | 3. The liveness of a _Relay Monitor_ can be subjectively determined by detecting whether the _Relay Monitor_ has published events with respect to `frequency` value of any particular monitor. | ||
| 247 | |||
| 248 | 4. The reliability and trustworthiness of a _Relay Monitor_ could be established via web-of-trust, reviews or similar mechanisms. | ||
| 249 | |||
| 250 | ## Risk Mitigation | ||
| 251 | |||
| 252 | - When a client implements `NIP-66` events, the client should have a fallback if `NIP-66` events cannot be located. | ||
| 253 | |||
| 254 | - A `Monitor` or `Ad-hoc Monitor` may publish erroneous `30166` events, intentionally or otherwise. Therefor, it's important to program defensively to limit the impact of such events. This can be achieved with web-of-trust, reviews, fallbacks and/or data-aggregation for example. | ||