radrootsd

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

commit 0e2693cd8c633f84a1632eae1ef6afc42c5f85ec
parent e81bc7465fb46fe7fe2263c6da7ff4ca971e06f4
Author: triesap <triesap@radroots.dev>
Date:   Sat,  3 Jan 2026 17:48:08 +0000

jsonrpc: standardize nostr publish response

- Reuse shared PublishResponse serializer for publish endpoints
- Replace hardcoded kind IDs with KIND_LISTING and KIND_POST constants
- Remove ad-hoc serde_json construction in listing, post, and profile methods
- Rename post params struct to PublishPostParams for clarity

Diffstat:
Msrc/api/jsonrpc/methods/events/listing/publish.rs | 11++++-------
Msrc/api/jsonrpc/methods/events/post/publish.rs | 23++++++-----------------
Msrc/api/jsonrpc/methods/events/profile/publish.rs | 16++--------------
Msrc/api/jsonrpc/nostr.rs | 27++++++++++++++++++++++++++-
4 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/src/api/jsonrpc/methods/events/listing/publish.rs b/src/api/jsonrpc/methods/events/listing/publish.rs @@ -1,9 +1,10 @@ use anyhow::Result; use jsonrpsee::server::RpcModule; use serde::Deserialize; -use serde_json::{Value as JsonValue, json}; +use crate::api::jsonrpc::nostr::{publish_response, PublishResponse}; use crate::api::jsonrpc::{MethodRegistry, RpcContext, RpcError}; +use radroots_events::kinds::KIND_LISTING; use radroots_events::listing::RadrootsListing; use radroots_nostr::prelude::{radroots_nostr_build_event, radroots_nostr_send_event}; use radroots_trade::listing::codec::listing_tags_build; @@ -32,18 +33,14 @@ pub fn register(m: &mut RpcModule<RpcContext>, registry: &MethodRegistry) -> Res if let Some(extra_tags) = tags { tag_slices.extend(extra_tags); } - let builder = radroots_nostr_build_event(30402, content, tag_slices) + let builder = radroots_nostr_build_event(KIND_LISTING, content, tag_slices) .map_err(|e| RpcError::Other(format!("failed to build listing event: {e}")))?; let out = radroots_nostr_send_event(&ctx.state.client, builder) .await .map_err(|e| RpcError::Other(format!("failed to publish listing: {e}")))?; - Ok::<JsonValue, RpcError>(json!({ - "id": out.id().to_string(), - "sent": out.success.into_iter().map(|u| u.to_string()).collect::<Vec<_>>(), - "failed": out.failed.into_iter().map(|(u,e)| (u.to_string(), e.to_string())).collect::<Vec<_>>(), - })) + Ok::<PublishResponse, RpcError>(publish_response(out)) })?; Ok(()) } diff --git a/src/api/jsonrpc/methods/events/post/publish.rs b/src/api/jsonrpc/methods/events/post/publish.rs @@ -1,13 +1,14 @@ use anyhow::Result; use jsonrpsee::server::RpcModule; use serde::Deserialize; -use serde_json::{Value as JsonValue, json}; +use crate::api::jsonrpc::nostr::{publish_response, PublishResponse}; use crate::api::jsonrpc::{MethodRegistry, RpcContext, RpcError}; +use radroots_events::kinds::KIND_POST; use radroots_nostr::prelude::{radroots_nostr_build_event, radroots_nostr_send_event}; #[derive(Debug, Deserialize)] -struct PublishProfileParams { +struct PublishPostParams { content: String, #[serde(default)] tags: Option<Vec<Vec<String>>>, @@ -21,7 +22,7 @@ pub fn register(m: &mut RpcModule<RpcContext>, registry: &MethodRegistry) -> Res return Err(RpcError::NoRelays); } - let PublishProfileParams { content, tags } = params + let PublishPostParams { content, tags } = params .parse() .map_err(|e| RpcError::InvalidParams(e.to_string()))?; @@ -29,26 +30,14 @@ pub fn register(m: &mut RpcModule<RpcContext>, registry: &MethodRegistry) -> Res return Err(RpcError::InvalidParams("content must not be empty".into())); } - let builder = radroots_nostr_build_event(1, content, tags.unwrap_or_default()) + let builder = radroots_nostr_build_event(KIND_POST, content, tags.unwrap_or_default()) .map_err(|e| RpcError::Other(format!("failed to build note: {e}")))?; let output = radroots_nostr_send_event(&ctx.state.client, builder) .await .map_err(|e| RpcError::Other(format!("failed to publish note: {e}")))?; - let id_hex = output.id().to_string(); - let sent: Vec<String> = output.success.into_iter().map(|u| u.to_string()).collect(); - let failed: Vec<(String, String)> = output - .failed - .into_iter() - .map(|(u, e)| (u.to_string(), e.to_string())) - .collect(); - - Ok::<JsonValue, RpcError>(json!({ - "id": id_hex, - "sent": sent, - "failed": failed - })) + Ok::<PublishResponse, RpcError>(publish_response(output)) })?; Ok(()) diff --git a/src/api/jsonrpc/methods/events/profile/publish.rs b/src/api/jsonrpc/methods/events/profile/publish.rs @@ -1,8 +1,8 @@ use anyhow::Result; use jsonrpsee::server::RpcModule; use serde::Deserialize; -use serde_json::{Value as JsonValue, json}; +use crate::api::jsonrpc::nostr::{publish_response, PublishResponse}; use crate::api::jsonrpc::{MethodRegistry, RpcContext, RpcError}; use radroots_events::profile::RadrootsProfile; @@ -36,19 +36,7 @@ pub fn register(m: &mut RpcModule<RpcContext>, registry: &MethodRegistry) -> Res .await .map_err(|e| RpcError::Other(format!("failed to publish metadata: {e}")))?; - let id_hex = output.id().to_string(); - let sent: Vec<String> = output.success.into_iter().map(|u| u.to_string()).collect(); - let failed: Vec<(String, String)> = output - .failed - .into_iter() - .map(|(u, e)| (u.to_string(), e.to_string())) - .collect(); - - Ok::<JsonValue, RpcError>(json!({ - "id": id_hex, - "sent": sent, - "failed": failed - })) + Ok::<PublishResponse, RpcError>(publish_response(output)) })?; Ok(()) diff --git a/src/api/jsonrpc/nostr.rs b/src/api/jsonrpc/nostr.rs @@ -2,7 +2,11 @@ use serde::Serialize; -use radroots_nostr::prelude::RadrootsNostrEvent; +use radroots_nostr::prelude::{ + RadrootsNostrEvent, + RadrootsNostrEventId, + RadrootsNostrOutput, +}; #[derive(Clone, Debug, Serialize)] pub struct NostrEventView { @@ -15,6 +19,13 @@ pub struct NostrEventView { pub sig: String, } +#[derive(Clone, Debug, Serialize)] +pub struct PublishResponse { + pub id: String, + pub sent: Vec<String>, + pub failed: Vec<(String, String)>, +} + pub(crate) fn event_tags(event: &RadrootsNostrEvent) -> Vec<Vec<String>> { event.tags.iter().map(|t| t.as_slice().to_vec()).collect() } @@ -37,3 +48,17 @@ pub(crate) fn event_view_with_tags( sig: event.sig.to_string(), } } + +pub(crate) fn publish_response( + output: RadrootsNostrOutput<RadrootsNostrEventId>, +) -> PublishResponse { + PublishResponse { + id: output.id().to_string(), + sent: output.success.into_iter().map(|u| u.to_string()).collect(), + failed: output + .failed + .into_iter() + .map(|(u, e)| (u.to_string(), e.to_string())) + .collect(), + } +}