diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/client.rs | 73 | ||||
| -rw-r--r-- | src/lib/git/nostr_url.rs | 31 | ||||
| -rw-r--r-- | src/lib/git_events.rs | 19 | ||||
| -rw-r--r-- | src/lib/login/fresh.rs | 12 | ||||
| -rw-r--r-- | src/lib/repo_ref.rs | 29 |
5 files changed, 89 insertions, 75 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 7093dd5..051aa3d 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -30,11 +30,11 @@ use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, P | |||
| 30 | #[cfg(test)] | 30 | #[cfg(test)] |
| 31 | use mockall::*; | 31 | use mockall::*; |
| 32 | use nostr::{nips::nip01::Coordinate, Event}; | 32 | use nostr::{nips::nip01::Coordinate, Event}; |
| 33 | use nostr_database::NostrDatabase; | 33 | use nostr_database::NostrEventsDatabase; |
| 34 | use nostr_lmdb::NostrLMDB; | 34 | use nostr_lmdb::NostrLMDB; |
| 35 | use nostr_sdk::{ | 35 | use nostr_sdk::{ |
| 36 | prelude::RelayLimits, EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, | 36 | prelude::RelayLimits, EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, |
| 37 | SingleLetterTag, Timestamp, Url, | 37 | SingleLetterTag, Timestamp, |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | use crate::{ | 40 | use crate::{ |
| @@ -63,7 +63,7 @@ pub trait Connect { | |||
| 63 | fn default() -> Self; | 63 | fn default() -> Self; |
| 64 | fn new(opts: Params) -> Self; | 64 | fn new(opts: Params) -> Self; |
| 65 | async fn set_signer(&mut self, signer: Arc<dyn NostrSigner>); | 65 | async fn set_signer(&mut self, signer: Arc<dyn NostrSigner>); |
| 66 | async fn connect(&self, relay_url: &Url) -> Result<()>; | 66 | async fn connect(&self, relay_url: &RelayUrl) -> Result<()>; |
| 67 | async fn disconnect(&self) -> Result<()>; | 67 | async fn disconnect(&self) -> Result<()>; |
| 68 | fn get_fallback_relays(&self) -> &Vec<String>; | 68 | fn get_fallback_relays(&self) -> &Vec<String>; |
| 69 | fn get_more_fallback_relays(&self) -> &Vec<String>; | 69 | fn get_more_fallback_relays(&self) -> &Vec<String>; |
| @@ -82,7 +82,7 @@ pub trait Connect { | |||
| 82 | ) -> Result<Vec<nostr::Event>>; | 82 | ) -> Result<Vec<nostr::Event>>; |
| 83 | async fn get_events_per_relay( | 83 | async fn get_events_per_relay( |
| 84 | &self, | 84 | &self, |
| 85 | relays: Vec<Url>, | 85 | relays: Vec<RelayUrl>, |
| 86 | filters: Vec<nostr::Filter>, | 86 | filters: Vec<nostr::Filter>, |
| 87 | progress_reporter: MultiProgress, | 87 | progress_reporter: MultiProgress, |
| 88 | ) -> Result<(Vec<Result<Vec<nostr::Event>>>, MultiProgress)>; | 88 | ) -> Result<(Vec<Result<Vec<nostr::Event>>>, MultiProgress)>; |
| @@ -172,7 +172,7 @@ impl Connect for Client { | |||
| 172 | self.client.set_signer(signer).await; | 172 | self.client.set_signer(signer).await; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | async fn connect(&self, relay_url: &Url) -> Result<()> { | 175 | async fn connect(&self, relay_url: &RelayUrl) -> Result<()> { |
| 176 | self.client | 176 | self.client |
| 177 | .add_relay(relay_url) | 177 | .add_relay(relay_url) |
| 178 | .await | 178 | .await |
| @@ -244,7 +244,7 @@ impl Connect for Client { | |||
| 244 | ) -> Result<Vec<nostr::Event>> { | 244 | ) -> Result<Vec<nostr::Event>> { |
| 245 | let (relay_results, _) = self | 245 | let (relay_results, _) = self |
| 246 | .get_events_per_relay( | 246 | .get_events_per_relay( |
| 247 | relays.iter().map(|r| Url::parse(r).unwrap()).collect(), | 247 | relays.iter().map(|r| RelayUrl::parse(r).unwrap()).collect(), |
| 248 | filters, | 248 | filters, |
| 249 | MultiProgress::new(), | 249 | MultiProgress::new(), |
| 250 | ) | 250 | ) |
| @@ -254,7 +254,7 @@ impl Connect for Client { | |||
| 254 | 254 | ||
| 255 | async fn get_events_per_relay( | 255 | async fn get_events_per_relay( |
| 256 | &self, | 256 | &self, |
| 257 | relays: Vec<Url>, | 257 | relays: Vec<RelayUrl>, |
| 258 | filters: Vec<nostr::Filter>, | 258 | filters: Vec<nostr::Filter>, |
| 259 | progress_reporter: MultiProgress, | 259 | progress_reporter: MultiProgress, |
| 260 | ) -> Result<(Vec<Result<Vec<nostr::Event>>>, MultiProgress)> { | 260 | ) -> Result<(Vec<Result<Vec<nostr::Event>>>, MultiProgress)> { |
| @@ -335,8 +335,8 @@ impl Connect for Client { | |||
| 335 | let fallback_relays = &self | 335 | let fallback_relays = &self |
| 336 | .fallback_relays | 336 | .fallback_relays |
| 337 | .iter() | 337 | .iter() |
| 338 | .filter_map(|r| Url::parse(r).ok()) | 338 | .filter_map(|r| RelayUrl::parse(r).ok()) |
| 339 | .collect::<HashSet<Url>>(); | 339 | .collect::<HashSet<RelayUrl>>(); |
| 340 | 340 | ||
| 341 | let mut request = create_relays_request( | 341 | let mut request = create_relays_request( |
| 342 | git_repo_path, | 342 | git_repo_path, |
| @@ -359,17 +359,17 @@ impl Connect for Client { | |||
| 359 | // don't look for events on blaster | 359 | // don't look for events on blaster |
| 360 | .filter(|&r| !r.as_str().contains("nostr.mutinywallet.com")) | 360 | .filter(|&r| !r.as_str().contains("nostr.mutinywallet.com")) |
| 361 | .cloned() | 361 | .cloned() |
| 362 | .collect::<HashSet<Url>>() | 362 | .collect::<HashSet<RelayUrl>>() |
| 363 | .difference(&processed_relays) | 363 | .difference(&processed_relays) |
| 364 | .cloned() | 364 | .cloned() |
| 365 | .collect::<HashSet<Url>>(); | 365 | .collect::<HashSet<RelayUrl>>(); |
| 366 | if relays.is_empty() { | 366 | if relays.is_empty() { |
| 367 | break; | 367 | break; |
| 368 | } | 368 | } |
| 369 | let profile_relays_only = request | 369 | let profile_relays_only = request |
| 370 | .user_relays_for_profiles | 370 | .user_relays_for_profiles |
| 371 | .difference(&request.repo_relays) | 371 | .difference(&request.repo_relays) |
| 372 | .collect::<HashSet<&Url>>(); | 372 | .collect::<HashSet<&RelayUrl>>(); |
| 373 | for relay in &request.repo_relays { | 373 | for relay in &request.repo_relays { |
| 374 | self.client | 374 | self.client |
| 375 | .add_relay(relay.as_str()) | 375 | .add_relay(relay.as_str()) |
| @@ -469,11 +469,7 @@ impl Connect for Client { | |||
| 469 | processed_relays.extend(relays.clone()); | 469 | processed_relays.extend(relays.clone()); |
| 470 | 470 | ||
| 471 | if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await { | 471 | if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await { |
| 472 | request.repo_relays = repo_ref | 472 | request.repo_relays = repo_ref.relays.iter().cloned().collect(); |
| 473 | .relays | ||
| 474 | .iter() | ||
| 475 | .filter_map(|r| Url::parse(r).ok()) | ||
| 476 | .collect(); | ||
| 477 | } | 473 | } |
| 478 | 474 | ||
| 479 | request.user_relays_for_profiles = { | 475 | request.user_relays_for_profiles = { |
| @@ -486,7 +482,7 @@ impl Connect for Client { | |||
| 486 | { | 482 | { |
| 487 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { | 483 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { |
| 488 | for r in user_ref.relays.write() { | 484 | for r in user_ref.relays.write() { |
| 489 | if let Ok(url) = Url::parse(&r) { | 485 | if let Ok(url) = RelayUrl::parse(&r) { |
| 490 | set.insert(url); | 486 | set.insert(url); |
| 491 | } | 487 | } |
| 492 | } | 488 | } |
| @@ -905,7 +901,7 @@ async fn create_relays_request( | |||
| 905 | git_repo_path: Option<&Path>, | 901 | git_repo_path: Option<&Path>, |
| 906 | repo_coordinates: &HashSet<Coordinate>, | 902 | repo_coordinates: &HashSet<Coordinate>, |
| 907 | user_profiles: &HashSet<PublicKey>, | 903 | user_profiles: &HashSet<PublicKey>, |
| 908 | fallback_relays: HashSet<Url>, | 904 | fallback_relays: HashSet<RelayUrl>, |
| 909 | ) -> Result<FetchRequest> { | 905 | ) -> Result<FetchRequest> { |
| 910 | let repo_ref = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await; | 906 | let repo_ref = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await; |
| 911 | 907 | ||
| @@ -1026,7 +1022,7 @@ async fn create_relays_request( | |||
| 1026 | { | 1022 | { |
| 1027 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { | 1023 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { |
| 1028 | for r in user_ref.relays.write() { | 1024 | for r in user_ref.relays.write() { |
| 1029 | if let Ok(url) = Url::parse(&r) { | 1025 | if let Ok(url) = RelayUrl::parse(&r) { |
| 1030 | set.insert(url); | 1026 | set.insert(url); |
| 1031 | } | 1027 | } |
| 1032 | } | 1028 | } |
| @@ -1068,17 +1064,13 @@ async fn create_relays_request( | |||
| 1068 | let relays = { | 1064 | let relays = { |
| 1069 | let mut relays = fallback_relays; | 1065 | let mut relays = fallback_relays; |
| 1070 | if let Ok(repo_ref) = &repo_ref { | 1066 | if let Ok(repo_ref) = &repo_ref { |
| 1071 | for r in &repo_ref.relays { | 1067 | for r in repo_ref.relays.clone() { |
| 1072 | if let Ok(url) = Url::parse(r) { | 1068 | relays.insert(r); |
| 1073 | relays.insert(url); | ||
| 1074 | } | ||
| 1075 | } | 1069 | } |
| 1076 | } | 1070 | } |
| 1077 | for c in repo_coordinates { | 1071 | for c in repo_coordinates { |
| 1078 | for r in &c.relays { | 1072 | for r in &c.relays { |
| 1079 | if let Ok(url) = Url::parse(r) { | 1073 | relays.insert(r.clone()); |
| 1080 | relays.insert(url); | ||
| 1081 | } | ||
| 1082 | } | 1074 | } |
| 1083 | } | 1075 | } |
| 1084 | relays | 1076 | relays |
| @@ -1500,8 +1492,8 @@ impl Display for FetchReport { | |||
| 1500 | 1492 | ||
| 1501 | #[derive(Default, Clone)] | 1493 | #[derive(Default, Clone)] |
| 1502 | pub struct FetchRequest { | 1494 | pub struct FetchRequest { |
| 1503 | repo_relays: HashSet<Url>, | 1495 | repo_relays: HashSet<RelayUrl>, |
| 1504 | selected_relay: Option<Url>, | 1496 | selected_relay: Option<RelayUrl>, |
| 1505 | relay_column_width: usize, | 1497 | relay_column_width: usize, |
| 1506 | repo_coordinates_without_relays: Vec<(Coordinate, Option<Timestamp>)>, | 1498 | repo_coordinates_without_relays: Vec<(Coordinate, Option<Timestamp>)>, |
| 1507 | state: Option<(Timestamp, EventId)>, | 1499 | state: Option<(Timestamp, EventId)>, |
| @@ -1510,7 +1502,7 @@ pub struct FetchRequest { | |||
| 1510 | missing_contributor_profiles: HashSet<PublicKey>, | 1502 | missing_contributor_profiles: HashSet<PublicKey>, |
| 1511 | existing_events: HashSet<EventId>, | 1503 | existing_events: HashSet<EventId>, |
| 1512 | profiles_to_fetch_from_user_relays: HashMap<PublicKey, (Timestamp, Timestamp)>, | 1504 | profiles_to_fetch_from_user_relays: HashMap<PublicKey, (Timestamp, Timestamp)>, |
| 1513 | user_relays_for_profiles: HashSet<Url>, | 1505 | user_relays_for_profiles: HashSet<RelayUrl>, |
| 1514 | } | 1506 | } |
| 1515 | 1507 | ||
| 1516 | pub async fn fetching_with_report( | 1508 | pub async fn fetching_with_report( |
| @@ -1646,7 +1638,7 @@ pub async fn send_events( | |||
| 1646 | git_repo_path: Option<&Path>, | 1638 | git_repo_path: Option<&Path>, |
| 1647 | events: Vec<nostr::Event>, | 1639 | events: Vec<nostr::Event>, |
| 1648 | my_write_relays: Vec<String>, | 1640 | my_write_relays: Vec<String>, |
| 1649 | repo_read_relays: Vec<String>, | 1641 | repo_read_relays: Vec<RelayUrl>, |
| 1650 | animate: bool, | 1642 | animate: bool, |
| 1651 | silent: bool, | 1643 | silent: bool, |
| 1652 | ) -> Result<()> { | 1644 | ) -> Result<()> { |
| @@ -1659,7 +1651,12 @@ pub async fn send_events( | |||
| 1659 | }, | 1651 | }, |
| 1660 | ] | 1652 | ] |
| 1661 | .concat(); | 1653 | .concat(); |
| 1662 | let mut relays: Vec<&String> = vec![]; | 1654 | let mut relays: Vec<&str> = vec![]; |
| 1655 | |||
| 1656 | let repo_read_relays = repo_read_relays | ||
| 1657 | .iter() | ||
| 1658 | .map(|r| r.to_string()) | ||
| 1659 | .collect::<Vec<String>>(); | ||
| 1663 | 1660 | ||
| 1664 | let all = &[ | 1661 | let all = &[ |
| 1665 | repo_read_relays.clone(), | 1662 | repo_read_relays.clone(), |
| @@ -1722,7 +1719,7 @@ pub async fn send_events( | |||
| 1722 | 1719 | ||
| 1723 | #[allow(clippy::borrow_deref_ref)] | 1720 | #[allow(clippy::borrow_deref_ref)] |
| 1724 | join_all(relays.iter().map(|&relay| async { | 1721 | join_all(relays.iter().map(|&relay| async { |
| 1725 | let relay_clean = remove_trailing_slash(&*relay); | 1722 | let relay_clean = remove_trailing_slash(relay); |
| 1726 | let details = format!( | 1723 | let details = format!( |
| 1727 | "{}{}{} {}", | 1724 | "{}{}{} {}", |
| 1728 | if my_write_relays | 1725 | if my_write_relays |
| @@ -1735,7 +1732,7 @@ pub async fn send_events( | |||
| 1735 | }, | 1732 | }, |
| 1736 | if repo_read_relays | 1733 | if repo_read_relays |
| 1737 | .iter() | 1734 | .iter() |
| 1738 | .any(|r| relay_clean.eq(&remove_trailing_slash(r))) | 1735 | .any(|r| relay_clean.eq(&remove_trailing_slash(&r.to_string()))) |
| 1739 | { | 1736 | { |
| 1740 | " [repo-relay]" | 1737 | " [repo-relay]" |
| 1741 | } else { | 1738 | } else { |
| @@ -1763,7 +1760,7 @@ pub async fn send_events( | |||
| 1763 | let mut failed = false; | 1760 | let mut failed = false; |
| 1764 | for event in &events { | 1761 | for event in &events { |
| 1765 | match client | 1762 | match client |
| 1766 | .send_event_to(git_repo_path, relay.as_str(), event.clone()) | 1763 | .send_event_to(git_repo_path, relay, event.clone()) |
| 1767 | .await | 1764 | .await |
| 1768 | { | 1765 | { |
| 1769 | Ok(_) => pb.inc(1), | 1766 | Ok(_) => pb.inc(1), |
| @@ -1793,8 +1790,8 @@ pub async fn send_events( | |||
| 1793 | Ok(()) | 1790 | Ok(()) |
| 1794 | } | 1791 | } |
| 1795 | 1792 | ||
| 1796 | fn remove_trailing_slash(s: &String) -> String { | 1793 | fn remove_trailing_slash(s: &str) -> String { |
| 1797 | match s.as_str().strip_suffix('/') { | 1794 | match s.strip_suffix('/') { |
| 1798 | Some(s) => s, | 1795 | Some(s) => s, |
| 1799 | None => s, | 1796 | None => s, |
| 1800 | } | 1797 | } |
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index b310782..e4b6825 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs | |||
| @@ -3,7 +3,7 @@ use std::{collections::HashSet, str::FromStr}; | |||
| 3 | 3 | ||
| 4 | use anyhow::{anyhow, bail, Context, Error, Result}; | 4 | use anyhow::{anyhow, bail, Context, Error, Result}; |
| 5 | use nostr::nips::nip01::Coordinate; | 5 | use nostr::nips::nip01::Coordinate; |
| 6 | use nostr_sdk::{PublicKey, Url}; | 6 | use nostr_sdk::{PublicKey, RelayUrl, Url}; |
| 7 | 7 | ||
| 8 | #[derive(Debug, PartialEq, Default, Clone)] | 8 | #[derive(Debug, PartialEq, Default, Clone)] |
| 9 | pub enum ServerProtocol { | 9 | pub enum ServerProtocol { |
| @@ -85,8 +85,8 @@ impl std::str::FromStr for NostrUrlDecoded { | |||
| 85 | decoded = format!("wss://{decoded}"); | 85 | decoded = format!("wss://{decoded}"); |
| 86 | } | 86 | } |
| 87 | let url = | 87 | let url = |
| 88 | Url::parse(&decoded).context("could not parse relays in nostr git url")?; | 88 | RelayUrl::parse(&decoded).context("could not parse relays in nostr git url")?; |
| 89 | relays.push(url.to_string()); | 89 | relays.push(url); |
| 90 | } else if name == "protocol" { | 90 | } else if name == "protocol" { |
| 91 | protocol = match value.as_ref() { | 91 | protocol = match value.as_ref() { |
| 92 | "ssh" => Some(ServerProtocol::Ssh), | 92 | "ssh" => Some(ServerProtocol::Ssh), |
| @@ -151,8 +151,8 @@ impl std::str::FromStr for NostrUrlDecoded { | |||
| 151 | decoded = format!("wss://{decoded}"); | 151 | decoded = format!("wss://{decoded}"); |
| 152 | } | 152 | } |
| 153 | let url = | 153 | let url = |
| 154 | Url::parse(&decoded).context("could not parse relays in nostr git url")?; | 154 | RelayUrl::parse(&decoded).context("could not parse relays in nostr git url")?; |
| 155 | relays.push(url.to_string()); | 155 | relays.push(url); |
| 156 | } | 156 | } |
| 157 | coordinates.insert(Coordinate { | 157 | coordinates.insert(Coordinate { |
| 158 | identifier, | 158 | identifier, |
| @@ -852,7 +852,7 @@ mod tests { | |||
| 852 | .unwrap(), | 852 | .unwrap(), |
| 853 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 853 | kind: nostr_sdk::Kind::GitRepoAnnouncement, |
| 854 | relays: if relays { | 854 | relays: if relays { |
| 855 | vec!["wss://nos.lol/".to_string()] | 855 | vec![RelayUrl::parse("wss://nos.lol").unwrap()] |
| 856 | } else { | 856 | } else { |
| 857 | vec![] | 857 | vec![] |
| 858 | }, | 858 | }, |
| @@ -873,7 +873,8 @@ mod tests { | |||
| 873 | ) | 873 | ) |
| 874 | .unwrap(), | 874 | .unwrap(), |
| 875 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 875 | kind: nostr_sdk::Kind::GitRepoAnnouncement, |
| 876 | relays: vec!["wss://nos.lol".to_string()], // wont add the slash | 876 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], /* wont add the |
| 877 | * slash */ | ||
| 877 | }]), | 878 | }]), |
| 878 | protocol: None, | 879 | protocol: None, |
| 879 | user: None, | 880 | user: None, |
| @@ -942,8 +943,8 @@ mod tests { | |||
| 942 | fn with_multiple_encoded_relays() -> Result<()> { | 943 | fn with_multiple_encoded_relays() -> Result<()> { |
| 943 | let url = format!( | 944 | let url = format!( |
| 944 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}&relay1={}", | 945 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}&relay1={}", |
| 945 | urlencoding::encode("wss://nos.lol"), | 946 | urlencoding::encode("wss://nos.lol/"), |
| 946 | urlencoding::encode("wss://relay.damus.io"), | 947 | urlencoding::encode("wss://relay.damus.io/"), |
| 947 | ); | 948 | ); |
| 948 | assert_eq!( | 949 | assert_eq!( |
| 949 | NostrUrlDecoded::from_str(&url)?, | 950 | NostrUrlDecoded::from_str(&url)?, |
| @@ -957,8 +958,8 @@ mod tests { | |||
| 957 | .unwrap(), | 958 | .unwrap(), |
| 958 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 959 | kind: nostr_sdk::Kind::GitRepoAnnouncement, |
| 959 | relays: vec![ | 960 | relays: vec![ |
| 960 | "wss://nos.lol/".to_string(), | 961 | RelayUrl::parse("wss://nos.lol/").unwrap(), |
| 961 | "wss://relay.damus.io/".to_string(), | 962 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), |
| 962 | ], | 963 | ], |
| 963 | }]), | 964 | }]), |
| 964 | protocol: None, | 965 | protocol: None, |
| @@ -1039,8 +1040,8 @@ mod tests { | |||
| 1039 | fn with_multiple_encoded_relays() -> Result<()> { | 1040 | fn with_multiple_encoded_relays() -> Result<()> { |
| 1040 | let url = format!( | 1041 | let url = format!( |
| 1041 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/{}/ngit", | 1042 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/{}/ngit", |
| 1042 | urlencoding::encode("wss://nos.lol"), | 1043 | urlencoding::encode("wss://nos.lol/"), |
| 1043 | urlencoding::encode("wss://relay.damus.io"), | 1044 | urlencoding::encode("wss://relay.damus.io/"), |
| 1044 | ); | 1045 | ); |
| 1045 | assert_eq!( | 1046 | assert_eq!( |
| 1046 | NostrUrlDecoded::from_str(&url)?, | 1047 | NostrUrlDecoded::from_str(&url)?, |
| @@ -1054,8 +1055,8 @@ mod tests { | |||
| 1054 | .unwrap(), | 1055 | .unwrap(), |
| 1055 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1056 | kind: nostr_sdk::Kind::GitRepoAnnouncement, |
| 1056 | relays: vec![ | 1057 | relays: vec![ |
| 1057 | "wss://nos.lol/".to_string(), | 1058 | RelayUrl::parse("wss://nos.lol/").unwrap(), |
| 1058 | "wss://relay.damus.io/".to_string(), | 1059 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), |
| 1059 | ], | 1060 | ], |
| 1060 | }]), | 1061 | }]), |
| 1061 | protocol: None, | 1062 | protocol: None, |
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs index bfe5b30..c4d6770 100644 --- a/src/lib/git_events.rs +++ b/src/lib/git_events.rs | |||
| @@ -4,7 +4,7 @@ use anyhow::{bail, Context, Result}; | |||
| 4 | use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; | 4 | use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; |
| 5 | use nostr_sdk::{ | 5 | use nostr_sdk::{ |
| 6 | hashes::sha1::Hash as Sha1Hash, Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, | 6 | hashes::sha1::Hash as Sha1Hash, Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, |
| 7 | PublicKey, Tag, TagKind, TagStandard, UncheckedUrl, | 7 | PublicKey, RelayUrl, Tag, TagKind, TagStandard, |
| 8 | }; | 8 | }; |
| 9 | 9 | ||
| 10 | use crate::{ | 10 | use crate::{ |
| @@ -96,7 +96,7 @@ pub async fn generate_patch_event( | |||
| 96 | let commit_parent = git_repo | 96 | let commit_parent = git_repo |
| 97 | .get_commit_parent(commit) | 97 | .get_commit_parent(commit) |
| 98 | .context("failed to get parent commit")?; | 98 | .context("failed to get parent commit")?; |
| 99 | let relay_hint = repo_ref.relays.first().map(nostr::UncheckedUrl::from); | 99 | let relay_hint = repo_ref.relays.first().cloned(); |
| 100 | 100 | ||
| 101 | sign_event( | 101 | sign_event( |
| 102 | EventBuilder::new( | 102 | EventBuilder::new( |
| @@ -104,6 +104,8 @@ pub async fn generate_patch_event( | |||
| 104 | git_repo | 104 | git_repo |
| 105 | .make_patch_from_commit(commit, &series_count) | 105 | .make_patch_from_commit(commit, &series_count) |
| 106 | .context(format!("failed to make patch for commit {commit}"))?, | 106 | .context(format!("failed to make patch for commit {commit}"))?, |
| 107 | ) | ||
| 108 | .tags( | ||
| 107 | [ | 109 | [ |
| 108 | repo_ref | 110 | repo_ref |
| 109 | .maintainers | 111 | .maintainers |
| @@ -141,6 +143,7 @@ pub async fn generate_patch_event( | |||
| 141 | relay_url: relay_hint.clone(), | 143 | relay_url: relay_hint.clone(), |
| 142 | marker: Some(Marker::Root), | 144 | marker: Some(Marker::Root), |
| 143 | public_key: None, | 145 | public_key: None, |
| 146 | uppercase: false, | ||
| 144 | })] | 147 | })] |
| 145 | } else if let Some(event_ref) = root_proposal_id.clone() { | 148 | } else if let Some(event_ref) = root_proposal_id.clone() { |
| 146 | vec![ | 149 | vec![ |
| @@ -165,6 +168,7 @@ pub async fn generate_patch_event( | |||
| 165 | relay_url: relay_hint.clone(), | 168 | relay_url: relay_hint.clone(), |
| 166 | marker: Some(Marker::Reply), | 169 | marker: Some(Marker::Reply), |
| 167 | public_key: None, | 170 | public_key: None, |
| 171 | uppercase: false, | ||
| 168 | })] | 172 | })] |
| 169 | } else { | 173 | } else { |
| 170 | vec![] | 174 | vec![] |
| @@ -256,9 +260,10 @@ pub fn event_tag_from_nip19_or_hex( | |||
| 256 | Nip19::Event(n) => { | 260 | Nip19::Event(n) => { |
| 257 | break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { | 261 | break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { |
| 258 | event_id: n.event_id, | 262 | event_id: n.event_id, |
| 259 | relay_url: n.relays.first().map(UncheckedUrl::new), | 263 | relay_url: n.relays.first().and_then(|url| RelayUrl::parse(url).ok()), |
| 260 | marker: Some(marker), | 264 | marker: Some(marker), |
| 261 | public_key: None, | 265 | public_key: None, |
| 266 | uppercase: false, | ||
| 262 | })); | 267 | })); |
| 263 | } | 268 | } |
| 264 | Nip19::EventId(id) => { | 269 | Nip19::EventId(id) => { |
| @@ -267,6 +272,7 @@ pub fn event_tag_from_nip19_or_hex( | |||
| 267 | relay_url: None, | 272 | relay_url: None, |
| 268 | marker: Some(marker), | 273 | marker: Some(marker), |
| 269 | public_key: None, | 274 | public_key: None, |
| 275 | uppercase: false, | ||
| 270 | })); | 276 | })); |
| 271 | } | 277 | } |
| 272 | Nip19::Coordinate(coordinate) => { | 278 | Nip19::Coordinate(coordinate) => { |
| @@ -291,6 +297,7 @@ pub fn event_tag_from_nip19_or_hex( | |||
| 291 | relay_url: None, | 297 | relay_url: None, |
| 292 | marker: Some(marker), | 298 | marker: Some(marker), |
| 293 | public_key: None, | 299 | public_key: None, |
| 300 | uppercase: false, | ||
| 294 | })); | 301 | })); |
| 295 | } | 302 | } |
| 296 | if prompt_for_correction { | 303 | if prompt_for_correction { |
| @@ -326,7 +333,8 @@ pub async fn generate_cover_letter_and_patch_events( | |||
| 326 | "From {} Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/{}] {title}\n\n{description}", | 333 | "From {} Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/{}] {title}\n\n{description}", |
| 327 | commits.last().unwrap(), | 334 | commits.last().unwrap(), |
| 328 | commits.len() | 335 | commits.len() |
| 329 | ), | 336 | )) |
| 337 | .tags( | ||
| 330 | [ | 338 | [ |
| 331 | repo_ref.maintainers.iter().map(|m| Tag::coordinate(Coordinate { | 339 | repo_ref.maintainers.iter().map(|m| Tag::coordinate(Coordinate { |
| 332 | kind: nostr::Kind::GitRepoAnnouncement, | 340 | kind: nostr::Kind::GitRepoAnnouncement, |
| @@ -618,7 +626,8 @@ mod tests { | |||
| 618 | Ok(nostr::event::EventBuilder::new( | 626 | Ok(nostr::event::EventBuilder::new( |
| 619 | nostr::event::Kind::GitPatch, | 627 | nostr::event::Kind::GitPatch, |
| 620 | format!("From ea897e987ea9a7a98e7a987e97987ea98e7a3334 Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/2] {title}\n\n{description}"), | 628 | format!("From ea897e987ea9a7a98e7a987e97987ea98e7a3334 Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/2] {title}\n\n{description}"), |
| 621 | [ | 629 | ) |
| 630 | .tags([ | ||
| 622 | Tag::hashtag("cover-letter"), | 631 | Tag::hashtag("cover-letter"), |
| 623 | Tag::hashtag("root"), | 632 | Tag::hashtag("root"), |
| 624 | ], | 633 | ], |
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index 23c4bdc..615c0a6 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs | |||
| @@ -5,7 +5,7 @@ use console::Style; | |||
| 5 | use dialoguer::theme::{ColorfulTheme, Theme}; | 5 | use dialoguer::theme::{ColorfulTheme, Theme}; |
| 6 | use nostr::nips::{nip05, nip46::NostrConnectURI}; | 6 | use nostr::nips::{nip05, nip46::NostrConnectURI}; |
| 7 | use nostr_connect::client::NostrConnect; | 7 | use nostr_connect::client::NostrConnect; |
| 8 | use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, ToBech32, Url}; | 8 | use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, RelayUrl, ToBech32}; |
| 9 | use qrcode::QrCode; | 9 | use qrcode::QrCode; |
| 10 | use tokio::{signal, sync::Mutex}; | 10 | use tokio::{signal, sync::Mutex}; |
| 11 | 11 | ||
| @@ -370,8 +370,8 @@ pub fn generate_nostr_connect_app( | |||
| 370 | client | 370 | client |
| 371 | .get_fallback_signer_relays() | 371 | .get_fallback_signer_relays() |
| 372 | .iter() | 372 | .iter() |
| 373 | .flat_map(|s| Url::parse(s)) | 373 | .flat_map(RelayUrl::parse) |
| 374 | .collect::<Vec<Url>>() | 374 | .collect::<Vec<RelayUrl>>() |
| 375 | } else { | 375 | } else { |
| 376 | vec![] | 376 | vec![] |
| 377 | }; | 377 | }; |
| @@ -438,8 +438,8 @@ pub async fn listen_for_remote_signer( | |||
| 438 | let bunker_url = NostrConnectURI::Bunker { | 438 | let bunker_url = NostrConnectURI::Bunker { |
| 439 | // TODO the remote signer pubkey may not be the user pubkey | 439 | // TODO the remote signer pubkey may not be the user pubkey |
| 440 | remote_signer_public_key: public_key, | 440 | remote_signer_public_key: public_key, |
| 441 | relays: nostr_connect_url.relays(), | 441 | relays: nostr_connect_url.relays().to_vec(), |
| 442 | secret: nostr_connect_url.secret(), | 442 | secret: nostr_connect_url.secret().map(String::from), |
| 443 | }; | 443 | }; |
| 444 | Ok((signer, public_key, bunker_url)) | 444 | Ok((signer, public_key, bunker_url)) |
| 445 | } else { | 445 | } else { |
| @@ -727,7 +727,7 @@ async fn signup( | |||
| 727 | client | 727 | client |
| 728 | .get_fallback_relays() | 728 | .get_fallback_relays() |
| 729 | .iter() | 729 | .iter() |
| 730 | .map(|s| (Url::parse(s).unwrap(), None)), | 730 | .map(|s| (RelayUrl::parse(s).unwrap(), None)), |
| 731 | ) | 731 | ) |
| 732 | .sign_with_keys(&keys)?; | 732 | .sign_with_keys(&keys)?; |
| 733 | eprintln!("publishing user profile to relays"); | 733 | eprintln!("publishing user profile to relays"); |
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index 05234e2..8319c78 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs | |||
| @@ -9,7 +9,7 @@ use std::{ | |||
| 9 | use anyhow::{bail, Context, Result}; | 9 | use anyhow::{bail, Context, Result}; |
| 10 | use console::Style; | 10 | use console::Style; |
| 11 | use nostr::{nips::nip01::Coordinate, FromBech32, PublicKey, Tag, TagStandard, ToBech32}; | 11 | use nostr::{nips::nip01::Coordinate, FromBech32, PublicKey, Tag, TagStandard, ToBech32}; |
| 12 | use nostr_sdk::{Kind, NostrSigner, Timestamp}; | 12 | use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; |
| 13 | use serde::{Deserialize, Serialize}; | 13 | use serde::{Deserialize, Serialize}; |
| 14 | 14 | ||
| 15 | #[cfg(not(test))] | 15 | #[cfg(not(test))] |
| @@ -28,7 +28,7 @@ pub struct RepoRef { | |||
| 28 | pub root_commit: String, | 28 | pub root_commit: String, |
| 29 | pub git_server: Vec<String>, | 29 | pub git_server: Vec<String>, |
| 30 | pub web: Vec<String>, | 30 | pub web: Vec<String>, |
| 31 | pub relays: Vec<String>, | 31 | pub relays: Vec<RelayUrl>, |
| 32 | pub maintainers: Vec<PublicKey>, | 32 | pub maintainers: Vec<PublicKey>, |
| 33 | pub events: HashMap<Coordinate, nostr::Event>, | 33 | pub events: HashMap<Coordinate, nostr::Event>, |
| 34 | // code languages and hashtags | 34 | // code languages and hashtags |
| @@ -78,8 +78,11 @@ impl TryFrom<nostr::Event> for RepoRef { | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("relays")) { | 80 | if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("relays")) { |
| 81 | r.relays = t.clone().to_vec(); | 81 | for relay in t.clone().to_vec() { |
| 82 | r.relays.remove(0); | 82 | if let Ok(relay) = RelayUrl::parse(relay) { |
| 83 | r.relays.push(relay); | ||
| 84 | } | ||
| 85 | } | ||
| 83 | } | 86 | } |
| 84 | 87 | ||
| 85 | if let Some(t) = event | 88 | if let Some(t) = event |
| @@ -119,9 +122,7 @@ impl TryFrom<nostr::Event> for RepoRef { | |||
| 119 | impl RepoRef { | 122 | impl RepoRef { |
| 120 | pub async fn to_event(&self, signer: &Arc<dyn NostrSigner>) -> Result<nostr::Event> { | 123 | pub async fn to_event(&self, signer: &Arc<dyn NostrSigner>) -> Result<nostr::Event> { |
| 121 | sign_event( | 124 | sign_event( |
| 122 | nostr_sdk::EventBuilder::new( | 125 | nostr_sdk::EventBuilder::new(nostr::event::Kind::GitRepoAnnouncement, "").tags( |
| 123 | nostr::event::Kind::GitRepoAnnouncement, | ||
| 124 | "", | ||
| 125 | [ | 126 | [ |
| 126 | vec![ | 127 | vec![ |
| 127 | Tag::identifier(if self.identifier.to_string().is_empty() { | 128 | Tag::identifier(if self.identifier.to_string().is_empty() { |
| @@ -158,7 +159,7 @@ impl RepoRef { | |||
| 158 | ), | 159 | ), |
| 159 | Tag::custom( | 160 | Tag::custom( |
| 160 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed("relays")), | 161 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed("relays")), |
| 161 | self.relays.clone(), | 162 | self.relays.iter().map(|r| r.to_string()), |
| 162 | ), | 163 | ), |
| 163 | Tag::custom( | 164 | Tag::custom( |
| 164 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed("maintainers")), | 165 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed("maintainers")), |
| @@ -206,7 +207,7 @@ impl RepoRef { | |||
| 206 | .unwrap(), | 207 | .unwrap(), |
| 207 | identifier: self.identifier.clone(), | 208 | identifier: self.identifier.clone(), |
| 208 | relays: if let Some(relay) = self.relays.first() { | 209 | relays: if let Some(relay) = self.relays.first() { |
| 209 | vec![relay.to_string()] | 210 | vec![relay.clone()] |
| 210 | } else { | 211 | } else { |
| 211 | vec![] | 212 | vec![] |
| 212 | }, | 213 | }, |
| @@ -481,7 +482,10 @@ mod tests { | |||
| 481 | "https://exampleproject.xyz".to_string(), | 482 | "https://exampleproject.xyz".to_string(), |
| 482 | "https://gitworkshop.dev/123".to_string(), | 483 | "https://gitworkshop.dev/123".to_string(), |
| 483 | ], | 484 | ], |
| 484 | relays: vec!["ws://relay1.io".to_string(), "ws://relay2.io".to_string()], | 485 | relays: vec![ |
| 486 | RelayUrl::parse("ws://relay1.io").unwrap(), | ||
| 487 | RelayUrl::parse("ws://relay2.io").unwrap(), | ||
| 488 | ], | ||
| 485 | maintainers: vec![TEST_KEY_1_KEYS.public_key(), TEST_KEY_2_KEYS.public_key()], | 489 | maintainers: vec![TEST_KEY_1_KEYS.public_key(), TEST_KEY_2_KEYS.public_key()], |
| 486 | events: HashMap::new(), | 490 | events: HashMap::new(), |
| 487 | } | 491 | } |
| @@ -592,7 +596,10 @@ mod tests { | |||
| 592 | async fn relays() { | 596 | async fn relays() { |
| 593 | assert_eq!( | 597 | assert_eq!( |
| 594 | RepoRef::try_from(create().await).unwrap().relays, | 598 | RepoRef::try_from(create().await).unwrap().relays, |
| 595 | vec!["ws://relay1.io".to_string(), "ws://relay2.io".to_string()], | 599 | vec![ |
| 600 | RelayUrl::parse("ws://relay1.io").unwrap(), | ||
| 601 | RelayUrl::parse("ws://relay2.io").unwrap(), | ||
| 602 | ], | ||
| 596 | ) | 603 | ) |
| 597 | } | 604 | } |
| 598 | 605 | ||