radrootsd

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

commit b705a954a0b6e1dde8cf54f5864cdbaaeeacdc1e
parent 498a71bf0a9f699929efa8436ce5ae0762ae73a2
Author: triesap <triesap@radroots.dev>
Date:   Tue,  6 Jan 2026 14:27:18 +0000

nip46: add ping rpc

- add nip46.ping jsonrpc method with session lookup
- send NIP-46 ping request and parse pong response
- return pong result on success
- register ping in nip46 module

Diffstat:
Msrc/api/jsonrpc/methods/nip46/mod.rs | 2++
Asrc/api/jsonrpc/methods/nip46/ping.rs | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/radrootsd.rs | 3++-
3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/src/api/jsonrpc/methods/nip46/mod.rs b/src/api/jsonrpc/methods/nip46/mod.rs @@ -7,6 +7,7 @@ use crate::api::jsonrpc::{MethodRegistry, RpcContext}; pub mod status; pub mod connect; +pub mod ping; pub mod get_public_key; pub mod sign_event; pub mod session_status; @@ -16,6 +17,7 @@ pub fn module(ctx: RpcContext, registry: MethodRegistry) -> Result<RpcModule<Rpc let mut m = RpcModule::new(ctx); status::register(&mut m, &registry)?; connect::register(&mut m, &registry)?; + ping::register(&mut m, &registry)?; get_public_key::register(&mut m, &registry)?; sign_event::register(&mut m, &registry)?; session_status::register(&mut m, &registry)?; diff --git a/src/api/jsonrpc/methods/nip46/ping.rs b/src/api/jsonrpc/methods/nip46/ping.rs @@ -0,0 +1,58 @@ +use anyhow::Result; +use jsonrpsee::server::RpcModule; +use serde::{Deserialize, Serialize}; + +use crate::api::jsonrpc::{MethodRegistry, RpcContext, RpcError}; +use crate::nip46::client; +use crate::nip46::session::Nip46Session; +use nostr::nips::nip46::{NostrConnectMethod, NostrConnectRequest, ResponseResult}; + +#[derive(Debug, Deserialize)] +struct Nip46PingParams { + session_id: String, +} + +#[derive(Clone, Debug, Serialize)] +struct Nip46PingResponse { + result: String, +} + +pub fn register(m: &mut RpcModule<RpcContext>, registry: &MethodRegistry) -> Result<()> { + registry.track("nip46.ping"); + m.register_async_method("nip46.ping", |params, ctx, _| async move { + let Nip46PingParams { session_id } = params + .parse() + .map_err(|e| RpcError::InvalidParams(e.to_string()))?; + let session = ctx + .state + .nip46_sessions + .get(&session_id) + .await + .ok_or_else(|| RpcError::InvalidParams("unknown session".to_string()))?; + let response = request_ping(&session).await?; + Ok::<Nip46PingResponse, RpcError>(Nip46PingResponse { + result: response, + }) + })?; + Ok(()) +} + +async fn request_ping(session: &Nip46Session) -> Result<String, RpcError> { + let request = NostrConnectRequest::Ping; + let response = client::request(session, request, "ping").await?; + let response = response + .to_response(NostrConnectMethod::Ping) + .map_err(|e| RpcError::Other(format!("nip46 ping failed: {e}")))?; + + if let Some(error) = response.error { + return Err(RpcError::Other(format!("nip46 ping error: {error}"))); + } + + match response.result { + Some(ResponseResult::Pong) => Ok("pong".to_string()), + Some(_) => Err(RpcError::Other( + "nip46 ping unexpected response".to_string(), + )), + None => Err(RpcError::Other("nip46 ping missing response".to_string())), + } +} diff --git a/src/radrootsd.rs b/src/radrootsd.rs @@ -38,4 +38,4 @@ impl Radrootsd { nip46_sessions, } } -} +} +\ No newline at end of file