nips/66.md
2024-09-17 19:39:10 +02:00

9.8 KiB

NIP-66: Relay Discovery and Liveness Monitoring

draft optional

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.

In its purest form:

{
  "kind": 30166,
  "created_at": 1722173222,  
  "content": "{}",
  "tags": [
    [ "d", "wss://somerelay.abc/" ]
  ],
  "pubkey": "<pubkey>", 
  "sig": "<signature>",
  "id": "<eventid>"
}

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.

Kinds

NIP-66 defines two (2) event kinds, 30166 and 10166

kind name description
30166 Relay Discovery A PRE that is published by a monitor when a relay is online
10166 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

Ontology

  • Relay Operator: someone who operates a relay
  • Monitor: A pubkey that monitors relays and publishes 30166 events at the frequency specified in their 10166 event.
  • Ad-hoc Monitor: A pubkey that monitors relays and publishes 30166 events at an irregular frequency.
  • Monitor Service: A group or individual that monitors relays using one or more Monitors.
  • Check: a specific data point that is tested or aggregated by a monitor.

30166: "Relay Discovery"

Summary

30166 is a NIP-33 Parameterized-Replaceable Event [PRE], referred to as a "Relay Discovery" event. These events are optimized with a small footprint for protocol-level relay Discovery.

Purpose

Discovery of relays over nostr.

Schema

Content

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.

created_at

The created_at field in a NIP-66 event should reflect the time when the relay liveness (and potentially other data points) was checked.

tags

Meta Tags (unindexed)
  • rtt-open The relay's open round-trip time in milliseconds.
  • rtt-read The relay's read round-trip time in milliseconds.
  • rtt-write The relay's write round-trip time in milliseconds.

Other rtt values MAY be present. This NIP should be updated if there is value found in more rtt values.

Single Letter Tags (indexed)
  • 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. For relays not accessible via conventional means but rather by an npub/pubkey, an npub/pubkey MAY be used in place of a URL.

    [ "d", "wss://somerelay.abc/"]
    
  • n: Network

    [ "n", "clearnet" ]
    
  • T: Relay Type. Enumerated relay type formatted as PascalCase

    ["T", "PrivateInbox" ]
    
  • N: Supported Nips From NIP-11 "Informational Document" nip11.supported_nips[]

    [ "N", "42" ]
    
  • 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

    [ "R", "payment" ],
    [ "R", "auth" ],
    

    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

    [ "R", "!payment" ], //no payment required, is public
    [ "R", "!auth" ], //no authentication required
    
  • t: "Topics" From NIP-11 "Informational Document" nip11.tags[]

    [ "t", "nsfw" ]
    
  • k: Accepted/Blocked Kinds [NIP-22]

    [ "k", "0" ],
    [ "k", "3" ],
    [ "k", "10002" ]
    

    or for blocked kinds

    [ "k", "!0" ]
    [ "k", "!3" ],
    [ "k", "!10002" ]
    
  • g: NIP-52 g tags (geohash)

    [ "g", "9r1652whz" ]
    
  • 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.

Robust Example of a 30166 Event

Relay was online, and you can filter on a number of different tags

{
  "id": "<eventid>",
  "pubkey": "<monitor's pubkey>",
  "created_at": "<created_at  [some recent date ...]>",
  "signature": "<signature>",
  "content": "{}",
  "kind": 30166,
  "tags": [  
    ["d","wss://some.relay/"],
    ["n", "clearnet"],
    ["N", "40"],
    ["N", "33"],
    ["R", "!payment"],
    ["R", "auth"],
    ["g", "ww8p1r4t8"],
    ["p", "somehexkey..."],
    ["l", "en", "ISO-639-1"],
    ["t", "nsfw" ],
    ["rtt-open", 234 ]
  ]
} 

10166: "Relay Monitor Announcement" Events

Summary

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.

Purpose

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.

Schema

Standard Tags

  • 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.

    [ "frequency", "3600" ]
    
  • 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.

    [ "timeout", "2000", "open" ],
    [ "timeout", "2000", "read" ],
    [ "timeout", "3000", "write" ],
    [ "timeout", "2000", "nip11" ],
    [ "timeout", "4000", "ssl" ]
    

Indexed Tags

  • 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.

    [ "c", "ws" ],
    [ "c", "nip11" ],
    [ "c", "dns" ],
    [ "c", "geo" ],
    [ "c", "ssl" ],
    
  • g: NIP-52 g tags (geohash)

    [ "g", "9r1652whz" ]
    
  • Any other globally defined indexable tags MAY be included as found necessary.

Other Requirements

Monitors SHOULD have the following

  • A published 0 (NIP-1) event
  • A published 10002 (NIP-65) event that defines the relays the monitor publishes to.

Robust Example of a 10166 Event

{
  "id": "<eventid>",
  "pubkey": "<monitor's pubkey>",
  "created_at": "<created_at  [some recent date ...]>",
  "signature": "<signature>",
  "content": "",
  "tags": [  

    [ "timeout", "open", "5000"  ],
    [ "timeout", "read", "3000"  ],
    [ "timeout", "write", "3000" ],
    [ "timeout", "nip11", "3000" ],

    [ "frequency", "3600" ],

    [ "c", "ws" ],
    [ "c", "nip11" ],
    [ "c", "ssl" ],
    [ "c", "dns" ],
    [ "c", "geo" ]

    [ "g", "ww8p1r4t8" ]
  ]
} 

Methodology

Monitors

  1. A Relay Monitor checks the liveness and potentially other attributes of a relay.

  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.

Any pubkey that publishes 30166 events SHOULD at a minimum be checking that the relay is available by websocket and behaves like a relay

Clients

  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.

  2. Relay Liveness is subjectively determined by the client, starting with the frequency value of a monitor.

  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.

  4. The reliability and trustworthiness of a Relay Monitor could be established via web-of-trust, reviews or similar mechanisms.

Risk Mitigation

  • When a client implements NIP-66 events, the client should have a fallback if NIP-66 events cannot be located.

  • 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.