lib

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

commit 1125fa3c96bfe7163ffd29890fdf2a5bb01f5235
parent 2969de4edb2eb70fecd5288d048d2ffdaf2730ac
Author: triesap <tyson@radroots.org>
Date:   Sun,  4 Jan 2026 17:11:40 +0000

nostr: publish identity profile with optional type tag


- Add radrootsd profile type tag constant and enum variant
- Extend tag conversion helpers to map radrootsd type correctly
- Build metadata events with custom tags instead of post helper
- Add codec test covering radrootsd profile type decoding

Diffstat:
Mevents-codec/tests/profile.rs | 19+++++++++++++++++++
Mevents/src/profile.rs | 4++++
Mnostr/src/identity_profile.rs | 36++++++++++++++++++++++++++++++++----
Mnostr/src/lib.rs | 5++++-
4 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/events-codec/tests/profile.rs b/events-codec/tests/profile.rs @@ -7,6 +7,7 @@ use radroots_events::{ RADROOTS_PROFILE_TYPE_TAG_ANY, RADROOTS_PROFILE_TYPE_TAG_FARM, RADROOTS_PROFILE_TYPE_TAG_KEY, + RADROOTS_PROFILE_TYPE_TAG_RADROOTSD, }, }; use radroots_events_codec::error::EventParseError; @@ -99,3 +100,21 @@ fn profile_metadata_reads_profile_type_any_tag() { assert_eq!(metadata.profile_type, Some(RadrootsProfileType::Any)); } + +#[test] +fn profile_metadata_reads_profile_type_radrootsd_tag() { + let metadata = radroots_events_codec::profile::decode::metadata_from_event( + "id".to_string(), + "author".to_string(), + 1, + 0, + "{\"name\":\"alice\"}".to_string(), + vec![vec![ + RADROOTS_PROFILE_TYPE_TAG_KEY.to_string(), + RADROOTS_PROFILE_TYPE_TAG_RADROOTSD.to_string(), + ]], + ) + .expect("metadata"); + + assert_eq!(metadata.profile_type, Some(RadrootsProfileType::Radrootsd)); +} diff --git a/events/src/profile.rs b/events/src/profile.rs @@ -10,6 +10,7 @@ pub const RADROOTS_PROFILE_TYPE_TAG_INDIVIDUAL: &str = "radroots:type:individual pub const RADROOTS_PROFILE_TYPE_TAG_FARM: &str = "radroots:type:farm"; pub const RADROOTS_PROFILE_TYPE_TAG_COOP: &str = "radroots:type:coop"; pub const RADROOTS_PROFILE_TYPE_TAG_ANY: &str = "radroots:type:any"; +pub const RADROOTS_PROFILE_TYPE_TAG_RADROOTSD: &str = "radroots:type:radrootsd"; #[cfg_attr(feature = "ts-rs", derive(TS))] #[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] @@ -21,6 +22,7 @@ pub enum RadrootsProfileType { Farm, Coop, Any, + Radrootsd, } pub fn radroots_profile_type_tag_value(profile_type: RadrootsProfileType) -> &'static str { @@ -29,6 +31,7 @@ pub fn radroots_profile_type_tag_value(profile_type: RadrootsProfileType) -> &'s RadrootsProfileType::Farm => RADROOTS_PROFILE_TYPE_TAG_FARM, RadrootsProfileType::Coop => RADROOTS_PROFILE_TYPE_TAG_COOP, RadrootsProfileType::Any => RADROOTS_PROFILE_TYPE_TAG_ANY, + RadrootsProfileType::Radrootsd => RADROOTS_PROFILE_TYPE_TAG_RADROOTSD, } } @@ -38,6 +41,7 @@ pub fn radroots_profile_type_from_tag_value(value: &str) -> Option<RadrootsProfi RADROOTS_PROFILE_TYPE_TAG_FARM => Some(RadrootsProfileType::Farm), RADROOTS_PROFILE_TYPE_TAG_COOP => Some(RadrootsProfileType::Coop), RADROOTS_PROFILE_TYPE_TAG_ANY => Some(RadrootsProfileType::Any), + RADROOTS_PROFILE_TYPE_TAG_RADROOTSD => Some(RadrootsProfileType::Radrootsd), _ => None, } } diff --git a/nostr/src/identity_profile.rs b/nostr/src/identity_profile.rs @@ -1,17 +1,45 @@ -use crate::error::RadrootsNostrError; -use crate::events::metadata::radroots_nostr_post_metadata_event; -use crate::types::{RadrootsNostrEventId, RadrootsNostrOutput}; use crate::client::RadrootsNostrClient; +use crate::error::RadrootsNostrError; +use crate::events::metadata::radroots_nostr_build_metadata_event; +use crate::types::{ + RadrootsNostrEventId, + RadrootsNostrOutput, + RadrootsNostrTag, + RadrootsNostrTagKind, +}; +use radroots_events::profile::RadrootsProfileType; +use radroots_events_codec::profile::encode::profile_build_tags; use radroots_identity::RadrootsIdentity; pub async fn radroots_nostr_publish_identity_profile( client: &RadrootsNostrClient, identity: &RadrootsIdentity, ) -> Result<Option<RadrootsNostrOutput<RadrootsNostrEventId>>, RadrootsNostrError> { + radroots_nostr_publish_identity_profile_with_type(client, identity, None).await +} + +pub async fn radroots_nostr_publish_identity_profile_with_type( + client: &RadrootsNostrClient, + identity: &RadrootsIdentity, + profile_type: Option<RadrootsProfileType>, +) -> Result<Option<RadrootsNostrOutput<RadrootsNostrEventId>>, RadrootsNostrError> { let Some(profile) = identity.profile().and_then(|p| p.profile.as_ref()) else { return Ok(None); }; let metadata = radroots_events_codec::profile::encode::to_metadata(profile)?; - let out = radroots_nostr_post_metadata_event(client, &metadata).await?; + let tags = profile_build_tags(profile_type); + let mut tag_list: Vec<RadrootsNostrTag> = Vec::new(); + for mut tag in tags { + if tag.is_empty() { + continue; + } + let key = tag.remove(0); + tag_list.push(RadrootsNostrTag::custom( + RadrootsNostrTagKind::Custom(key.into()), + tag, + )); + } + let builder = radroots_nostr_build_metadata_event(&metadata).tags(tag_list); + let out = client.send_event_builder(builder).await?; Ok(Some(out)) } diff --git a/nostr/src/lib.rs b/nostr/src/lib.rs @@ -75,7 +75,10 @@ pub mod prelude { }; #[cfg(all(feature = "client", feature = "codec"))] - pub use crate::identity_profile::radroots_nostr_publish_identity_profile; + pub use crate::identity_profile::{ + radroots_nostr_publish_identity_profile, + radroots_nostr_publish_identity_profile_with_type, + }; #[cfg(all(feature = "client", feature = "events"))] pub use crate::events::post::radroots_nostr_fetch_post_events;