Avatar
Lez
cfd7df62799a22e384a4ab5da8c4026c875b119d0f47c2716b20cdac9cc1f1a6
Inventor of nsite, building tribewiki.org. Biohacker.

What's the name of a caching relay that runs in the browser? #asknostr

Replying to Avatar DanConwayDev

From b4d81f54ad6e5cbf212593527727e7f7cb036aef Mon Sep 17 00:00:00 2001

From: DanConwayDev

Date: Mon, 9 Dec 2024 09:34:08 +0000

Subject: [PATCH] add nostr_url nip05 whilst retaining structure

Following the discussion:

nostr:nevent1qvzqqqqqqypzpn7hma38nx3zuwz2f26a4rzqymy8tvge6r68cfckkgxd4jwvrudxqyt8wumn8ghj7ur4wfcxcetjv4kxz7fwvdhk6tcppemhxue69uhkummn9ekx7mp0qythwumn8ghj7un9d3shjtnwdaehgu3wvfskuep0qyt8wumn8ghj7ur4wfcxcetjv4kxz7fwvdhk6tcppemhxue69uhkummn9ekx7mp0qythwumn8ghj7un9d3shjtnwdaehgu3wvfskuep0qqsf26xu3q0x4mzfz2nu76pcj42qthh30hwwrclzdhj3n60qvwe54dcrghvk2

I've pulled this together to demonstrate how this feature could be

added to `NostrUrlDecoded` without dramatically changing its

structure or adding a similar struct which omits the `PublicKey`.

it replaces `NostrUrlDecoded::from_str` with

`NostrUrlDecoded::parse_and_resolve`.

In this WIP I have began to add nip05 to repo_ref so that

`RepoRef::to_nostr_git_url` can render the nip05 when originally

used. Unfortunately, there is more work to as the type of

`trusted_maintainer` needs to change to `NostrUrlDecoded`.

There may still be instances where the variable name

`repo_coordinate` is used to create repo_refs when it is exclusively

refering to trusted maintainers and not other repo maintainers.

these should use the type `NostrUrlDecoded` too, to ensure

`RepoRef::to_nostr_git_url` always includes nip05 when originally

taken from the nostr_url.

---

src/bin/git_remote_nostr/main.rs | 12 ++++++------

src/bin/ngit/sub_commands/init.rs | 11 +++++++----

src/lib/git/nostr_url.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------

src/lib/repo_ref.rs | 19 +++++++++++++++----

4 files changed, 100 insertions(+), 23 deletions(-)

diff --git a/src/bin/git_remote_nostr/main.rs b/src/bin/git_remote_nostr/main.rs

index 8e12d68..84327d7 100644

--- a/src/bin/git_remote_nostr/main.rs

+++ b/src/bin/git_remote_nostr/main.rs

@@ -9,7 +9,6 @@ use std::{

collections::HashSet,

env, io,

path::{Path, PathBuf},

- str::FromStr,

};

use anyhow::{bail, Context, Result};

@@ -28,7 +27,7 @@ mod utils;

#[tokio::main]

