lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit b798d74b381ed24e9b54293280564748368daa0e
parent 8540e67c66559e6e94f22872bcd4a1de62cfdd38
Author: triesap <tyson@radroots.org>
Date:   Sat,  4 Oct 2025 00:13:10 +0100

net-core: add kind-0 profile retrieval support

Diffstat:
MCargo.lock | 1+
Mcrates/events/Cargo.toml | 2+-
Mcrates/net-core/Cargo.toml | 20++++++++++++--------
Mcrates/net-core/src/logging.rs | 2+-
Mcrates/net-core/src/nostr_client.rs | 40++++++++++++++++++++++++++++++++++++++++
5 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1702,6 +1702,7 @@ dependencies = [ "hex", "nostr", "nostr-sdk", + "radroots-events", "radroots-log", "secrecy", "serde", diff --git a/crates/events/Cargo.toml b/crates/events/Cargo.toml @@ -13,7 +13,7 @@ serde = ["dep:serde"] typeshare = ["dep:typeshare"] [dependencies] -radroots-core = { workspace = true, default-features = false, features = ["serde"] } +radroots-core = { workspace = true, default-features = false, features = ["std", "serde", "typeshare"] } serde = { workspace = true, default-features = false, features = ["alloc", "derive"], optional = true } typeshare = { workspace = true, optional = true } diff --git a/crates/net-core/Cargo.toml b/crates/net-core/Cargo.toml @@ -11,20 +11,23 @@ default = ["std"] std = [] rt = ["dep:tokio"] nostr-client = [ -"dep:nostr", -"dep:nostr-sdk", -"dep:secrecy", -"dep:hex", -"dep:tempfile", -"dep:serde_json" + "dep:radroots-events", + "radroots-events/serde", + "dep:nostr", + "dep:nostr-sdk", + "dep:secrecy", + "dep:hex", + "dep:tempfile", + "dep:serde_json" ] directories = ["dep:directories"] fs-persistence = [] [dependencies] +radroots-events = { workspace = true, optional = true, default-features = true, features = ["std", "serde", "typeshare"] } radroots-log = { workspace = true } directories = { workspace = true, optional = true } -hex = { workspace = true, optional = true } +hex = { workspace = true, optional = true } nostr = { workspace = true, optional = true } nostr-sdk = { workspace = true, optional = true } secrecy = { workspace = true, optional = true } @@ -35,4 +38,4 @@ thiserror = { workspace = true } tokio = { workspace = true, optional = true, features = ["rt-multi-thread"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["fmt", "env-filter"] } -tracing-appender = { workspace = true } +tracing-appender = { workspace = true } +\ No newline at end of file diff --git a/crates/net-core/src/logging.rs b/crates/net-core/src/logging.rs @@ -16,7 +16,7 @@ impl Default for LoggingOptions { fn default() -> Self { Self { dir: None, - file_name: "radroots.log".into(), + file_name: "radroots_net_core.log".into(), also_stdout: true, } } diff --git a/crates/net-core/src/nostr_client.rs b/crates/net-core/src/nostr_client.rs @@ -6,6 +6,8 @@ use std::sync::{Arc, Mutex}; #[cfg(feature = "nostr-client")] use nostr_sdk::prelude::*; #[cfg(feature = "nostr-client")] +use radroots_events::profile::models::RadrootsProfile; +#[cfg(feature = "nostr-client")] use tokio::runtime::Handle; #[cfg(feature = "nostr-client")] use tracing::{error, info}; @@ -135,6 +137,44 @@ impl NostrClientManager { } } + pub async fn fetch_profile_kind0( + &self, + author: nostr::PublicKey, + ) -> Result<Option<RadrootsProfile>, String> { + let filter = Filter::new() + .authors(vec![author]) + .kind(Kind::Metadata) + .limit(1); + let events = self + .inner + .client + .fetch_events(filter, std::time::Duration::from_secs(5)) + .await + .map_err(|e| e.to_string())?; + if let Some(ev) = events.into_iter().next() { + if let Ok(p) = serde_json::from_str::<RadrootsProfile>(&ev.content) { + return Ok(Some(p)); + } + if let Ok(md) = serde_json::from_str::<nostr::Metadata>(&ev.content) { + let p = RadrootsProfile { + name: md.name.unwrap_or_default(), + display_name: md.display_name, + nip05: md.nip05, + about: md.about, + website: md.website.map(|u| u.to_string()), + picture: md.picture.map(|u| u.to_string()), + banner: md.banner.map(|u| u.to_string()), + lud06: md.lud06, + lud16: md.lud16, + bot: None, + }; + return Ok(Some(p)); + } + return Err("failed to parse kind:0 metadata content".to_string()); + } + Ok(None) + } + fn spawn_status_watcher(&self) { let inner = self.inner.clone(); let rt = inner.rt.clone();