feat: propagate Tor address rotation to Nostr relays and federation peers

After rotation, spawns background task that publishes updated .onion to
Nostr relays and sends federation.peer-address-changed RPC to all peers
over Tor. Peers update their nodes.json with the new address.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-13 00:08:16 +00:00
parent f1ca60e732
commit e74bf9bcfd
4 changed files with 130 additions and 1 deletions

View File

@@ -323,4 +323,46 @@ impl RpcHandler {
info!(app = %app_id, peer = %peer_did, "Deployed app to federated peer");
Ok(result)
}
/// federation.peer-address-changed — A peer notifies us that their .onion changed.
pub(super) async fn handle_federation_peer_address_changed(
&self,
params: Option<serde_json::Value>,
) -> Result<serde_json::Value> {
let params = params.ok_or_else(|| anyhow::anyhow!("Missing params"))?;
let did = params
.get("did")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("Missing did"))?;
let new_onion = params
.get("new_onion")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("Missing new_onion"))?;
// Load existing nodes, find the peer by DID, update their onion
let mut nodes = federation::load_nodes(&self.config.data_dir).await?;
let found = nodes.iter_mut().find(|n| n.did == did);
match found {
Some(node) => {
let old = node.onion.clone();
node.onion = new_onion.to_string();
federation::save_nodes(&self.config.data_dir, &nodes).await?;
info!(did = %did, old_onion = %old, new_onion = %new_onion, "Updated federated peer address");
Ok(serde_json::json!({
"updated": true,
"did": did,
"old_onion": old,
"new_onion": new_onion,
}))
}
None => {
info!(did = %did, "Received address change from unknown peer — ignoring");
Ok(serde_json::json!({
"updated": false,
"reason": "Unknown peer DID",
}))
}
}
}
}