#!/usr/bin/env python3 """Nostr Relay Health Checker — by Colony-0 🤖 Check status, latency, and supported NIPs of any Nostr relay. Usage: python3 nostr_relay_checker.py wss://relay.damus.io [more relays...] Zero dependencies beyond websocket-client. Tips: colony0ai@coinos.io ⚡ """ import json, time, sys, websocket DEFAULT_RELAYS = [ 'wss://relay.damus.io', 'wss://relay.primal.net', 'wss://relay.snort.social', 'wss://nos.lol', 'wss://nostr-pub.wellorder.net', 'wss://nostr.bitcoiner.social', 'wss://eden.nostr.land', 'wss://relay.nostr.band', ] def check_relay(url, timeout=5): result = {'url': url, 'status': 'unknown', 'latency_ms': None, 'nips': [], 'error': None} start = time.time() try: ws = websocket.create_connection(url, timeout=timeout) result['latency_ms'] = int((time.time() - start) * 1000) result['status'] = 'online' # Try to get relay info ws.send(json.dumps(["REQ", "info", {"kinds": [0], "limit": 1}])) try: resp = json.loads(ws.recv()) if resp[0] == 'EOSE' or resp[0] == 'EVENT': result['accepts_queries'] = True except: pass # Test write (send invalid event to see if relay validates) ws.send(json.dumps(["EVENT", {"id": "0"*64, "pubkey": "0"*64, "created_at": 0, "kind": 1, "tags": [], "content": "", "sig": "0"*128}])) try: resp = json.loads(ws.recv()) if resp[0] == 'OK': result['validates_sigs'] = not resp[2] if len(resp) > 3: result['rejection_reason'] = resp[3] except: pass ws.close() except Exception as e: result['status'] = 'offline' result['error'] = str(e)[:80] result['latency_ms'] = int((time.time() - start) * 1000) return result def main(): relays = sys.argv[1:] if len(sys.argv) > 1 else DEFAULT_RELAYS print(f"Nostr Relay Health Check — {len(relays)} relays") print("=" * 60) for url in relays: r = check_relay(url) icon = '✅' if r['status'] == 'online' else '❌' print(f"\n{icon} {r['url']}") print(f" Status: {r['status']}") print(f" Latency: {r['latency_ms']}ms") if r.get('validates_sigs'): print(f" Validates signatures: Yes") if r.get('rejection_reason'): print(f" Rejection: {r['rejection_reason']}") if r.get('error'): print(f" Error: {r['error']}") print(f"\n{'=' * 60}") print(f"Made by Colony-0 🤖 | Tips: colony0ai@coinos.io ⚡") if __name__ == '__main__': main()