From 948fe972eb2bddf187b79f2673a091b6331cfd90 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 1 Apr 2025 14:31:34 +0100 Subject: chore: bump rust-nostr v0.37 ~> v0.40 and fix all of the breaking changes --- src/lib/client.rs | 223 +++++++++++++++++++++++++--------------- src/lib/git/mod.rs | 2 +- src/lib/git/nostr_url.rs | 150 +++++++++++++++------------ src/lib/git_events.rs | 42 +++++--- src/lib/login/existing.rs | 2 +- src/lib/login/fresh.rs | 2 +- src/lib/login/key_encryption.rs | 2 +- src/lib/login/mod.rs | 4 +- src/lib/repo_ref.rs | 103 +++++++++++-------- 9 files changed, 313 insertions(+), 217 deletions(-) (limited to 'src/lib') diff --git a/src/lib/client.rs b/src/lib/client.rs index 59ec583..142df64 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs @@ -29,9 +29,14 @@ use futures::{ use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle}; #[cfg(test)] use mockall::*; -use nostr::{Event, nips::nip01::Coordinate, signer::SignerBackend}; -use nostr_database::NostrEventsDatabase; +use nostr::{ + Event, + nips::{nip01::Coordinate, nip19::Nip19Coordinate}, + signer::SignerBackend, +}; +use nostr_database::{NostrEventsDatabase, SaveEventStatus}; use nostr_lmdb::NostrLMDB; +use nostr_relay_pool::relay::ReqExitPolicy; use nostr_sdk::{ EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, SingleLetterTag, Timestamp, prelude::RelayLimits, @@ -89,7 +94,7 @@ pub trait Connect { async fn fetch_all<'a>( &self, git_repo_path: Option<&'a Path>, - repo_coordinates: Option<&'a Coordinate>, + repo_coordinates: Option<&'a Nip19Coordinate>, user_profiles: &HashSet, ) -> Result<(Vec>, MultiProgress)>; async fn fetch_all_from_relay<'a>( @@ -182,8 +187,8 @@ impl Connect for Client { if !relay.is_connected() { #[allow(clippy::large_futures)] - relay - .connect(Some(std::time::Duration::from_secs(CONNECTION_TIMEOUT))) + let _ = relay + .try_connect(std::time::Duration::from_secs(CONNECTION_TIMEOUT)) .await; } @@ -194,7 +199,7 @@ impl Connect for Client { } async fn disconnect(&self) -> Result<()> { - self.client.disconnect().await?; + self.client.disconnect().await; Ok(()) } @@ -223,11 +228,7 @@ impl Connect for Client { self.client.add_relay(url).await?; #[allow(clippy::large_futures)] self.client.connect_relay(url).await?; - self.client - .relay(url) - .await? - .send_event(event.clone()) - .await?; + self.client.relay(url).await?.send_event(&event).await?; if let Some(git_repo_path) = git_repo_path { save_event_in_local_cache(git_repo_path, &event).await?; } @@ -329,7 +330,7 @@ impl Connect for Client { async fn fetch_all<'a>( &self, git_repo_path: Option<&'a Path>, - trusted_maintainer_coordinate: Option<&'a Coordinate>, + trusted_maintainer_coordinate: Option<&'a Nip19Coordinate>, user_profiles: &HashSet, ) -> Result<(Vec>, MultiProgress)> { let fallback_relays = &self @@ -504,7 +505,7 @@ impl Connect for Client { request: FetchRequest, pb: &Option, ) -> Result { - let mut fresh_coordinates: HashSet = HashSet::new(); + let mut fresh_coordinates: HashSet = HashSet::new(); for (c, _) in request.repo_coordinates_without_relays.clone() { fresh_coordinates.insert(c); } @@ -617,8 +618,8 @@ async fn get_events_of( if !relay.is_connected() { #[allow(clippy::large_futures)] - relay - .connect(Some(std::time::Duration::from_secs(CONNECTION_TIMEOUT))) + let _ = relay + .try_connect(std::time::Duration::from_secs(CONNECTION_TIMEOUT)) .await; } @@ -627,16 +628,27 @@ async fn get_events_of( } else if let Some(pb) = pb { pb.set_prefix(format!("connected {}", relay.url())); } - let events = relay - .fetch_events( - filters, - // 20 is nostr_sdk default - std::time::Duration::from_secs(GET_EVENTS_TIMEOUT), - nostr_sdk::FilterOptions::ExitOnEOSE, - ) - .await? - .to_vec(); - Ok(events) + + let events_res = join_all(filters.into_iter().map(|filter| async { + relay + .fetch_events( + filter, + // 20 is nostr_sdk default + std::time::Duration::from_secs(GET_EVENTS_TIMEOUT), + ReqExitPolicy::ExitOnEOSE, + ) + .await + })) + .await; + + // no Event is being mutated, just new items added to the set + #[allow(clippy::mutable_key_type)] + let mut events: HashSet = HashSet::new(); + + for res in events_res { + events.extend(res?); + } + Ok(events.into_iter().collect()) } #[derive(Default)] @@ -770,50 +782,81 @@ pub async fn get_events_from_local_cache( git_repo_path: &Path, filters: Vec, ) -> Result> { - Ok(get_local_cache_database(git_repo_path) - .await? - .query(filters.clone()) - .await - .context( - "failed to execute query on opened git repo nostr cache database .git/nostr-cache.lmdb", - )? - .to_vec()) + let db = get_local_cache_database(git_repo_path).await?; + + let query_results = join_all(filters.into_iter().map(|filter| async { + db.query(filter) + .await + .context("failed to execute query on opened ngit nostr cache database") + })) + .await; + + // no Event is being mutated, just new items added to the set + #[allow(clippy::mutable_key_type)] + let mut events: HashSet = HashSet::new(); + + for result in query_results { + events.extend(result?); + } + + Ok(events.into_iter().collect()) } pub async fn get_event_from_global_cache( git_repo_path: Option<&Path>, filters: Vec, ) -> Result> { - Ok(get_global_cache_database(git_repo_path) - .await? - .query(filters.clone()) - .await - .context("failed to execute query on opened ngit nostr cache database")? - .to_vec()) + let db = get_global_cache_database(git_repo_path).await?; + + let query_results = join_all(filters.into_iter().map(|filter| async { + db.query(filter) + .await + .context("failed to execute query on opened ngit nostr cache database") + })) + .await; + + // no Event is being mutated, just new items added to the set + #[allow(clippy::mutable_key_type)] + let mut events: HashSet = HashSet::new(); + + for result in query_results { + events.extend(result?); + } + + Ok(events.into_iter().collect()) } pub async fn save_event_in_local_cache(git_repo_path: &Path, event: &nostr::Event) -> Result { - get_local_cache_database(git_repo_path) + match get_local_cache_database(git_repo_path) .await? .save_event(event) .await - .context("failed to save event in local cache") + .context("failed to save event in local cache")? + { + SaveEventStatus::Success => Ok(true), + _ => Ok(false), + } } pub async fn save_event_in_global_cache( git_repo_path: Option<&Path>, event: &nostr::Event, ) -> Result { - get_global_cache_database(git_repo_path) + match get_global_cache_database(git_repo_path) .await? .save_event(event) .await .context("failed to save event in local cache") + { + Ok(SaveEventStatus::Success) => Ok(true), + Ok(_) => Ok(false), + Err(e) => Err(e).context("failed to save event in local cache"), + } } pub async fn get_repo_ref_from_cache( git_repo_path: Option<&Path>, - repo_coordinate: &Coordinate, + repo_coordinate: &Nip19Coordinate, ) -> Result { let mut maintainers = HashSet::new(); let mut new_coordinate: bool; @@ -824,10 +867,12 @@ pub async fn get_repo_ref_from_cache( new_coordinate = false; let repo_events_filter = get_filter_repo_events(&HashSet::from_iter(maintainers.iter().map(|m| { - Coordinate { - kind: Kind::GitRepoAnnouncement, - public_key: *m, - identifier: repo_coordinate.identifier.to_string(), + Nip19Coordinate { + coordinate: Coordinate { + kind: Kind::GitRepoAnnouncement, + public_key: *m, + identifier: repo_coordinate.identifier.to_string(), + }, relays: vec![], } }))); @@ -859,19 +904,21 @@ pub async fn get_repo_ref_from_cache( let repo_ref = RepoRef::try_from(( repo_events .first() - .context("no repo announcement event found at specified coordinates. if you are the repository maintainer consider running `ngit init` to create one")? + .context("no repo announcement event found at specified Nip19Coordinates. if you are the repository maintainer consider running `ngit init` to create one")? .clone(), Some(repo_coordinate.public_key), ))?; - let mut events: HashMap = HashMap::new(); + let mut events: HashMap = HashMap::new(); for m in &maintainers { if let Some(e) = repo_events.iter().find(|e| e.pubkey.eq(m)) { events.insert( - Coordinate { - kind: e.kind, - identifier: e.tags.identifier().unwrap().to_string(), - public_key: e.pubkey, + Nip19Coordinate { + coordinate: Coordinate { + kind: e.kind, + identifier: e.tags.identifier().unwrap().to_string(), + public_key: e.pubkey, + }, relays: vec![], }, e.clone(), @@ -912,7 +959,7 @@ pub async fn get_state_from_cache( #[allow(clippy::too_many_lines)] async fn create_relays_request( git_repo_path: Option<&Path>, - trusted_maintainer_coordinate: Option<&Coordinate>, + trusted_maintainer_coordinate: Option<&Nip19Coordinate>, user_profiles: &HashSet, fallback_relays: HashSet, ) -> Result { @@ -929,9 +976,9 @@ async fn create_relays_request( }; let repo_coordinates = { - // add coordinates of users listed in maintainers to explicitly specified - // coodinates - let mut set: HashSet = HashSet::new(); + // add Nip19Coordinates of users listed in maintainers to explicitly + // specified coodinates + let mut set: HashSet = HashSet::new(); if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate { set.insert(trusted_maintainer_coordinate.clone()); } @@ -951,10 +998,12 @@ async fn create_relays_request( let repo_coordinates_without_relays = { let mut set = HashSet::new(); for c in &repo_coordinates { - set.insert(Coordinate { - kind: c.kind, - identifier: c.identifier.clone(), - public_key: c.public_key, + set.insert(Nip19Coordinate { + coordinate: Coordinate { + kind: c.kind, + identifier: c.identifier.clone(), + public_key: c.public_key, + }, relays: vec![], }); } @@ -976,11 +1025,11 @@ async fn create_relays_request( for event in &get_events_from_local_cache(git_repo_path, vec![ nostr::Filter::default() .kinds(vec![Kind::GitPatch]) - .custom_tag( + .custom_tags( SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), repo_coordinates_without_relays .iter() - .map(std::string::ToString::to_string) + .map(|c| c.coordinate.to_string()) .collect::>(), ), ]) @@ -1153,7 +1202,7 @@ async fn process_fetched_events( events: Vec, request: &FetchRequest, git_repo_path: Option<&Path>, - fresh_coordinates: &mut HashSet, + fresh_coordinates: &mut HashSet, fresh_proposal_roots: &mut HashSet, fresh_profiles: &mut HashSet, report: &mut FetchReport, @@ -1188,10 +1237,12 @@ async fn process_fetched_events( }); if update_to_existing { report.updated_repo_announcements.push(( - Coordinate { - kind: event.kind, - public_key: event.pubkey, - identifier: event.tags.identifier().unwrap().to_owned(), + Nip19Coordinate { + coordinate: Coordinate { + kind: event.kind, + public_key: event.pubkey, + identifier: event.tags.identifier().unwrap().to_owned(), + }, relays: vec![], }, event.created_at, @@ -1204,14 +1255,16 @@ async fn process_fetched_events( .repo_coordinates_without_relays // prexisting maintainers .iter() .map(|(c, _)| c.clone()) - .collect::>() + .collect::>() .union(&report.repo_coordinates_without_relays) // already added maintainers .any(|c| c.identifier.eq(&repo_ref.identifier) && m.eq(&c.public_key)) { - let c = Coordinate { - kind: event.kind, - public_key: *m, - identifier: repo_ref.identifier.clone(), + let c = Nip19Coordinate { + coordinate: Coordinate { + kind: event.kind, + public_key: *m, + identifier: repo_ref.identifier.clone(), + }, relays: vec![], }; fresh_coordinates.insert(c.clone()); @@ -1343,7 +1396,7 @@ pub fn consolidate_fetch_reports(reports: Vec>) -> FetchRepo report } pub fn get_fetch_filters( - repo_coordinates: &HashSet, + repo_coordinates: &HashSet, proposal_ids: &HashSet, required_profiles: &HashSet, ) -> Vec { @@ -1356,11 +1409,11 @@ pub fn get_fetch_filters( get_filter_repo_events(repo_coordinates), nostr::Filter::default() .kinds(vec![Kind::GitPatch, Kind::EventDeletion]) - .custom_tag( + .custom_tags( SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), repo_coordinates .iter() - .map(std::string::ToString::to_string) + .map(|c| c.coordinate.to_string()) .collect::>(), ), ] @@ -1383,7 +1436,7 @@ pub fn get_fetch_filters( .concat() } -pub fn get_filter_repo_events(repo_coordinates: &HashSet) -> nostr::Filter { +pub fn get_filter_repo_events(repo_coordinates: &HashSet) -> nostr::Filter { nostr::Filter::default() .kind(Kind::GitRepoAnnouncement) .identifiers( @@ -1401,7 +1454,7 @@ pub fn get_filter_repo_events(repo_coordinates: &HashSet) -> nostr:: } pub static STATE_KIND: nostr::Kind = Kind::Custom(30618); -pub fn get_filter_state_events(repo_coordinates: &HashSet) -> nostr::Filter { +pub fn get_filter_state_events(repo_coordinates: &HashSet) -> nostr::Filter { nostr::Filter::default() .kind(STATE_KIND) .identifiers( @@ -1426,8 +1479,8 @@ pub fn get_filter_contributor_profiles(contributors: HashSet) -> nost #[derive(Default)] pub struct FetchReport { - repo_coordinates_without_relays: HashSet, - updated_repo_announcements: Vec<(Coordinate, Timestamp)>, + repo_coordinates_without_relays: HashSet, + updated_repo_announcements: Vec<(Nip19Coordinate, Timestamp)>, updated_state: Option<(Timestamp, EventId)>, proposals: HashSet, /// commits against existing propoals @@ -1518,7 +1571,7 @@ pub struct FetchRequest { repo_relays: HashSet, selected_relay: Option, relay_column_width: usize, - repo_coordinates_without_relays: Vec<(Coordinate, Option)>, + repo_coordinates_without_relays: Vec<(Nip19Coordinate, Option)>, state: Option<(Timestamp, EventId)>, proposals: HashSet, contributors: HashSet, @@ -1532,7 +1585,7 @@ pub async fn fetching_with_report( git_repo_path: &Path, #[cfg(test)] client: &crate::client::MockConnect, #[cfg(not(test))] client: &Client, - trusted_maintainer_coordinate: &Coordinate, + trusted_maintainer_coordinate: &Nip19Coordinate, ) -> Result { let term = console::Term::stderr(); term.write_line("fetching updates...")?; @@ -1557,16 +1610,16 @@ pub async fn fetching_with_report( pub async fn get_proposals_and_revisions_from_cache( git_repo_path: &Path, - repo_coordinates: HashSet, + repo_coordinates: HashSet, ) -> Result> { let mut proposals = get_events_from_local_cache(git_repo_path, vec![ nostr::Filter::default() .kind(nostr::Kind::GitPatch) - .custom_tag( + .custom_tags( nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), repo_coordinates .iter() - .map(std::string::ToString::to_string) + .map(|c| c.coordinate.to_string()) .collect::>(), ), ]) diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs index 2b78f38..1329820 100644 --- a/src/lib/git/mod.rs +++ b/src/lib/git/mod.rs @@ -1141,7 +1141,7 @@ mod tests { fn test(time: git2::Time) -> Result<()> { assert_eq!( extract_sig_from_patch_tags( - &Tags::new(vec![nostr::Tag::custom( + &Tags::from_list(vec![nostr::Tag::custom( nostr::TagKind::Custom("author".to_string().into()), prep(&time)?, )]), diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index ae0ac5f..54be292 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -2,8 +2,8 @@ use core::fmt; use std::{collections::HashMap, str::FromStr}; use anyhow::{Context, Error, Result, anyhow, bail}; -use nostr::nips::{nip01::Coordinate, nip05}; -use nostr_sdk::{PublicKey, RelayUrl, ToBech32, Url}; +use nostr::nips::{nip01::Coordinate, nip05, nip19::Nip19Coordinate}; +use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; use super::{Repo, get_git_config_item, save_git_config_item}; @@ -58,7 +58,7 @@ impl FromStr for ServerProtocol { #[derive(Debug, PartialEq, Clone)] pub struct NostrUrlDecoded { pub original_string: String, - pub coordinate: Coordinate, + pub coordinate: Nip19Coordinate, pub protocol: Option, pub user: Option, pub nip05: Option, @@ -166,7 +166,7 @@ impl NostrUrlDecoded { // extract naddr npub//identifer let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; // naddr used - let coordinate = if let Ok(coordinate) = Coordinate::parse(part) { + let coordinate = if let Ok(coordinate) = Nip19Coordinate::from_bech32(part) { if coordinate.kind.eq(&nostr_sdk::Kind::GitRepoAnnouncement) { coordinate } else { @@ -225,10 +225,12 @@ impl NostrUrlDecoded { } } }; - Coordinate { - identifier, - public_key, - kind: nostr_sdk::Kind::GitRepoAnnouncement, + Nip19Coordinate { + coordinate: Coordinate { + identifier, + public_key, + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays, } }; @@ -959,7 +961,7 @@ mod tests { } } mod nostr_git_url_format { - use nostr::nips::nip01::Coordinate; + use nostr::nips::nip19::Nip19Coordinate; use nostr_sdk::PublicKey; use super::*; @@ -970,13 +972,15 @@ mod tests { assert_eq!( format!("{}", NostrUrlDecoded { original_string: String::new(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], }, protocol: None, @@ -993,13 +997,15 @@ mod tests { assert_eq!( format!("{}", NostrUrlDecoded { original_string: String::new(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![], }, protocol: None, @@ -1016,13 +1022,15 @@ mod tests { assert_eq!( format!("{}", NostrUrlDecoded { original_string: String::new(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], }, protocol: Some(ServerProtocol::Ssh), @@ -1039,13 +1047,15 @@ mod tests { assert_eq!( format!("{}", NostrUrlDecoded { original_string: String::new(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], }, protocol: Some(ServerProtocol::Ssh), @@ -1061,14 +1071,16 @@ mod tests { mod nostr_url_decoded_paramemters_from_str { use super::*; - fn get_model_coordinate(relays: bool) -> Coordinate { - Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + fn get_model_coordinate(relays: bool) -> Nip19Coordinate { + Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: if relays { vec![RelayUrl::parse("wss://nos.lol").unwrap()] } else { @@ -1084,13 +1096,15 @@ mod tests { NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], /* wont add the * slash */ }, @@ -1172,13 +1186,15 @@ mod tests { NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![ RelayUrl::parse("wss://nos.lol/").unwrap(), RelayUrl::parse("wss://relay.damus.io/").unwrap(), @@ -1274,13 +1290,15 @@ mod tests { NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), - coordinate: Coordinate { - identifier: "ngit".to_string(), - public_key: PublicKey::parse( - "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", - ) - .unwrap(), - kind: nostr_sdk::Kind::GitRepoAnnouncement, + coordinate: Nip19Coordinate { + coordinate: Coordinate { + identifier: "ngit".to_string(), + public_key: PublicKey::parse( + "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", + ) + .unwrap(), + kind: nostr_sdk::Kind::GitRepoAnnouncement, + }, relays: vec![ RelayUrl::parse("wss://nos.lol/").unwrap(), RelayUrl::parse("wss://relay.damus.io/").unwrap(), diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs index 559155a..2b3df42 100644 --- a/src/lib/git_events.rs +++ b/src/lib/git_events.rs @@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc}; use anyhow::{Context, Result, bail}; use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; use nostr_sdk::{ - Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, RelayUrl, Tag, TagKind, + Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, Tag, TagKind, TagStandard, hashes::sha1::Hash as Sha1Hash, }; @@ -115,11 +115,14 @@ pub async fn generate_patch_event( .maintainers .iter() .map(|m| { - Tag::coordinate(Coordinate { - kind: nostr::Kind::GitRepoAnnouncement, - public_key: *m, - identifier: repo_ref.identifier.to_string(), - relays: repo_ref.relays.clone(), + Tag::from_standardized(TagStandard::Coordinate { + coordinate: Coordinate { + kind: nostr::Kind::GitRepoAnnouncement, + public_key: *m, + identifier: repo_ref.identifier.to_string(), + }, + relay_url: repo_ref.relays.first().cloned(), + uppercase: false, }) }) .collect::>(), @@ -257,12 +260,12 @@ pub fn event_tag_from_nip19_or_hex( PromptInputParms::default().with_prompt(format!("{reference_name} reference")), )?; } - if let Ok(nip19) = Nip19::from_bech32(bech32.clone()) { + if let Ok(nip19) = Nip19::from_bech32(&bech32) { match nip19 { Nip19::Event(n) => { break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { event_id: n.event_id, - relay_url: n.relays.first().and_then(|url| RelayUrl::parse(url).ok()), + relay_url: n.relays.first().cloned(), marker: Some(marker), public_key: None, uppercase: false, @@ -278,7 +281,11 @@ pub fn event_tag_from_nip19_or_hex( })); } Nip19::Coordinate(coordinate) => { - break Ok(Tag::coordinate(coordinate)); + break Ok(Tag::from_standardized(TagStandard::Coordinate { + coordinate: coordinate.coordinate, + relay_url: coordinate.relays.first().cloned(), + uppercase: false, + })); } Nip19::Profile(profile) => { if allow_npub_reference { @@ -338,12 +345,17 @@ pub async fn generate_cover_letter_and_patch_events( )) .tags( [ - repo_ref.maintainers.iter().map(|m| Tag::coordinate(Coordinate { - kind: nostr::Kind::GitRepoAnnouncement, - public_key: *m, - identifier: repo_ref.identifier.to_string(), - relays: repo_ref.relays.clone(), - })).collect::>(), + repo_ref.maintainers.iter().map(|m| + Tag::from_standardized(TagStandard::Coordinate { + coordinate: Coordinate { + kind: nostr::Kind::GitRepoAnnouncement, + public_key: *m, + identifier: repo_ref.identifier.to_string(), + }, + relay_url: repo_ref.relays.first().cloned(), + uppercase: false, + }) + ).collect::>(), vec![ Tag::from_standardized(TagStandard::Reference(format!("{root_commit}"))), Tag::hashtag("cover-letter"), diff --git a/src/lib/login/existing.rs b/src/lib/login/existing.rs index efe187e..e60621d 100644 --- a/src/lib/login/existing.rs +++ b/src/lib/login/existing.rs @@ -208,7 +208,7 @@ async fn get_signer( Duration::from_secs(10 * 60), None, )?; - if let Some(public_key) = npub.clone().and_then(|npub| PublicKey::parse(npub).ok()) { + if let Some(public_key) = npub.clone().and_then(|npub| PublicKey::parse(&npub).ok()) { s.non_secure_set_user_public_key(public_key)?; let signer: Arc = Arc::new(s); Ok((signer, public_key)) diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index 635c0b3..76998ff 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs @@ -372,7 +372,7 @@ pub fn generate_nostr_connect_app( client .get_fallback_signer_relays() .iter() - .flat_map(RelayUrl::parse) + .flat_map(|s| RelayUrl::parse(s)) .collect::>() } else { vec![] diff --git a/src/lib/login/key_encryption.rs b/src/lib/login/key_encryption.rs index efb38d1..d57b3b5 100644 --- a/src/lib/login/key_encryption.rs +++ b/src/lib/login/key_encryption.rs @@ -7,7 +7,7 @@ pub fn decrypt_key(encrypted_key: &str, password: &str) -> Result { if encrypted_key.log_n() > 14 { println!("this may take a few seconds..."); } - Ok(nostr::Keys::new(encrypted_key.to_secret_key(password)?)) + Ok(nostr::Keys::new(encrypted_key.decrypt(password)?)) } #[cfg(test)] diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs index a1c45d5..c37375f 100644 --- a/src/lib/login/mod.rs +++ b/src/lib/login/mod.rs @@ -93,7 +93,7 @@ pub async fn get_likely_logged_in_user(git_repo_path: &Path) -> Result Result Result> { Ok( if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { - if let Ok(public_key) = PublicKey::parse(npub) { + if let Ok(public_key) = PublicKey::parse(&npub) { Some(public_key) } else { None diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index 38f6774..b21a911 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs @@ -8,7 +8,10 @@ use std::{ use anyhow::{Context, Result, bail}; use console::Style; -use nostr::{FromBech32, PublicKey, Tag, TagStandard, ToBech32, nips::nip01::Coordinate}; +use nostr::{ + FromBech32, PublicKey, Tag, TagStandard, ToBech32, + nips::{nip01::Coordinate, nip19::Nip19Coordinate}, +}; use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; use serde::{Deserialize, Serialize}; @@ -37,7 +40,7 @@ pub struct RepoRef { pub relays: Vec, pub maintainers: Vec, pub trusted_maintainer: PublicKey, - pub events: HashMap, + pub events: HashMap, pub nostr_git_url: Option, } @@ -119,10 +122,12 @@ impl TryFrom<(nostr::Event, Option)> for RepoRef { } r.events = HashMap::new(); r.events.insert( - Coordinate { - kind: event.kind, - identifier: event.tags.identifier().unwrap().to_string(), - public_key: event.pubkey, + Nip19Coordinate { + coordinate: Coordinate { + kind: event.kind, + identifier: event.tags.identifier().unwrap().to_string(), + public_key: event.pubkey, + }, relays: vec![], }, event, @@ -195,20 +200,24 @@ impl RepoRef { .context("failed to create repository reference event") } /// coordinates without relay hints - pub fn coordinates(&self) -> HashSet { + pub fn coordinates(&self) -> HashSet { let mut res = HashSet::new(); - res.insert(Coordinate { - kind: Kind::GitRepoAnnouncement, - public_key: self.trusted_maintainer, - identifier: self.identifier.clone(), + res.insert(Nip19Coordinate { + coordinate: Coordinate { + kind: Kind::GitRepoAnnouncement, + public_key: self.trusted_maintainer, + identifier: self.identifier.clone(), + }, relays: vec![], }); for m in &self.maintainers { - res.insert(Coordinate { - kind: Kind::GitRepoAnnouncement, - public_key: *m, - identifier: self.identifier.clone(), + res.insert(Nip19Coordinate { + coordinate: Coordinate { + kind: Kind::GitRepoAnnouncement, + public_key: *m, + identifier: self.identifier.clone(), + }, relays: vec![], }); } @@ -216,11 +225,13 @@ impl RepoRef { } /// coordinates without relay hints - pub fn coordinate_with_hint(&self) -> Coordinate { - Coordinate { - kind: Kind::GitRepoAnnouncement, - public_key: self.trusted_maintainer, - identifier: self.identifier.clone(), + pub fn coordinate_with_hint(&self) -> Nip19Coordinate { + Nip19Coordinate { + coordinate: Coordinate { + kind: Kind::GitRepoAnnouncement, + public_key: self.trusted_maintainer, + identifier: self.identifier.clone(), + }, relays: if let Some(relay) = self.relays.first() { vec![relay.clone()] } else { @@ -230,11 +241,11 @@ impl RepoRef { } /// coordinates without relay hints - pub fn coordinates_with_timestamps(&self) -> Vec<(Coordinate, Option)> { + pub fn coordinates_with_timestamps(&self) -> Vec<(Nip19Coordinate, Option)> { self.coordinates() .iter() .map(|c| (c.clone(), self.events.get(c).map(|e| e.created_at))) - .collect::)>>() + .collect::)>>() } pub fn set_nostr_git_url(&mut self, nostr_git_url: NostrUrlDecoded) { @@ -264,7 +275,7 @@ pub async fn get_repo_coordinates_when_remote_unknown( git_repo: &Repo, #[cfg(test)] client: &crate::client::MockConnect, #[cfg(not(test))] client: &Client, -) -> Result { +) -> Result { if let Ok(c) = try_and_get_repo_coordinates_when_remote_unknown(git_repo).await { Ok(c) } else { @@ -274,7 +285,7 @@ pub async fn get_repo_coordinates_when_remote_unknown( pub async fn try_and_get_repo_coordinates_when_remote_unknown( git_repo: &Repo, -) -> Result { +) -> Result { let remote_coordinates = get_repo_coordinates_from_nostr_remotes(git_repo).await?; if remote_coordinates.is_empty() { if let Ok(c) = get_repo_coordinates_from_git_config(git_repo) { @@ -318,7 +329,7 @@ pub async fn try_and_get_repo_coordinates_when_remote_unknown( async fn get_nostr_git_remote_selection_labels( git_repo: &Repo, - remote_coordinates: &HashMap, + remote_coordinates: &HashMap, ) -> Result> { let mut res = vec![]; for (remote, c) in remote_coordinates { @@ -334,9 +345,9 @@ async fn get_nostr_git_remote_selection_labels( Ok(res) } -fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result { - Coordinate::parse( - git_repo +fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result { + Nip19Coordinate::from_bech32( + &git_repo .get_git_config_item("nostr.repo", Some(false))? .context("git config item \"nostr.repo\" is not set in local repository")?, ) @@ -345,7 +356,7 @@ fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result { async fn get_repo_coordinates_from_nostr_remotes( git_repo: &Repo, -) -> Result> { +) -> Result> { let mut repo_coordinates = HashMap::new(); for remote_name in git_repo.git_repo.remotes()?.iter().flatten() { if let Some(remote_url) = git_repo.git_repo.find_remote(remote_name)?.url() { @@ -359,21 +370,23 @@ async fn get_repo_coordinates_from_nostr_remotes( Ok(repo_coordinates) } -async fn get_repo_coordinates_from_maintainers_yaml(git_repo: &Repo) -> Result { +async fn get_repo_coordinates_from_maintainers_yaml(git_repo: &Repo) -> Result { let repo_config = get_repo_config_from_yaml(git_repo)?; - Ok(Coordinate { - identifier: repo_config - .identifier - .context("maintainers.yaml doesnt list the identifier")?, - kind: Kind::GitRepoAnnouncement, - public_key: PublicKey::from_bech32( - repo_config - .maintainers - .first() - .context("maintainers.yaml doesnt list any maintainers")?, - ) - .context("maintainers.yaml doesn't list the first maintainer using a valid npub")?, + Ok(Nip19Coordinate { + coordinate: Coordinate { + identifier: repo_config + .identifier + .context("maintainers.yaml doesnt list the identifier")?, + kind: Kind::GitRepoAnnouncement, + public_key: PublicKey::from_bech32( + repo_config + .maintainers + .first() + .context("maintainers.yaml doesnt list any maintainers")?, + ) + .context("maintainers.yaml doesn't list the first maintainer using a valid npub")?, + }, relays: repo_config .relays .iter() @@ -386,7 +399,7 @@ async fn get_repo_coordinate_from_user_prompt( git_repo: &Repo, #[cfg(test)] client: &crate::client::MockConnect, #[cfg(not(test))] client: &Client, -) -> Result { +) -> Result { // TODO: present list of events filter by root_commit // TODO: fallback to search based on identifier let dim = Style::new().color256(247); @@ -401,7 +414,7 @@ async fn get_repo_coordinate_from_user_prompt( loop { let input = Interactor::default() .input(PromptInputParms::default().with_prompt("nostr repository"))?; - let coordinate = if let Ok(c) = Coordinate::parse(&input) { + let coordinate = if let Ok(c) = Nip19Coordinate::from_bech32(&input) { c } else if let Ok(nostr_url) = NostrUrlDecoded::parse_and_resolve(&input, &Some(git_repo)).await @@ -491,7 +504,7 @@ pub fn extract_pks(pk_strings: Vec) -> Result> { let mut pks: Vec = vec![]; for s in pk_strings { pks.push( - nostr_sdk::prelude::PublicKey::from_bech32(s.clone()).context(format!( + nostr_sdk::prelude::PublicKey::from_bech32(&s).context(format!( "failed to convert {s} into a valid nostr public key" ))?, ); -- cgit v1.2.3