metadata.rs (2262B)
1 //! Sealed authoring for validated NIP-01 profile metadata events. 2 3 #[cfg(feature = "events")] 4 use crate::error::Error; 5 #[cfg(feature = "events")] 6 use crate::events::sealed::SealedBuilderCore; 7 #[cfg(feature = "events")] 8 use crate::types::{ 9 ExternalSigningRequest, RadrootsNostrEvent, RadrootsNostrKeys, RadrootsNostrPublicKey, 10 RadrootsNostrTimestamp, 11 }; 12 #[cfg(feature = "events")] 13 use radroots_event::profile::AuthoredProfile; 14 #[cfg(feature = "events")] 15 use radroots_event_codec::authoring::{AuthoredEventBody, AuthoredPlanError}; 16 17 /// A sealed builder for a validated kind-0 Profile replacement snapshot. 18 /// 19 /// The wrapper exposes no raw builder conversion or tag/content mutation. 20 /// Media-bearing profiles still require the owning runtime to prove successful 21 /// BUD-02 upload completion before signing or publication. 22 #[cfg(feature = "events")] 23 #[must_use = "Profile event builders must be signed or published"] 24 pub struct ProfileBuilder { 25 inner: SealedBuilderCore, 26 } 27 28 #[cfg(feature = "events")] 29 impl ProfileBuilder { 30 /// Sets the event timestamp without changing the validated Profile shape. 31 pub fn custom_created_at(mut self, created_at: RadrootsNostrTimestamp) -> Self { 32 self.inner = self.inner.custom_created_at(created_at); 33 self 34 } 35 36 /// Signs the validated Profile directly with local keys. 37 pub fn sign_with_keys(self, keys: &RadrootsNostrKeys) -> Result<RadrootsNostrEvent, Error> { 38 self.inner.sign_with_keys(keys) 39 } 40 41 /// Finalizes the exact authored plan for an external signer. 42 pub fn into_external_signing_request( 43 self, 44 public_key: RadrootsNostrPublicKey, 45 ) -> Result<ExternalSigningRequest, Error> { 46 self.inner.into_external_signing_request(public_key) 47 } 48 } 49 50 /// Builds a sealed kind-0 event from the strict authored Profile contract. 51 #[cfg(feature = "events")] 52 pub fn build_profile_event(profile: &AuthoredProfile) -> Result<ProfileBuilder, Error> { 53 let body = AuthoredEventBody::from_profile(profile).map_err(|error| match error { 54 AuthoredPlanError::Profile(error) => Error::ProfileEncode(error), 55 error => Error::AuthoredPlan(error), 56 })?; 57 let inner = SealedBuilderCore::new(body); 58 Ok(ProfileBuilder { inner }) 59 }