diff --git a/59.md b/59.md new file mode 100644 index 00000000..25942cc3 --- /dev/null +++ b/59.md @@ -0,0 +1,100 @@ +# NIP-59: Relay Status + +`draft` `optional` `author:dskvr` + +This NIP defines `30303`, a parameterized replaceable event [NIP-33], referred to as Relay Statuses. Relay Statuses use tags extensively and **may** have `.content` populated with Stringified JSON. + +## Purpose +To store relay meta-data and the result of subjective checks as queryable [NIP-12] events on nostr. + +## Personas +- **Publishers** generate and push `30303` events. Events **should** be published at a regular interval. Events **may** be stale. +- **Consumers** aggregate `30303` for insight on relays. Some example consumers are a social client or relay status client. + +## schema + +### `event.created_at` +`created_at` **should** be interpreted by consumers as `updated_at` + +### `event.tags` +Relay status events have **two** (1) required tags and **eight** (8) optional tags. + +The tags should be used to represent the Relay's abilities and meta at a point in time. Below the `tags schema` is expressed using pseudo-types for reasons of communication and brevity, for example `tagDescriptor[]`. + +1. `"d" == tagId[0]` The relay URL (`#d`). The `#d` tag **must** be included in the `event.tags[]` array. `tagId[1]` **must** be the relay websocket URL. The URL **should** be normalized. +```json +["d", "wss://history.nostr.watch/"] //tagId[] +``` +2. `"o" == tagOnline[0]` Is the relay online (`#o`). `tagOnline[]` **may** be included in the `event.tags[]` array. `tagOnline[1]` **should** be type string as exactly `true` or `false` +```json +["o", "true"] //tagOnline[] +``` +3. `"r" == tagRead[0]` Was able to read from the relay. `tagRead[]` **may** be included in the `event.tags[]` array. `tagRead[1]` **should** be type string as exactly `true` or `false` +```json +["r", "true"] //tagRead[] +``` +4. `"w" == tagWrite[0]` Was able to write to the relay. `tagWrite[]` **may** be included in the `event.tags[]` array. `tagWrite[1]` **should** be type string as exactly `true` or `false` +```json +["w", "false"] //tagWrite[] +``` +5. `"s" == tagSsl[0]` Is the relay's SSL valid (`#s`). `tagSsl[]` **may** be included in the `event.tags[]` array. `tagSsl[1]` **should** be type string as exactly `true` or `false` +```json +["s", "true"] //tagSSL[] +``` +6. `"t" == tagTopic[0]` Topics relavant to the relay. `tagTopic[]` **may** be included in the `event.tags[]` array. `tagTopic[1]` **should** be string +```json +["t", "bitcoin"] //tagTopic[] +``` +7. `"g" == tagGeo[0]` Relay Geo Data. `tagGeo[]` **may** be included in the `event.tags[]` array. `tagGeo[1]` **must** be string. There **may** be strings defined in the key range `2-6` (`tagGeo[2-6]`) and they **must** be strings if set. +```json +["g", "Europe", "NE", "Amsterdam", "52.377956", "4.897070"] //tagGeo[] +``` +8. `"x" == tagIPv4[0]` Relay IPv4. `tagIPv4[]` **may** be included in the `event.tags[]` array. `tagIPv4[1]` **must** be string. +```json +["x", "1.1.1.1"] //tagIPv4[] +``` +9. `"y" == tagIPv6[0]` Relay IPv6. `tagIPv6[]` **may** be included in the `event.tags[]` array. `tagIPv6[1]` **must** be string. +```json +["y", "2001:db8:3333:4444:5555:6666:7777:8888"] //tagIPv6[] +``` + +Example Event: +```json +{ + "id": "", + "pubkey": "", + "created_at": "", + "signature": "", + "content": "{}", + "tags": [ + ["d","wss://relay.snort.social/"], + ["o","true"], + ["r","true"], + ["w","false"], + ["s","true"], + ["t","bitcoin"], + ["t","nostrica"], + ["g","Europe","NE","Amsterdam","52.377956","4.897070"], + ["x", "1.1.1.1"], + ["y", "2001:db8:3333:4444:5555:6666:7777:8888"] + ] +} +``` + +### `event.content` _optional_ +The `.content` of these events **may** be empty. `.content` **may** contain stringified JSON. The parsed JSON has a flexible schema, all members are optional. The parsed `.content` JSON **should** be extended by NIPs. + +## Testing Criteria +The testing criteria to determine conditions defined in event's tags **may** be subjective and **may** vary between publishers. + +## Consumption +The data in `30303` **may** be erroneous, intentionally or otherwise. When accuracy is required, the data in `30303` events **should** be subscribed to by populating tthe `authors` filter array with the pubkeys of trusted **publishers** + +## Use Cases +- A lite social client identifies relays that were recently reported to be online without client-side tests +- A social client may find relays where a particular topic is popular. +- A social client may find relays based on their geographic proximity +- A status client shows relay statuses +- Identify macro-patterns amongst relays. +- Relays self-report statuses and/or metadata in `.content` signed by their NIP-11 `pubkey`. +- Could be used to store user checks for a relay to express personalized policies. For example, a user's pubkey was blacklisted on a relay, so they were unable to write: `..., tags: { [ ["d","wss://relay.damus.io"], ["o","true"], ["w","false"] ] }, ...`.