Relay Monitoring
Relay monitors are services that check relays and publish what they find (NIP-66). A monitor announces itself with a kind 10166 event, then publishes an addressable kind 30166 discovery event per relay, keyed by the relay URL, with its latency, supported NIPs, and requirements.
Finding monitors
Cast monitor announcements with RelayMonitor to read how often a monitor publishes and what it checks.
const monitors = use$(
() => store.timeline({ kinds: [RELAY_MONITOR_ANNOUNCEMENT_KIND] }).pipe(castTimelineStream(RelayMonitor, store)),
[],
);
monitor.frequency; // seconds between reports
monitor.checks; // ["open", "read", "write", ...]
monitor.timeouts; // [{ test?: "open", timeout: 5000 }]
monitor.geohash;Checking a relay
monitor.relayStatus(url) returns an observable of the monitor's report for one relay, requested from the monitor's outboxes. The URL must match the report's d tag exactly, so normalize it with normalizeURL() first.
const status = use$(() => monitor.relayStatus(normalizeURL(url)), [monitor, url]);Reading a report
The RelayDiscovery cast reads a kind 30166 report. Load every report from a monitor with a { kinds: [RELAY_DISCOVERY_KIND], authors: [pubkey] } filter.
report.url; // the relay from the "d" tag
report.rttOpen; // ms to connect; also rttRead and rttWrite
report.networkType; // "clearnet", "tor", "i2p", or "loki"
report.supportedNIPs; // ["1", "11", "42"]
report.requirements; // ["auth", "!payment"]
report.acceptedKinds; // ["1", "!4"]types, attributes, topics, geohash, and geohashes read the remaining tags. Values prefixed with ! mean the opposite, such as no payment required.
Helpers
isValidRelayMonitorAnnouncement(event)andisValidRelayDiscovery(event)validate the two kinds; a report needs adtaggetMonitorFrequency,getMonitorTimeouts,getMonitorChecks, andgetMonitorGeohashread announcementsgetRelayDiscoveryRTT(event, "open" | "read" | "write")and the othergetRelayDiscovery*helpers read reportsRELAY_MONITOR_ANNOUNCEMENT_KINDandRELAY_DISCOVERY_KINDare the kind numbers
Examples: Monitor feed · Relay directory
Best Practices
- Filter reports with
sincea few multiples ofmonitor.frequencyto skip relays the monitor stopped checking - Combine reports from several monitors before ranking relays, since each sees the network from one place
- Request reports from the monitor's outboxes, as
relayStatus()does