mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 07:21:32 +02:00
nip05: advertise only the relays the operator chose
relay_hints appended damus/nos.lol unconditionally, so every self-hosted instance published a NIP-05 document pointing its own users at third-party relays, and a correspondent would deliver there instead of to the operator's relay. An operator running a private deployment had no way to stop it. Now opt-in: NIP05_INTEROP_HINTS (default off) for the built-in interop pair, plus NIP05_EXTRA_RELAY_HINTS for the operator's own list.
This commit is contained in:
+24
-15
@@ -40,16 +40,16 @@ use crate::AppState;
|
|||||||
|
|
||||||
// ── constants ─────────────────────────────────────────────────────────────────
|
// ── constants ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// Default relay hints advertised in the well-known `relays` map.
|
/// Fallback interop relay hints, used ONLY when the operator has opted in via
|
||||||
|
/// `NIP05_EXTRA_RELAY_HINTS`.
|
||||||
///
|
///
|
||||||
/// Public relays shared with other wallets so cross-wallet delivery works before
|
/// These are third-party relays. Advertising them unconditionally made every
|
||||||
/// any per-user relay list is configured. NIP-05 lets a server advertise relay
|
/// self-hosted instance publish a document pointing its own users at
|
||||||
/// hints per pubkey in the `relays` object; we serve the same default set for
|
/// damus/nos.lol, so a correspondent would deliver there instead of to the
|
||||||
/// every resolved name.
|
/// operator's relay. An operator running a private or air-gapped deployment had
|
||||||
///
|
/// no way to stop their NIP-05 document recommending someone else's
|
||||||
/// TODO(phase-2): make configurable and serve per-user lists (NIP-65 kind 10002
|
/// infrastructure. Opt-in only.
|
||||||
/// / NIP-17 inbox relays) when private-message delivery lands.
|
const INTEROP_RELAY_HINTS: &[&str] = &["wss://relay.damus.io", "wss://nos.lol"];
|
||||||
const DEFAULT_RELAYS: &[&str] = &["wss://relay.damus.io", "wss://nos.lol"];
|
|
||||||
|
|
||||||
// ── DTOs ──────────────────────────────────────────────────────────────────────
|
// ── DTOs ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -118,18 +118,27 @@ pub async fn well_known_nostr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Relay hints advertised for a resolved pubkey: this instance's own relay (the
|
/// Relay hints advertised for a resolved pubkey: this instance's own relay (the
|
||||||
/// user's DM inbox) FIRST when enabled, then the public interop relays so
|
/// user's DM inbox) first, then any interop relays the OPERATOR opted into.
|
||||||
/// cross-wallet (e.g. Goblin) delivery still works before any per-user list.
|
///
|
||||||
/// Per-user lists (NIP-65 kind 10002 / NIP-17 inbox relays) remain future work.
|
/// An instance advertises only what its operator chose. Per-user lists (NIP-65
|
||||||
|
/// kind 10002 / NIP-17 inbox relays) remain future work.
|
||||||
fn relay_hints(config: &crate::config::Config) -> Vec<String> {
|
fn relay_hints(config: &crate::config::Config) -> Vec<String> {
|
||||||
let mut hints = Vec::new();
|
let mut hints = Vec::new();
|
||||||
let r = &config.messaging.relay;
|
let r = &config.messaging.relay;
|
||||||
if r.enabled && !r.advertised_url.trim().is_empty() {
|
if r.enabled && !r.advertised_url.trim().is_empty() {
|
||||||
hints.push(r.advertised_url.clone());
|
hints.push(r.advertised_url.clone());
|
||||||
}
|
}
|
||||||
for d in DEFAULT_RELAYS {
|
if config.messaging.nip05_interop_hints {
|
||||||
if !hints.iter().any(|h| h == d) {
|
for d in INTEROP_RELAY_HINTS {
|
||||||
hints.push((*d).to_string());
|
if !hints.iter().any(|h| h == d) {
|
||||||
|
hints.push((*d).to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for extra in &config.messaging.nip05_extra_relay_hints {
|
||||||
|
let extra = extra.trim();
|
||||||
|
if !extra.is_empty() && !hints.iter().any(|h| h == extra) {
|
||||||
|
hints.push(extra.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hints
|
hints
|
||||||
|
|||||||
@@ -655,6 +655,15 @@ fn parse_premium_plans(s: &str) -> Vec<PremiumPlan> {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MessagingConfig {
|
pub struct MessagingConfig {
|
||||||
pub relay: RelayConfig,
|
pub relay: RelayConfig,
|
||||||
|
/// Advertise the built-in third-party interop relays (damus, nos.lol) in the
|
||||||
|
/// NIP-05 document. OFF by default: an instance should recommend only what
|
||||||
|
/// its operator chose. Turn on for a public deployment that wants
|
||||||
|
/// cross-wallet delivery to work before correspondents publish their own
|
||||||
|
/// relay lists.
|
||||||
|
pub nip05_interop_hints: bool,
|
||||||
|
/// Additional relay URLs to advertise in the NIP-05 document, comma-separated
|
||||||
|
/// in `NIP05_EXTRA_RELAY_HINTS`. Appended after the instance's own relay.
|
||||||
|
pub nip05_extra_relay_hints: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Optional first-party Nostr relay. When `enabled`, the operator runs a relay
|
/// Optional first-party Nostr relay. When `enabled`, the operator runs a relay
|
||||||
@@ -927,6 +936,8 @@ impl Config {
|
|||||||
retention_days: env_parse("RELAY_RETENTION_DAYS", 30u32)?,
|
retention_days: env_parse("RELAY_RETENTION_DAYS", 30u32)?,
|
||||||
write_allowlist: env_list("RELAY_WRITE_ALLOWLIST_NPUBS"),
|
write_allowlist: env_list("RELAY_WRITE_ALLOWLIST_NPUBS"),
|
||||||
},
|
},
|
||||||
|
nip05_interop_hints: env_bool("NIP05_INTEROP_HINTS", false),
|
||||||
|
nip05_extra_relay_hints: env_list("NIP05_EXTRA_RELAY_HINTS"),
|
||||||
},
|
},
|
||||||
premium: PremiumConfig {
|
premium: PremiumConfig {
|
||||||
enabled: env_bool("PREMIUM_ENABLED", false),
|
enabled: env_bool("PREMIUM_ENABLED", false),
|
||||||
@@ -1527,6 +1538,8 @@ mod tests {
|
|||||||
retention_days: 30,
|
retention_days: 30,
|
||||||
write_allowlist: Vec::new(),
|
write_allowlist: Vec::new(),
|
||||||
},
|
},
|
||||||
|
nip05_interop_hints: false,
|
||||||
|
nip05_extra_relay_hints: Vec::new(),
|
||||||
},
|
},
|
||||||
premium: PremiumConfig {
|
premium: PremiumConfig {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user