From 6d3a4eb870cd344b11ccda13e1339584ed4e4d17 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 9 Dec 2024 09:34:08 +0000 Subject: feat(NostrUrlDecoded) add nip05 support replace `NostrUrlDecoded::from_str` with `NostrUrlDecoded::parse_and_resolve` store nip05 pubkey mapping in git cache --- src/lib/git/nostr_url.rs | 81 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index c26bb2e..ac57538 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -2,9 +2,11 @@ use core::fmt; use std::str::FromStr; use anyhow::{anyhow, bail, Context, Error, Result}; -use nostr::nips::nip01::Coordinate; +use nostr::nips::{nip01::Coordinate, nip05}; use nostr_sdk::{PublicKey, RelayUrl, ToBech32, Url}; +use super::{get_git_config_item, save_git_config_item, Repo}; + #[derive(Debug, PartialEq, Default, Clone)] pub enum ServerProtocol { Ssh, @@ -59,6 +61,7 @@ pub struct NostrUrlDecoded { pub coordinate: Coordinate, pub protocol: Option, pub user: Option, + pub nip05: Option, } impl fmt::Display for NostrUrlDecoded { @@ -89,10 +92,8 @@ impl fmt::Display for NostrUrlDecoded { static INCORRECT_NOSTR_URL_FORMAT_ERROR: &str = "incorrect nostr git url format. try nostr://naddr123 or nostr://npub123/my-repo or nostr://ssh/npub123/relay.damus.io/my-repo"; -impl std::str::FromStr for NostrUrlDecoded { - type Err = anyhow::Error; - - fn from_str(url: &str) -> Result { +impl NostrUrlDecoded { + pub async fn parse_and_resolve(url: &str, git_repo: &Option<&Repo>) -> Result { let mut protocol = None; let mut user = None; let mut relays = vec![]; @@ -154,6 +155,7 @@ impl std::str::FromStr for NostrUrlDecoded { } // extract naddr npub//identifer let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; + let mut nip05 = None; // naddr used let coordinate = if let Ok(coordinate) = Coordinate::parse(part) { if coordinate.kind.eq(&nostr_sdk::Kind::GitRepoAnnouncement) { @@ -161,8 +163,9 @@ impl std::str::FromStr for NostrUrlDecoded { } else { bail!("naddr doesnt point to a git repository announcement"); } - // npub//identifer used - } else if let Ok(public_key) = PublicKey::parse(part) { + // //identifer used + } else { + let npub_or_nip05 = part.to_owned(); parts.remove(0); let identifier = parts .pop() @@ -179,14 +182,41 @@ impl std::str::FromStr for NostrUrlDecoded { RelayUrl::parse(&decoded).context("could not parse relays in nostr git url")?; relays.push(url); } + let public_key = match PublicKey::parse(npub_or_nip05) { + Ok(public_key) => public_key, + Err(_) => { + nip05 = Some(npub_or_nip05.to_string()); + if let Ok(public_key) = + resolve_nip05_from_git_config_cache(npub_or_nip05, git_repo) + { + public_key + } else { + // TODO eprint loading message + let res = nip05::profile(npub_or_nip05, None) + .await + .context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; + // TODO clear loading message + nip05 = Some(npub_or_nip05.to_string()); + let _ = save_nip05_to_git_config_cache( + npub_or_nip05, + &res.public_key, + git_repo, + ); + if relays.is_empty() { + for r in res.relays { + relays.push(r); + } + } + res.public_key + } + } + }; Coordinate { identifier, public_key, kind: nostr_sdk::Kind::GitRepoAnnouncement, relays, } - } else { - bail!(INCORRECT_NOSTR_URL_FORMAT_ERROR); }; Ok(Self { @@ -194,10 +224,43 @@ impl std::str::FromStr for NostrUrlDecoded { coordinate, protocol, user, + nip05, }) } } +fn resolve_nip05_from_git_config_cache(nip05: &str, git_repo: &Option<&Repo>) -> Result { + let stored_value = get_git_config_item( + git_repo, + &format!("nostr.nip05.{}", urlencoding::encode(nip05)), + )? + .context("not in cache")?; + PublicKey::parse(stored_value) + .context("stored nip05 resolution value did not parse as public key") +} + +fn save_nip05_to_git_config_cache( + nip05: &str, + public_key: &PublicKey, + git_repo: &Option<&Repo>, +) -> Result<()> { + if save_git_config_item( + git_repo, + &format!("nostr.nip05.{}", urlencoding::encode(nip05)), + &public_key.to_bech32()?, + ) + .is_err() + { + save_git_config_item( + &None, + &format!("nostr.nip05.{}", urlencoding::encode(nip05)), + &public_key.to_bech32()?, + ) + } else { + Ok(()) + } +} + #[derive(Debug, PartialEq, Default)] pub struct CloneUrl { original_string: String, -- cgit v1.2.3 From 8bd0f64bfc1d8348aaac11c9882e6211599df320 Mon Sep 17 00:00:00 2001 From: Laszlo Megyer Date: Mon, 9 Dec 2024 23:06:23 +0100 Subject: test(NostrUrlDecoded): use `parse_and_resolve` update tests to use the async `parse_and_resolve` instead of removed `from_str` method --- src/lib/git/nostr_url.rs | 90 ++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 38 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index ac57538..6f418d5 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -950,6 +950,7 @@ mod tests { }, protocol: None, user: None, + nip05: None, } ), "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", @@ -975,6 +976,7 @@ mod tests { }, protocol: None, user: None, + nip05: None, } ), "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit", @@ -1000,6 +1002,7 @@ mod tests { }, protocol: Some(ServerProtocol::Ssh), user: None, + nip05: None, } ), "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", @@ -1025,6 +1028,7 @@ mod tests { }, protocol: Some(ServerProtocol::Ssh), user: Some("bla".to_string()), + nip05: None, } ), "nostr://bla@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", @@ -1034,8 +1038,6 @@ mod tests { } mod nostr_url_decoded_paramemters_from_str { - use std::str::FromStr; - use super::*; fn get_model_coordinate(relays: bool) -> Coordinate { @@ -1054,11 +1056,11 @@ mod tests { } } - #[test] - fn from_naddr() -> Result<()> { + #[tokio::test] + async fn from_naddr() -> Result<()> { let url = "nostr://naddr1qqzxuemfwsqs6amnwvaz7tmwdaejumr0dspzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqvzqqqrhnym0k2qj".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: Coordinate { @@ -1073,6 +1075,7 @@ mod tests { }, protocol: None, user: None, + nip05: None, }, ); Ok(()) @@ -1081,18 +1084,19 @@ mod tests { mod from_npub_slash_identifier { use super::*; - #[test] - fn without_relay() -> Result<()> { + #[tokio::test] + async fn without_relay() -> Result<()> { let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit" .to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(false), protocol: None, user: None, + nip05: None, }, ); Ok(()) @@ -1101,48 +1105,50 @@ mod tests { mod with_url_parameters { use super::*; - #[test] - fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { + #[tokio::test] + async fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay=nos.lol".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(true), protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_encoded_relay() -> Result<()> { + #[tokio::test] + async fn with_encoded_relay() -> Result<()> { let url = format!( "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}", urlencoding::encode("wss://nos.lol") ); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(true), protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_multiple_encoded_relays() -> Result<()> { + #[tokio::test] + async fn with_multiple_encoded_relays() -> Result<()> { let url = format!( "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}&relay1={}", urlencoding::encode("wss://nos.lol/"), urlencoding::encode("wss://relay.damus.io/"), ); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: Coordinate { @@ -1159,36 +1165,39 @@ mod tests { }, protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_server_protocol() -> Result<()> { + #[tokio::test] + async fn with_server_protocol() -> Result<()> { let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(false), protocol: Some(ServerProtocol::Ssh), user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_server_protocol_and_user() -> Result<()> { + #[tokio::test] + async fn with_server_protocol_and_user() -> Result<()> { let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh&user=fred".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(false), protocol: Some(ServerProtocol::Ssh), user: Some("fred".to_string()), + nip05: None, }, ); Ok(()) @@ -1198,48 +1207,50 @@ mod tests { mod with_parameters_embedded_with_slashes { use super::*; - #[test] - fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { + #[tokio::test] + async fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(true), protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_encoded_relay() -> Result<()> { + #[tokio::test] + async fn with_encoded_relay() -> Result<()> { let url = format!( "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/ngit", urlencoding::encode("wss://nos.lol") ); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(true), protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_multiple_encoded_relays() -> Result<()> { + #[tokio::test] + async fn with_multiple_encoded_relays() -> Result<()> { let url = format!( "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/{}/ngit", urlencoding::encode("wss://nos.lol/"), urlencoding::encode("wss://relay.damus.io/"), ); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: Coordinate { @@ -1256,36 +1267,39 @@ mod tests { }, protocol: None, user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_server_protocol() -> Result<()> { + #[tokio::test] + async fn with_server_protocol() -> Result<()> { let url = "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(false), protocol: Some(ServerProtocol::Ssh), user: None, + nip05: None, }, ); Ok(()) } - #[test] - fn with_server_protocol_and_user() -> Result<()> { + #[tokio::test] + async fn with_server_protocol_and_user() -> Result<()> { let url = "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); assert_eq!( - NostrUrlDecoded::from_str(&url)?, + NostrUrlDecoded::parse_and_resolve(&url, &None).await?, NostrUrlDecoded { original_string: url.clone(), coordinate: get_model_coordinate(false), protocol: Some(ServerProtocol::Ssh), user: Some("fred".to_string()), + nip05: None, }, ); Ok(()) -- cgit v1.2.3 From 8d8c21d05e4d8d7af30a96704a5919efc07010dc Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 10 Dec 2024 11:45:24 +0000 Subject: feat(nostr_url): improve nip05 git cache format store all nip05s in a single git config item called "nostr.nip05" using the `:` format with multiple values comma seperated. git config is suposed to be human readable so it consideration was given to storing the npub instead of hex but nip05 generally uses hex and its rarely, if at all, going to be read directly by humans. in the future it might be better to use git syntax for storing multiple items but library git2 doesn't support this. it would be trivial to do though. multiple nip05 items is an edge case so this format is ok for now. --- src/lib/git/nostr_url.rs | 53 ++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index 6f418d5..8bf458b 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -1,5 +1,5 @@ use core::fmt; -use std::str::FromStr; +use std::{collections::HashMap, str::FromStr}; use anyhow::{anyhow, bail, Context, Error, Result}; use nostr::nips::{nip01::Coordinate, nip05}; @@ -230,13 +230,11 @@ impl NostrUrlDecoded { } fn resolve_nip05_from_git_config_cache(nip05: &str, git_repo: &Option<&Repo>) -> Result { - let stored_value = get_git_config_item( - git_repo, - &format!("nostr.nip05.{}", urlencoding::encode(nip05)), - )? - .context("not in cache")?; - PublicKey::parse(stored_value) - .context("stored nip05 resolution value did not parse as public key") + if let Some(public_key) = load_nip_cache(git_repo)?.get(nip05) { + Ok(*public_key) + } else { + bail!("nip05 not stored in local git config cache") + } } fn save_nip05_to_git_config_cache( @@ -244,21 +242,32 @@ fn save_nip05_to_git_config_cache( public_key: &PublicKey, git_repo: &Option<&Repo>, ) -> Result<()> { - if save_git_config_item( - git_repo, - &format!("nostr.nip05.{}", urlencoding::encode(nip05)), - &public_key.to_bech32()?, - ) - .is_err() - { - save_git_config_item( - &None, - &format!("nostr.nip05.{}", urlencoding::encode(nip05)), - &public_key.to_bech32()?, - ) - } else { - Ok(()) + let mut h = load_nip_cache(git_repo)?; + h.insert(nip05.to_string(), *public_key); + + let s = h + .into_iter() + .map(|(nip05, public_key)| format!("{nip05}:{}", public_key.to_hex())) + .collect::>() + .join(","); + + save_git_config_item(git_repo, "nostr.nip05", s.as_str()) + .context("could not save nip05 cache in git config") +} + +fn load_nip_cache(git_repo: &Option<&Repo>) -> Result> { + let mut h = HashMap::new(); + let stored_value = get_git_config_item(git_repo, "nostr.nip05")? + .context("no nip05s in local git config cache so retun empty cache") + .unwrap_or_default(); + for pair in stored_value.split(',') { + if let Some((cached_nip05, pubkey)) = pair.split_once(':') { + if let Ok(public_key) = PublicKey::parse(pubkey) { + h.insert(cached_nip05.to_string(), public_key); + } + } } + Ok(h) } #[derive(Debug, PartialEq, Default)] -- cgit v1.2.3 From 36eb9395567dc0022b1700ec9cda1389baf22476 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 10 Dec 2024 12:12:14 +0000 Subject: fix(nostr_url): use nip05 in nostr url if cached prioritise using nip05 nostr url format when the nip05, public key mapping is stored in the (usually local) git config. --- src/bin/ngit/sub_commands/init.rs | 6 +++--- src/lib/git/nostr_url.rs | 10 ++++++++++ src/lib/repo_ref.rs | 20 ++++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs index c9c8873..86b681c 100644 --- a/src/bin/ngit/sub_commands/init.rs +++ b/src/bin/ngit/sub_commands/init.rs @@ -522,7 +522,7 @@ async fn prompt_to_set_nostr_url_as_origin(repo_ref: &RepoRef, git_repo: &Repo) } } println!("contributors can clone your repository by installing ngit and using this clone url:"); - println!("{}", repo_ref.to_nostr_git_url()); + println!("{}", repo_ref.to_nostr_git_url(&Some(git_repo))); Ok(()) } @@ -535,7 +535,7 @@ fn ask_to_set_origin_remote(repo_ref: &RepoRef, git_repo: &Repo) -> Result<()> { )? { git_repo .git_repo - .remote_set_url("origin", &repo_ref.to_nostr_git_url())?; + .remote_set_url("origin", &repo_ref.to_nostr_git_url(&Some(git_repo)))?; } Ok(()) } @@ -548,7 +548,7 @@ fn ask_to_create_new_origin_remote(repo_ref: &RepoRef, git_repo: &Repo) -> Resul )? { git_repo .git_repo - .remote("origin", &repo_ref.to_nostr_git_url())?; + .remote("origin", &repo_ref.to_nostr_git_url(&Some(git_repo)))?; } Ok(()) } diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index 8bf458b..bc56e1a 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -237,6 +237,16 @@ fn resolve_nip05_from_git_config_cache(nip05: &str, git_repo: &Option<&Repo>) -> } } +pub fn use_nip05_git_config_cache_to_find_nip05_from_public_key( + public_key: &PublicKey, + git_repo: &Option<&Repo>, +) -> Result> { + let h = load_nip_cache(git_repo)?; + Ok(h.iter() + .find_map(|(k, v)| if *v == *public_key { Some(k) } else { None }) + .cloned()) +} + fn save_nip05_to_git_config_cache( nip05: &str, public_key: &PublicKey, diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index 089befc..9a3c8f1 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs @@ -19,7 +19,10 @@ use crate::{ Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms, PromptInputParms, }, client::{consolidate_fetch_reports, get_repo_ref_from_cache, sign_event, Connect}, - git::{nostr_url::NostrUrlDecoded, Repo, RepoActions}, + git::{ + nostr_url::{use_nip05_git_config_cache_to_find_nip05_from_public_key, NostrUrlDecoded}, + Repo, RepoActions, + }, login::user::get_user_details, }; @@ -232,15 +235,20 @@ impl RepoRef { .collect::)>>() } - pub fn to_nostr_git_url(&self) -> String { + pub fn to_nostr_git_url(&self, git_repo: &Option<&Repo>) -> String { + let c = self.coordinate_with_hint(); format!( "{}", NostrUrlDecoded { original_string: String::new(), - coordinate: self.coordinate_with_hint(), + nip05: use_nip05_git_config_cache_to_find_nip05_from_public_key( + &c.public_key, + git_repo, + ) + .unwrap_or_default(), + coordinate: c, protocol: None, user: None, - nip05: None, // TODO: if nip05 for pubkey saved in local git config use it. } ) } @@ -446,10 +454,10 @@ fn set_or_create_git_remote_with_nostr_url( repo_ref: &RepoRef, git_repo: &Repo, ) -> Result<()> { - let url = repo_ref.to_nostr_git_url(); + let url = repo_ref.to_nostr_git_url(&Some(git_repo)); if git_repo .git_repo - .remote_set_url(name, &repo_ref.to_nostr_git_url()) + .remote_set_url(name, &repo_ref.to_nostr_git_url(&Some(git_repo))) .is_err() { git_repo.git_repo.remote(name, &url)?; -- cgit v1.2.3 From c72585a97736384ebe9e8e82a6311387808051fa Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 11 Dec 2024 08:04:41 +0000 Subject: fix(NostrUrlDecoded): add nip05 loading to TUI so the user understands the cause of any delay if the domain takes a while to respond --- src/lib/git/nostr_url.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index bc56e1a..39ce60e 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -191,11 +191,16 @@ impl NostrUrlDecoded { { public_key } else { - // TODO eprint loading message + let term = console::Term::stderr(); + let domain = { + let s = npub_or_nip05.split('@').collect::>(); + if s.len() == 2 { s[1] } else { s[0] } + }; + term.write_line(&format!("fetching pubic key info from {domain}..."))?; let res = nip05::profile(npub_or_nip05, None) .await .context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; - // TODO clear loading message + term.clear_last_lines(1)?; nip05 = Some(npub_or_nip05.to_string()); let _ = save_nip05_to_git_config_cache( npub_or_nip05, -- cgit v1.2.3 From 2c6e281c1643593cd079936924dc1d4e65c54ed6 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 11 Dec 2024 17:18:10 +0000 Subject: fix(NostrUrlDecoded): nip05 parsed as ssh user property `user`, which refers to the ssh user to be used when connecting to git remotes, was being parsed as the local section of the nip05 address --- src/lib/git/nostr_url.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/lib/git/nostr_url.rs') diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index 39ce60e..ca616a0 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs @@ -136,7 +136,9 @@ impl NostrUrlDecoded { // extract optional protocol if protocol.is_none() { let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; - let protocol_str = if let Some(at_index) = part.find('@') { + let protocol_str = if part.contains('.') { + part + } else if let Some(at_index) = part.find('@') { user = Some(part[..at_index].to_string()); &part[at_index + 1..] } else { @@ -147,7 +149,7 @@ impl NostrUrlDecoded { "https" => Some(ServerProtocol::Https), "http" => Some(ServerProtocol::Http), "git" => Some(ServerProtocol::Git), - _ => protocol, + _ => None, }; if protocol.is_some() { parts.remove(0); -- cgit v1.2.3