commit c639934736779f309f1f18bc4ac63705ed5e545e
parent 937182ebfecfec3db08587e877d7e54477bad23d
Author: triesap <tyson@radroots.org>
Date: Sun, 15 Feb 2026 18:16:14 +0000
app: use shared runtime config and nostr presence primitives
- replace local cli flag definitions with shared runtime service cli args
- flatten shared nostr service config into rhi configuration
- switch startup presence publishing to shared nostr bootstrap helper
- route nip89 identifier and extra tags through shared service config fields
Diffstat:
4 files changed, 29 insertions(+), 83 deletions(-)
diff --git a/src/cli.rs b/src/cli.rs
@@ -1,6 +1,5 @@
-use std::path::PathBuf;
-
-use clap::{Parser, ValueHint, command};
+use clap::Parser;
+use radroots_runtime::RadrootsServiceCliArgs;
#[derive(Parser, Debug, Clone)]
#[command(
@@ -9,27 +8,6 @@ use clap::{Parser, ValueHint, command};
version = env!("CARGO_PKG_VERSION")
)]
pub struct Args {
- #[arg(
- long,
- value_name = "PATH",
- value_hint = ValueHint::FilePath,
- default_value = "config.toml",
- help = "Path to the daemon configuration file (defaults to config.toml)"
- )]
- pub config: PathBuf,
-
- #[arg(
- long,
- value_name = "PATH",
- value_hint = ValueHint::FilePath,
- help = "Path to the daemon identity file (json, txt, or raw 32-byte key; defaults to identity.json)",
- )]
- pub identity: Option<PathBuf>,
-
- #[arg(
- long,
- action = clap::ArgAction::SetTrue,
- help = "Allow generating a new identity file if missing; if not set and identity file is absent, the daemon will fail"
- )]
- pub allow_generate_identity: bool,
+ #[command(flatten)]
+ pub service: RadrootsServiceCliArgs,
}
diff --git a/src/config.rs b/src/config.rs
@@ -1,15 +1,11 @@
use radroots_nostr::prelude::RadrootsNostrMetadata;
-use radroots_runtime::BackoffConfig;
+use radroots_runtime::{BackoffConfig, RadrootsNostrServiceConfig};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Configuration {
- pub logs_dir: String,
- pub relays: Vec<String>,
- #[serde(default)]
- pub nip89_identifier: Option<String>,
- #[serde(default)]
- pub nip89_extra_tags: Vec<Vec<String>>,
+ #[serde(flatten)]
+ pub service: RadrootsNostrServiceConfig,
#[serde(default)]
pub subscriber: SubscriberConfig,
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -13,86 +13,58 @@ pub use cli::Args as cli_args;
use anyhow::Result;
use std::time::Duration;
-use crate::{
- rhi::{Rhi, start_subscriber},
-};
+use crate::rhi::{Rhi, start_subscriber};
use radroots_identity::RadrootsIdentity;
use radroots_nostr::prelude::{
- radroots_nostr_publish_application_handler,
- radroots_nostr_publish_identity_profile,
- RadrootsNostrApplicationHandlerSpec,
- RadrootsNostrMetadata,
+ RadrootsNostrApplicationHandlerSpec, radroots_nostr_bootstrap_service_presence,
};
use radroots_trade::listing::dvm_kinds::TRADE_LISTING_DVM_KINDS;
use tracing::{info, warn};
-fn metadata_has_fields(md: &RadrootsNostrMetadata) -> bool {
- md.name.is_some()
- || md.display_name.is_some()
- || md.about.is_some()
- || md.website.is_some()
- || md.picture.is_some()
- || md.banner.is_some()
- || md.nip05.is_some()
- || md.lud06.is_some()
- || md.lud16.is_some()
- || !md.custom.is_empty()
-}
-
pub async fn run_rhi(settings: &config::Settings, args: &cli_args) -> Result<()> {
let identity = RadrootsIdentity::load_or_generate(
- args.identity.as_ref(),
- args.allow_generate_identity,
+ args.service.identity.as_ref(),
+ args.service.allow_generate_identity,
)?;
let keys = identity.keys().clone();
let rhi = Rhi::new(keys.clone());
let client = rhi.client.clone();
- let relays = settings.config.relays.clone();
+ let service_cfg = settings.config.service.clone();
+ let relays = service_cfg.relays.clone();
for relay in &relays {
client.add_relay(relay).await?;
}
let md = settings.metadata.clone();
- let has_metadata = metadata_has_fields(&md);
if !relays.is_empty() {
- client.connect().await;
- client.wait_for_connection(Duration::from_secs(5)).await;
- let profile_published = match radroots_nostr_publish_identity_profile(&client, &identity).await
- {
- Ok(Some(_)) => true,
- Ok(None) => false,
- Err(e) => {
- warn!("Failed to publish identity profile: {e}");
- false
- }
- };
- if has_metadata && !profile_published {
- if let Err(e) = client.set_metadata(&md).await {
- warn!("Failed to publish metadata on startup: {e}");
- } else {
- info!("Published metadata on startup");
- }
- }
-
let handler_kinds = TRADE_LISTING_DVM_KINDS
.iter()
.map(|kind| *kind as u32)
.collect();
let handler_spec = RadrootsNostrApplicationHandlerSpec {
kinds: handler_kinds,
- identifier: settings.config.nip89_identifier.clone(),
+ identifier: service_cfg.nip89_identifier.clone(),
metadata: Some(md.clone()),
- extra_tags: settings.config.nip89_extra_tags.clone(),
+ extra_tags: service_cfg.nip89_extra_tags.clone(),
relays: relays.clone(),
nostrconnect_url: None,
};
- if let Err(e) = radroots_nostr_publish_application_handler(&client, &handler_spec).await {
- warn!("Failed to publish NIP-89 announcement: {e}");
+ if let Err(e) = radroots_nostr_bootstrap_service_presence(
+ &client,
+ &identity,
+ None,
+ &md,
+ &handler_spec,
+ Duration::from_secs(5),
+ )
+ .await
+ {
+ warn!("Failed to publish service presence on startup: {e}");
} else {
- info!("Published NIP-89 announcement");
+ info!("Published service presence on startup");
}
}
diff --git a/src/main.rs b/src/main.rs
@@ -18,8 +18,8 @@ async fn main() -> ExitCode {
async fn run() -> Result<()> {
let (args, settings): (cli_args, config::Settings) =
radroots_runtime::parse_and_load_path_with_init(
- |a: &cli_args| Some(a.config.as_path()),
- |cfg: &config::Settings| cfg.config.logs_dir.as_str(),
+ |a: &cli_args| Some(a.service.config.as_path()),
+ |cfg: &config::Settings| cfg.config.service.logs_dir.as_str(),
None,
)
.context("load configuration")?;