nips/59.md
2023-03-01 17:51:26 +01:00

5.5 KiB

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 computationally expensive relay meta-data from active relays as events on nostr.

Personas

  • Publishers generate and push 30303 events. Events should be published at a regular interval. Events must implement NIP-40.
  • Consumers aggregate 30303 for insight on relays. Some example consumers are a social client or relay status client.

schema

event.tags

Relay status events have two (2) required tags and eight (8) optional tags. Relay status events introduce one (1) new indexable tag (NIP-12)

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. The #d tag must be included in the event.tags[] array. tagId[1] must be the relay websocket URL. The URL should be normalized.
["d", "wss://history.nostr.watch/"] //tagId[]
  1. "expiration" == tagExpiration[0] [NIP-40]. The tagExpiration[] tag must be included in the event.tags[] array. tagExpiration[1] should be set to a future timestamp that correlates with the publisher's intended update frequency.
["expiration", "1600000000"] //tagExpiration[]
  1. "t" == tagTopic[0] Topics relevant to the relay. tagTopic[] may be included in the event.tags[] array. tagTopic[1] should be string. There should be no more than twenty (20) tagTopic[] arrays.
["t", "bitcoin"]  //tagTopic[]
  1. "g" == tagGeo[0] Relay Geo Data. tagGeo[] may be included in the event.tags[] array. tagGeo[1] must be string and should be a geohash. There may be strings defined in the key range 2+ (tagGeo[2...]) and they must be strings if set. tagGeo[] items should be descending by precision. There should be no more than one (1) tagGeo[] per event.
["g", "ww8p1r4t8", "Amsterdam", "NL", "EU", "Earth", "Sol", "Milky Way"] //tagGeo[]
  1. "read" == tagRead[0] Was able to read from the relay. tagRead[] may be included in the event.tags[] array. tagRead[1] must be type string as exactly true or false
["read", "true"]     //tagRead[]
  1. "write" == tagWrite[0] Was able to write to the relay. tagWrite[] may be included in the event.tags[] array. tagWrite[1] must be type string as exactly true or false
["write", "false"]    //tagWrite[]
  1. "ssl" == tagSsl[0] Is the relay's SSL valid. tagSsl[] may be included in the event.tags[] array. tagSsl[1] must be type string as exactly true or false
["ssl", "true"]     //tagSsl[]
  1. "ip" == tagIp[0] Relay IP. tagIp[] may be included in the event.tags[] array. tagIp[1] must be string. There may be more than one (1) tagIp[]
["ip", "1.1.1.1"],  //tagIp[]
["ip", "2001:db8:3333:4444:5555:6666:7777:8888"] //tagIp[]
  1. "events" == tagEvents[0] Number of events on relay. tagEvents[] may be included in the event.tags[] array. tagEvents[1] must be string. There should only be one (1) tagEvents[]
["events", "502341"],  //tagEvents[]
  1. "users" == tagUsers[0] Relay IP. tagUsers[] may be included in the event.tags[] array. tagUsers[1] must be string. There should be no more than one (1) tagUsers[]
["users","37482"] //tagUsers[]

Example with Minimum Requirements:

{
  "id": "<eventid>",
  "pubkey": "<pubkey>",
  "created_at": "<created_at>",
  "signature": "<signature>",
  "content": "",
  "tags": [  
    ["d","wss://relay.snort.social/"],
    ["expiration", "1600000000"]
  ]
}

Example with all Tags:

{
  "id": "<eventid>",
  "pubkey": "<pubkey>",
  "created_at": "<created_at>",
  "signature": "<signature>",
  "content": "{}",
  "tags": [  
    ["d","wss://some.relay/"],
    ["expiration", "1600000000"],
    ["t","nostrica"],
    ["t","bitcoin"],
    ["g","ww8p1r4t8","Amsterdam","NL","EU","Earth"],
    ["ip","1.1.1.1"],
    ["ip","2001:db8:3333:4444:5555:6666:7777:8888"],
    ["read","true"],
    ["write","false"],
    ["ssl","true"],
    ["events", "502341"],
    ["users","37482"]
  ]
}

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. Where accuracy is required, the data in 30303 events should be subscribed to by populating the authors filter array with the pubkeys of trusted publishers

Use Cases

  • Aggregate relays quickly.
  • 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
  • Relays self-report statuses and/or metadata in .content signed by their NIP-11 pubkey.