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:
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;