async fn main() -> Result<()> {

- let Some((decoded_nostr_url, git_repo)) = process_args()? else {

+ let Some((decoded_nostr_url, git_repo)) = process_args().await? else {

return Ok(());

};

@@ -109,7 +108,7 @@ async fn main() -> Result<()> {

}

}

-fn process_args() -> Result> {

+async fn process_args() -> Result> {

let args = env::args();

let args = args.skip(1).take(2).collect::>();

@@ -135,13 +134,14 @@ fn process_args() -> Result> {

return Ok(None);

};

- let decoded_nostr_url =

- NostrUrlDecoded::from_str(nostr_remote_url).context("invalid nostr url")?;

-

let git_repo = Repo::from_path(&PathBuf::from(

std::env::var("GIT_DIR").context("git should set GIT_DIR when remote helper is called")?,

))?;

+ let decoded_nostr_url = NostrUrlDecoded::parse_and_resolve(nostr_remote_url, &Some(&git_repo))

+ .await

+ .context("invalid nostr url")?;

+

Ok(Some((decoded_nostr_url, git_repo)))

}

diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs

index 6fc1ec4..dbad9b6 100644

--- a/src/bin/ngit/sub_commands/init.rs

+++ b/src/bin/ngit/sub_commands/init.rs

@@ -1,4 +1,4 @@

-use std::{collections::HashMap, str::FromStr};

+use std::collections::HashMap;

use anyhow::{Context, Result};

use console::Style;

@@ -408,6 +408,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {

trusted_maintainer: user_ref.public_key,

maintainers: maintainers.clone(),

events: HashMap::new(),

+ nip05: None,

};

let repo_event = repo_ref.to_event(&signer).await?;

@@ -442,7 +443,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {

.map(std::string::ToString::to_string)

.collect::>();

- prompt_to_set_nostr_url_as_origin(&repo_ref, &git_repo)?;

+ prompt_to_set_nostr_url_as_origin(&repo_ref, &git_repo).await?;

// TODO: if no state event exists and there is currently a remote called

// "origin", automtically push rather than waiting for the next commit

@@ -483,7 +484,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {

Ok(())

}

-fn prompt_to_set_nostr_url_as_origin(repo_ref: &RepoRef, git_repo: &Repo) -> Result<()> {

+async fn prompt_to_set_nostr_url_as_origin(repo_ref: &RepoRef, git_repo: &Repo) -> Result<()> {

println!(

"starting from your next commit, when you `git push` to a remote that uses your nostr url, it will store your repository state on nostr and update the state of the git server(s) you just listed."

);

@@ -493,7 +494,9 @@ fn prompt_to_set_nostr_url_as_origin(repo_ref: &RepoRef, git_repo: &Repo) -> Res

if let Ok(origin_remote) = git_repo.git_repo.find_remote("origin") {

if let Some(origin_url) = origin_remote.url() {

- if let Ok(nostr_url) = NostrUrlDecoded::from_str(origin_url) {

+ if let Ok(nostr_url) =

+ NostrUrlDecoded::parse_and_resolve(origin_url, &Some(git_repo)).await

+ {

if nostr_url.coordinate.identifier == repo_ref.identifier {

if nostr_url.coordinate.public_key == repo_ref.trusted_maintainer {

return Ok(());

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,

diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs

index 1b25ccf..bf23d30 100644

--- a/src/lib/repo_ref.rs

+++ b/src/lib/repo_ref.rs

@@ -35,12 +35,14 @@ pub struct RepoRef {

pub maintainers: Vec,

pub trusted_maintainer: PublicKey,

pub events: HashMap,

+ pub nip05: Option,

}

impl TryFrom<(nostr::Event, Option)> for RepoRef {

type Error = anyhow::Error;

fn try_from((event, trusted_maintainer): (nostr::Event, Option)) -> Result {

+ // TODO: turn trusted maintainer into NostrUrlDecoded

if !event.kind.eq(&Kind::GitRepoAnnouncement) {

bail!("incorrect kind");

}

@@ -56,6 +58,7 @@ impl TryFrom<(nostr::Event, Option)> for RepoRef {

maintainers: Vec::new(),

trusted_maintainer: trusted_maintainer.unwrap_or(event.pubkey),

events: HashMap::new(),

+ nip05: None,

};

for tag in event.tags.iter() {

@@ -239,6 +242,7 @@ impl RepoRef {

coordinate: self.coordinate_with_hint(),

protocol: None,

user: None,

+ nip05: self.nip05.clone(),

}

)

}

@@ -259,7 +263,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 {

- let remote_coordinates = get_repo_coordinates_from_nostr_remotes(git_repo)?;

+ 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) {

Ok(c)

@@ -327,11 +331,15 @@ fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result {

.context("git config item \"nostr.repo\" is not an naddr")

}

-fn get_repo_coordinates_from_nostr_remotes(git_repo: &Repo) -> Result> {

+async fn get_repo_coordinates_from_nostr_remotes(

+ git_repo: &Repo,

+) -> 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() {

- if let Ok(nostr_url_decoded) = NostrUrlDecoded::from_str(remote_url) {

+ if let Ok(nostr_url_decoded) =

+ NostrUrlDecoded::parse_and_resolve(remote_url, &Some(git_repo)).await

+ {

repo_coordinates.insert(remote_name.to_string(), nostr_url_decoded.coordinate);

}

}

@@ -383,7 +391,9 @@ async fn get_repo_coordinate_from_user_prompt(

.input(PromptInputParms::default().with_prompt("nostr repository"))?;

let coordinate = if let Ok(c) = Coordinate::parse(&input) {

c

- } else if let Ok(nostr_url) = NostrUrlDecoded::from_str(&input) {

+ } else if let Ok(nostr_url) =

+ NostrUrlDecoded::parse_and_resolve(&input, &Some(git_repo)).await

+ {

nostr_url.coordinate

} else {

eprintln!("not a valid naddr or git nostr remote URL starting nostr://");

@@ -540,6 +550,7 @@ mod tests {

trusted_maintainer: TEST_KEY_1_KEYS.public_key(),

maintainers: vec![TEST_KEY_1_KEYS.public_key(), TEST_KEY_2_KEYS.public_key()],

events: HashMap::new(),

+ nip05: None,

}

.to_event(&TEST_KEY_1_SIGNER)

.await

--

libgit2 1.8.1

Great, just what I wanted :)

I was too coward to remove from_str trait.

And cloning nip05 repo already works!

Technical feedback: from nostrudel if I press "open on gitworkshop.dev", it tries to open nevent1qvzqqqqx2ypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqqs9cv8pajach39wg4dfxj3wz2w50e2mpfqwlykh4cmffec5hfxknngf2ef2k there, which shows an error.

If I go through https://nostrapp.link/#nevent1qvzqqqqx2ypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqqs9cv8pajach39wg4dfxj3wz2w50e2mpfqwlykh4cmffec5hfxknngf2ef2k?select=true it will open https://gitworkshop.dev/e/nevent1qqs9cv8pajach39wg4dfxj3wz2w50e2mpfqwlykh4cmffec5hfxknngzyzsq3hh327t0h2dq6matqn5064cgj2zanl2stkj6s0lg4t2h5dty67t3mez - which works.

I'll check the patch now. :)

2. I'm fine by doing an MVP, let's not touch the 30317 for now. I think increasing UX is more important here. Especially that by the authorities taking the DNS they achieve nothing a.) it's a news flash for the project b.) somebody trusted will point a new nip05 to the project c.) educating the public it's a dependency d.) still being able to use the npub/naddr remote, which ngit could support out of the box (as all the info is cached in a checked out repo)

2. I called "repo relays" the "relays" tag value in the 30317 event, and "relay hint" the relay in the nostr remote URL, like: nostr://nip05/relay.hint/identifier

How will gitworkshop.dev find out which URL to show in the green "clone" dropdown? (nostr://nip05/relay.hint/identifier, or nostr://nip05/identifier? - or one of the npub / nevent / naddr variant?)

3. Fine, but then we need to add an "identifier: Option" member, too. Because we can't store it anywhere else until we haven't resolved the nip05 to a pubkey.

Just a reminder, many people on Nostr believe that solving the decentralized naming problem perfectly is impossible - so we should not even try to come up with an almost perfect.

I think we need names, we need to break free of IANA, even if it's imperfect and SOME trust is involved. Handshake.org did it, although there is a shitcoin involved in it. There must be other ways.

Replying to Avatar Lez

From 3fc1a99b85fb20f78b1ea28e5daa75eef4688da5 Mon Sep 17 00:00:00 2001

From: Laszlo Megyer

Date: Mon, 2 Dec 2024 13:20:13 +0100

Subject: [PATCH 1/3] Parse NIP-05 address from a git remote URL

The nip05 address is stored as it is, because we can't run async code in

from_str().

We need to add an async resolve_nip05() to NostrUrlDecoded.

---

src/lib/git/nostr_url.rs | 27 +++++++++++++++++++--------

src/lib/repo_ref.rs | 1 +

2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs

index a501765..be4a825 100644

--- a/src/lib/git/nostr_url.rs

+++ b/src/lib/git/nostr_url.rs

@@ -59,6 +59,7 @@ pub struct NostrUrlDecoded {

pub coordinates: HashSet,

pub protocol: Option,

pub user: Option,

+ pub nip05: Option,

}

impl fmt::Display for NostrUrlDecoded {

@@ -98,6 +99,7 @@ impl std::str::FromStr for NostrUrlDecoded {

let mut protocol = None;

let mut user = None;

let mut relays = vec![];

+ let mut nip05 = None;

if !url.starts_with("nostr://") {

bail!("nostr git url must start with nostr://");

@@ -134,16 +136,24 @@ impl std::str::FromStr for NostrUrlDecoded {

.split('/')

.collect();

+ // split first part into user if present and hostname

+ let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?;

+ let hostname = if let Some(at_index) = part.find('@') {

+ // TODO throw error if user already set

+ user = Some(part[..at_index].to_string());

+ &part[at_index + 1..]

+ } else {

+ part

+ };

+

+ // check if it uses a NIP-05 address

+ if hostname.contains('.') {

+ nip05 = Some(part.to_string())

+ }

+

// 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('@') {

- user = Some(part[..at_index].to_string());

- &part[at_index + 1..]

- } else {

- part

- };

- protocol = match protocol_str {

+ protocol = match hostname {

"ssh" => Some(ServerProtocol::Ssh),

"https" => Some(ServerProtocol::Https),

"http" => Some(ServerProtocol::Http),

@@ -196,6 +206,7 @@ impl std::str::FromStr for NostrUrlDecoded {

coordinates,

protocol,

user,

+ nip05,

})

}

}

diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs

index 69fbe64..877d1ee 100644

--- a/src/lib/repo_ref.rs

+++ b/src/lib/repo_ref.rs

@@ -229,6 +229,7 @@ impl RepoRef {

coordinates: HashSet::from_iter(vec![self.coordinate_with_hint()]),

protocol: None,

user: None,

+ nip05: None,

}

)

}

--

libgit2 1.8.1

Caching the pubkey for the nip05 makes sense. Config is a good place for it.

A couple of questions:

- RepoRef is used to directly map the 30617 event into a rust object?

- Should we add the nostr remote URL into the gitrepo event? It would reflect the choice of the repo owner how he wants to use it. For example, if my nip05 relays intersect with the repo relays, I will omit the relay hint. If they are distinct, I'll include. But it would be easier to just store the URL and use later, than to do the intersection repeatedly. And it's a problem for not cors-enabled nip05s on the web.

- Do you think it would make sense to further refactor the `coordinate` member of `NostrUrlDecoded`? If we could include the Coordinate members (identifier, pubkey, kind, relays) direct members of the `NostrUrlDecoded`, we could change pubkey to Option, and NostrUrlDecoded could hold the URL value after parsing but before looking up NIP05. Also, the duplication of the `identifier` wouldn't be needed. I duplicated that previously because I couln't instantiate Coordinate from a NIP05 nostr:// remote URL.

I'd love to see the on/off config stored in the nip07 extension, per pubkey. Definitely not the one popup per page model.

Trust, but verify!

Congratulations, Trump!

You are a truly great student of Orbán, the prime minister of Hungary.

Now it's your turn to make the freedom lover Americans believe you are on their side.

You just have to put the endless freedom-fight on the scene.

If your rhetorics is on spot, nobody cares what you do in the background. They will re-elect you 2 more times.

While the population is distracted, you can make draconian money exchange laws,

you can bring in the socialism that nobody ever wanted,

you can mandate corporations to do proper and regular KYC,

and perfect the divide and conquer game into a civil war.

After all, there is no other way to conquer an armed population.

It's critical to catch it early. Now is the time when you can make it shorter and milder. What I usually do these times is taking Vitamin D and Vitamin A. It helps a lot. If you have the clean form (oily drops), take 50000 of each now, in the evening, and tomorrow morning, 3 times in sum. And take loads (50mg) of zinc, too. Make the room warm. Get better soon!

Replying to 79be667e...

From 3fc1a99b85fb20f78b1ea28e5daa75eef4688da5 Mon Sep 17 00:00:00 2001

From: Laszlo Megyer

Date: Mon, 2 Dec 2024 13:20:13 +0100

Subject: [PATCH 1/2] Parse NIP-05 address from a git remote URL

The nip05 address is stored as it is, because we can't run async code in

from_str().

We need to add an async resolve_nip05() to NostrUrlDecoded.

---

src/lib/git/nostr_url.rs | 27 +++++++++++++++++++--------

src/lib/repo_ref.rs | 1 +

2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs

index a501765..be4a825 100644

--- a/src/lib/git/nostr_url.rs

+++ b/src/lib/git/nostr_url.rs

@@ -59,6 +59,7 @@ pub struct NostrUrlDecoded {

pub coordinates: HashSet,

pub protocol: Option,

pub user: Option,

+ pub nip05: Option,

}

impl fmt::Display for NostrUrlDecoded {

@@ -98,6 +99,7 @@ impl std::str::FromStr for NostrUrlDecoded {

let mut protocol = None;

let mut user = None;

let mut relays = vec![];

+ let mut nip05 = None;

if !url.starts_with("nostr://") {

bail!("nostr git url must start with nostr://");

@@ -134,16 +136,24 @@ impl std::str::FromStr for NostrUrlDecoded {

.split('/')

.collect();

+ // split first part into user if present and hostname

+ let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?;

+ let hostname = if let Some(at_index) = part.find('@') {

+ // TODO throw error if user already set

+ user = Some(part[..at_index].to_string());

+ &part[at_index + 1..]

+ } else {

+ part

+ };

+

+ // check if it uses a NIP-05 address

+ if hostname.contains('.') {

+ nip05 = Some(part.to_string())

+ }

+

// 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('@') {

- user = Some(part[..at_index].to_string());

- &part[at_index + 1..]

- } else {

- part

- };

- protocol = match protocol_str {

+ protocol = match hostname {

"ssh" => Some(ServerProtocol::Ssh),

"https" => Some(ServerProtocol::Https),

"http" => Some(ServerProtocol::Http),

@@ -196,6 +206,7 @@ impl std::str::FromStr for NostrUrlDecoded {

coordinates,

protocol,

user,

+ nip05,

})

}

}

diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs

index 69fbe64..877d1ee 100644

--- a/src/lib/repo_ref.rs

+++ b/src/lib/repo_ref.rs

@@ -229,6 +229,7 @@ impl RepoRef {

coordinates: HashSet::from_iter(vec![self.coordinate_with_hint()]),

protocol: None,

user: None,

+ nip05: None,

}

)

}

--

libgit2 1.8.1

Actually, Chris is a guy with a very weak sec ("1").

Végülis igen. Használni, feature-öket requestelni, bugokat reportolni (ehhez még túl korai, van jópár). Azt hallottam, hogy a fejlesztőket motiválja, ha kapnak feedbacket.