diff --git a/src/relays.rs b/src/relays.rs index 3a6ecfb..1ed4dde 100644 --- a/src/relays.rs +++ b/src/relays.rs @@ -20,12 +20,22 @@ pub fn default_relays() -> Vec { /// reliability for ephemeral kind-24133 traffic; listening on a few extra /// well-known relays costs nothing and makes pairing robust whichever one /// the signer happens to choose. +/// +/// This set was curated with a live write+readback canary (Sep 22, 2026): +/// - wss://purplepag.es REJECTS kind 24133 ("blocked: kind 24133 is not +/// allowed") — a signer that picks it reports "connected" while its +/// connect event is thrown away, so it must never be in the pairing URI. +/// - wss://relay.nostr.band currently hangs the WebSocket handshake; it is +/// also pay-to-read. Dropped from the pairing set. +/// - wss://nos.lol and wss://relay.snort.social accept ephemeral 24133 and +/// serve it live (snort does not persist ephemeral kinds, which is fine — +/// pairing only needs the live push). pub fn pairing_relays() -> Vec { vec![ "wss://relay.damus.io".to_string(), "wss://relay.primal.net".to_string(), - "wss://purplepag.es".to_string(), - "wss://relay.nostr.band".to_string(), + "wss://nos.lol".to_string(), + "wss://relay.snort.social".to_string(), ] } @@ -195,6 +205,25 @@ mod tests { assert!(relays.iter().all(|r| r.enabled)); } + #[test] + fn pairing_relays_exclude_24133_blockers() { + // purplepag.es returns "blocked: kind 24133 is not allowed" and + // relay.nostr.band hangs the handshake (canary, Sep 22 2026). A + // signer that picks a blocking relay says "connected" while its + // connect event is discarded, so neither may appear in the URI. + let relays = pairing_relays(); + assert!(!relays.iter().any(|r| r.contains("purplepag"))); + assert!(!relays.iter().any(|r| r.contains("nostr.band"))); + // Every entry is a well-formed wss URL and the set is deduped. + for url in &relays { + validate_url(url).expect("pairing relay must be a valid wss URL"); + } + let mut sorted = relays.clone(); + sorted.sort(); + sorted.dedup(); + assert_eq!(sorted.len(), relays.len()); + } + #[test] fn validate_url_accepts_wss_and_ws() { assert!(validate_url("wss://relay.example.com").is_ok());