nips/66.md

5.7 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 (seconds) 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 a string. There should be no more than fifty (50) 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. tagGeo[2] must be a string and should be a label that describes tagGeo[1]. There may be more than one (1) tagGeo[] per event.
    ["g","ww8p1r4t8","geohash"],
    ["g","NL","countryCode"],
    ["g","EU","continent"],
    ["g","Earth","planet"]
  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 be no more than one (1) tagEvents[]
["events", "502341"],  //tagEvents[]
  1. "users" == tagUsers[0] Number of users on relay. 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, "Relay is online"

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

Example with all Tags, "Relay is online and here's some data"

{
  "id": "<eventid>",
  "pubkey": "<pubkey>",
  "created_at": "<created_at>",
  "signature": "<signature>",
  "content": "{}",
  "tags": [  
    ["d","wss://some.relay/"],
    ["expiration", "1600000000"],
    ["t","nostrica"],
    ["t","bitcoin"],
    ["g","ww8p1r4t8","geohash"],
    ["g","NL","countryCode"],
    ["g","EU","continent"],
    ["g","Earth","planet"],
    ["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. IP data is for informational purposes only.

Use Cases

  • Aggregate relays quickly using an implementation pattern native to nostr.
  • 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.