commit 34adc869cb6862267bc8e92032225c3ded2f3257
parent 9e025eabfce1c8547ed43943601406dc87381347
Author: triesap <tyson@radroots.org>
Date: Sun, 19 Jul 2026 20:21:46 +0000
nostr: publish service profiles through typed boundary
- build RHI service metadata as a sealed strict Profile event
- route Profile publication through the dedicated client method
- remove generic kind-0 construction from production and source guards
- refresh the standalone lockfile for the qualified codec feature graph
Diffstat:
5 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1609,6 +1609,7 @@ dependencies = [
"mediatype",
"serde",
"sha2",
+ "unicode-general-category",
"url",
]
@@ -1632,6 +1633,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
+ "unicode-general-category",
"url",
]
@@ -1640,6 +1642,7 @@ name = "radroots_event_codec"
version = "1.0.0-alpha.1"
dependencies = [
"nostr",
+ "radroots_blossom",
"radroots_core",
"radroots_event",
"serde",
@@ -2647,6 +2650,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
+name = "unicode-general-category"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f"
+
+[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/README b/README
@@ -3,6 +3,11 @@
This is the README for `rhi` which listens on Rad Roots networks and maintains
a stable activity record for parties buying and selling agricultural goods.
+RHI publishes its service kind-0 Profile only through the sealed
+`radroots_nostr` Profile builder after constructing the strict
+`RadrootsAuthoredProfile` replacement snapshot. It does not retain a generic
+kind-0 event-authoring path.
+
## Copyright
Except as otherwise noted, all files in the `rhi` distribution are
diff --git a/src/adapters/nostr/event.rs b/src/adapters/nostr/event.rs
@@ -83,7 +83,7 @@ mod tests {
use super::NostrEventAdapter;
use radroots_event_codec::job::traits::{JobEventBorrow, JobEventLike};
use radroots_nostr::prelude::{
- RadrootsNostrEvent, RadrootsNostrEventBuilder, RadrootsNostrKeys, RadrootsNostrKind,
+ RadrootsNostrEvent, RadrootsNostrGenericEventBuilder, RadrootsNostrKeys, RadrootsNostrKind,
RadrootsNostrTag, RadrootsNostrTagKind,
};
@@ -92,7 +92,7 @@ mod tests {
kind: RadrootsNostrKind,
tags: Vec<RadrootsNostrTag>,
) -> RadrootsNostrEvent {
- RadrootsNostrEventBuilder::new(kind, "content")
+ RadrootsNostrGenericEventBuilder::new(kind, "content")
.tags(tags)
.sign_with_keys(keys)
.expect("event must sign")
@@ -132,7 +132,7 @@ mod tests {
#[test]
fn adapter_maps_non_custom_kind_to_zero() {
let keys = RadrootsNostrKeys::generate();
- let event = build_event(&keys, RadrootsNostrKind::TextNote, Vec::new());
+ let event = build_event(&keys, RadrootsNostrKind::Repost, Vec::new());
let adapter = NostrEventAdapter::new(&event);
assert_eq!(JobEventBorrow::raw_kind(&adapter), 0);
diff --git a/src/lib.rs b/src/lib.rs
@@ -15,7 +15,6 @@ use radroots_event::{
kinds::TRADE_MUTATION_EVENT_KINDS,
profile::{RadrootsAuthoredProfile, RadrootsNip05Identifier},
};
-use radroots_event_codec::profile::authored::authored_profile_to_wire_parts;
use std::time::Duration;
use crate::features::trade_agreement_attestation::{
@@ -25,8 +24,8 @@ use crate::features::trade_agreement_attestation::{
use crate::identity_storage::load_service_identity;
use crate::rhi::{Rhi, start_subscriber_with_policy};
use radroots_nostr::prelude::{
- RadrootsNostrApplicationHandlerSpec, RadrootsNostrEventBuilder, RadrootsNostrMetadata,
- radroots_nostr_build_event, radroots_nostr_publish_application_handler,
+ RadrootsNostrApplicationHandlerSpec, RadrootsNostrMetadata, RadrootsNostrProfileEventBuilder,
+ radroots_nostr_build_profile_event, radroots_nostr_publish_application_handler,
};
use tracing::{info, warn};
@@ -88,7 +87,7 @@ async fn bootstrap_presence(
let builder = build_authored_service_profile_event(metadata)?;
client
- .send_event_builder(builder)
+ .send_profile_event_builder(builder)
.await
.context("publish strict RHI service Profile")?;
@@ -100,12 +99,9 @@ async fn bootstrap_presence(
fn build_authored_service_profile_event(
metadata: &RadrootsNostrMetadata,
-) -> Result<RadrootsNostrEventBuilder> {
+) -> Result<RadrootsNostrProfileEventBuilder> {
let profile = authored_service_profile(metadata)?;
- let wire =
- authored_profile_to_wire_parts(&profile).context("encode strict RHI service Profile")?;
- radroots_nostr_build_event(wire.kind, wire.content, wire.tags)
- .context("build strict RHI service Profile event")
+ radroots_nostr_build_profile_event(&profile).context("build strict RHI service Profile event")
}
fn authored_service_profile(metadata: &RadrootsNostrMetadata) -> Result<RadrootsAuthoredProfile> {
@@ -444,7 +440,8 @@ mod tests {
let keys = radroots_nostr::prelude::RadrootsNostrKeys::generate();
let event = build_authored_service_profile_event(&metadata)
.expect("strict Profile event")
- .build(keys.public_key());
+ .sign_with_keys(&keys)
+ .expect("sign strict Profile event");
assert_eq!(event.kind.as_u16(), 0);
assert!(event.tags.is_empty());
assert_eq!(
diff --git a/tests/source_guards.rs b/tests/source_guards.rs
@@ -120,7 +120,10 @@ fn rhi_agreement_attestation_is_release_product_optional_infrastructure() {
lib.contains("trade_mutation_subscription_kinds()")
&& lib.contains("&TRADE_MUTATION_EVENT_KINDS")
&& lib.contains("RadrootsAuthoredProfile")
- && lib.contains("authored_profile_to_wire_parts")
+ && lib.contains("RadrootsNostrProfileEventBuilder")
+ && lib.contains("radroots_nostr_build_profile_event")
+ && lib.contains("send_profile_event_builder")
+ && !lib.contains("radroots_nostr_build_event")
&& lib.contains("radroots_nostr_publish_application_handler")
&& !lib.contains("radroots_nostr_bootstrap_service_presence")
&& !lib.contains("RadrootsProfileType")