identity_profile.rs (3430B)
1 use crate::client::RadrootsNostrClient; 2 use crate::error::RadrootsNostrError; 3 #[cfg(feature = "events")] 4 use crate::events::application_handler::{ 5 RadrootsNostrApplicationHandlerSpec, radroots_nostr_metadata_has_fields, 6 radroots_nostr_publish_application_handler, 7 }; 8 use crate::events::metadata::radroots_nostr_build_metadata_event; 9 #[cfg(feature = "events")] 10 use crate::types::RadrootsNostrMetadata; 11 use crate::types::{ 12 RadrootsNostrEventId, RadrootsNostrOutput, RadrootsNostrTag, RadrootsNostrTagKind, 13 }; 14 #[cfg(feature = "events")] 15 use core::time::Duration; 16 use radroots_events::profile::RadrootsProfileType; 17 use radroots_events_codec::profile::encode::profile_build_tags; 18 use radroots_identity::RadrootsIdentity; 19 20 pub async fn radroots_nostr_publish_identity_profile( 21 client: &RadrootsNostrClient, 22 identity: &RadrootsIdentity, 23 ) -> Result<Option<RadrootsNostrOutput<RadrootsNostrEventId>>, RadrootsNostrError> { 24 radroots_nostr_publish_identity_profile_with_type(client, identity, None).await 25 } 26 27 pub async fn radroots_nostr_publish_identity_profile_with_type( 28 client: &RadrootsNostrClient, 29 identity: &RadrootsIdentity, 30 profile_type: Option<RadrootsProfileType>, 31 ) -> Result<Option<RadrootsNostrOutput<RadrootsNostrEventId>>, RadrootsNostrError> { 32 let Some(profile) = identity.profile().and_then(|p| p.profile.as_ref()) else { 33 return Ok(None); 34 }; 35 let metadata = radroots_events_codec::profile::encode::to_metadata(profile)?; 36 let tags = profile_build_tags(profile_type); 37 let mut tag_list: Vec<RadrootsNostrTag> = Vec::new(); 38 for mut tag in tags { 39 if tag.is_empty() { 40 continue; 41 } 42 let key = tag.remove(0); 43 tag_list.push(RadrootsNostrTag::custom( 44 RadrootsNostrTagKind::Custom(key.into()), 45 tag, 46 )); 47 } 48 let builder = radroots_nostr_build_metadata_event(&metadata).tags(tag_list); 49 let out = client.send_event_builder(builder).await?; 50 Ok(Some(out)) 51 } 52 53 #[cfg(feature = "events")] 54 pub async fn radroots_nostr_bootstrap_service_presence( 55 client: &RadrootsNostrClient, 56 identity: &RadrootsIdentity, 57 profile_type: Option<RadrootsProfileType>, 58 metadata: &RadrootsNostrMetadata, 59 handler_spec: &RadrootsNostrApplicationHandlerSpec, 60 connect_timeout: Duration, 61 ) -> Result<(), RadrootsNostrError> { 62 client.connect().await; 63 client.wait_for_connection(connect_timeout).await; 64 65 let profile_published = 66 radroots_nostr_publish_identity_profile_with_type(client, identity, profile_type) 67 .await? 68 .is_some(); 69 70 if radroots_nostr_metadata_has_fields(metadata) && !profile_published { 71 let builder = 72 radroots_nostr_build_metadata_event(metadata).tags(profile_type_tags(profile_type)); 73 client.send_event_builder(builder).await?; 74 } 75 76 radroots_nostr_publish_application_handler(client, handler_spec).await?; 77 Ok(()) 78 } 79 80 #[cfg(feature = "events")] 81 fn profile_type_tags(profile_type: Option<RadrootsProfileType>) -> Vec<RadrootsNostrTag> { 82 let mut tag_list: Vec<RadrootsNostrTag> = Vec::new(); 83 for mut tag in profile_build_tags(profile_type) { 84 if tag.is_empty() { 85 continue; 86 } 87 let key = tag.remove(0); 88 tag_list.push(RadrootsNostrTag::custom( 89 RadrootsNostrTagKind::Custom(key.into()), 90 tag, 91 )); 92 } 93 tag_list 94 }