radrootsd

JSON-RPC bridge for Radroots event publishing
git clone https://radroots.dev/git/radrootsd.git
Log | Files | Refs | README | LICENSE

commit d67dffa14a6ffdc6367d9b2eca0b26c474de35f4
parent ef63e2dfca1e5f1f48ccd0b6889f93b4281d0901
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Fri, 22 Aug 2025 14:28:01 -0700

Add nostr relays rpc events module.

Diffstat:
Mcrates/radrootsd/src/rpc/error.rs | 6++++++
Mcrates/radrootsd/src/rpc/mod.rs | 2++
Acrates/radrootsd/src/rpc/relays.rs | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/crates/radrootsd/src/rpc/error.rs b/crates/radrootsd/src/rpc/error.rs @@ -3,6 +3,12 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum RpcError { + #[error("failed to add relay {0}: {1}")] + AddRelay(String, String), + #[error("no relays configured; call relays.add first")] + NoRelays, + #[error("invalid params: {0}")] + InvalidParams(String), #[error("{0}")] Other(String), } diff --git a/crates/radrootsd/src/rpc/mod.rs b/crates/radrootsd/src/rpc/mod.rs @@ -6,6 +6,7 @@ use jsonrpsee::server::{RpcModule, Server, ServerHandle}; use crate::radrootsd::Radrootsd; mod error; +mod relays; mod system; pub use error::RpcError; @@ -15,6 +16,7 @@ pub async fn start_rpc(radrootsd: Radrootsd, addr: SocketAddr) -> Result<ServerH let mut root = RpcModule::new(radrootsd.clone()); root.merge(system::module(radrootsd.clone())?)?; + root.merge(relays::module(radrootsd.clone())?)?; let handle = server.start(root); Ok(handle) diff --git a/crates/radrootsd/src/rpc/relays.rs b/crates/radrootsd/src/rpc/relays.rs @@ -0,0 +1,52 @@ +use anyhow::Result; +use jsonrpsee::RpcModule; +use serde::Deserialize; +// note: bring JsonValue into scope to turbofish Ok later +use serde_json::{Value as JsonValue, json}; + +use crate::radrootsd::Radrootsd; +use crate::rpc::RpcError; + +#[derive(Debug, Deserialize)] +struct AddParams { + url: String, +} + +pub fn module(radrootsd: Radrootsd) -> Result<RpcModule<Radrootsd>> { + let mut m = RpcModule::new(radrootsd); + + // relays.add + m.register_async_method("relays.add", |params, ctx, _| async move { + let AddParams { url } = params + .parse() + .map_err(|e| RpcError::InvalidParams(e.to_string()))?; + ctx.client + .add_relay(&url) + .await + .map_err(|e| RpcError::AddRelay(url.clone(), e.to_string()))?; + + Ok::<JsonValue, RpcError>(json!({ "added": url })) + })?; + + // relays.list + m.register_async_method("relays.list", |_p, ctx, _| async move { + let relays = ctx.client.relays().await; + Ok::<JsonValue, RpcError>(json!( + relays.keys().map(|u| u.to_string()).collect::<Vec<_>>() + )) + })?; + + // relays.connect + m.register_async_method("relays.connect", |_p, ctx, _| async move { + let relays = ctx.client.relays().await; + if relays.is_empty() { + return Err(RpcError::NoRelays); + } + let client = ctx.client.clone(); + tokio::spawn(async move { client.connect().await }); + + Ok::<JsonValue, RpcError>(json!({ "connecting": relays.len() })) + })?; + + Ok(m) +}