rhi

Coordinated trade for connected markets
git clone https://radroots.dev/git/rhi.git
Log | Files | Refs | README | LICENSE

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:
MCargo.lock | 9+++++++++
MREADME | 5+++++
Msrc/adapters/nostr/event.rs | 6+++---
Msrc/lib.rs | 17+++++++----------
Mtests/source_guards.rs | 5++++-
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")