upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-07-31 16:47:31 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-07-31 16:47:31 +0100
commita7cabb96df30cd5d26f63affdb023b0706a387d1 (patch)
tree53c086492fd710f9f289c756ec511f8b3d3819f3 /src/lib
parentb1eabeb315dba8860f34c92e0e362559d3352ef7 (diff)
parent436ff29135e3deade80a6e53e53d74dddb613481 (diff)
Merge branch 'rust-nostr-v0.43'
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/client.rs43
-rw-r--r--src/lib/git/nostr_url.rs5
-rw-r--r--src/lib/git_events.rs38
-rw-r--r--src/lib/login/fresh.rs6
4 files changed, 74 insertions, 18 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 6f28cff..b27f9b1 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -32,17 +32,22 @@ use mockall::*;
32use nostr::{ 32use nostr::{
33 Event, 33 Event,
34 event::{TagKind, TagStandard, UnsignedEvent}, 34 event::{TagKind, TagStandard, UnsignedEvent},
35 filter::Alphabet, 35 filter::{Alphabet, MatchEventOptions},
36 nips::{nip01::Coordinate, nip19::Nip19Coordinate}, 36 nips::{
37 nip01::Coordinate,
38 nip05::{Nip05Address, Nip05Profile},
39 nip19::Nip19Coordinate,
40 },
37 signer::SignerBackend, 41 signer::SignerBackend,
38}; 42};
39use nostr_database::{NostrEventsDatabase, SaveEventStatus}; 43use nostr_database::{NostrDatabase, SaveEventStatus};
40use nostr_lmdb::NostrLMDB; 44use nostr_lmdb::NostrLMDB;
41use nostr_relay_pool::relay::ReqExitPolicy; 45use nostr_relay_pool::relay::ReqExitPolicy;
42use nostr_sdk::{ 46use nostr_sdk::{
43 EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, SingleLetterTag, 47 ClientOptions, EventBuilder, EventId, Kind, NostrSigner, PublicKey, RelayUrl, SingleLetterTag,
44 Timestamp, Url, prelude::RelayLimits, 48 Timestamp, Url, prelude::RelayLimits,
45}; 49};
50use serde_json::Value;
46 51
47use crate::{ 52use crate::{
48 get_dirs, 53 get_dirs,
@@ -144,12 +149,12 @@ impl Connect for Client {
144 Client { 149 Client {
145 client: if let Some(keys) = opts.keys { 150 client: if let Some(keys) = opts.keys {
146 nostr_sdk::ClientBuilder::new() 151 nostr_sdk::ClientBuilder::new()
147 .opts(Options::new().relay_limits(RelayLimits::disable())) 152 .opts(ClientOptions::new().relay_limits(RelayLimits::disable()))
148 .signer(keys) 153 .signer(keys)
149 .build() 154 .build()
150 } else { 155 } else {
151 nostr_sdk::ClientBuilder::new() 156 nostr_sdk::ClientBuilder::new()
152 .opts(Options::new().relay_limits(RelayLimits::disable())) 157 .opts(ClientOptions::new().relay_limits(RelayLimits::disable()))
153 .build() 158 .build()
154 }, 159 },
155 relay_default_set: opts.relay_default_set, 160 relay_default_set: opts.relay_default_set,
@@ -605,7 +610,11 @@ impl Connect for Client {
605 .await? 610 .await?
606 .iter() 611 .iter()
607 // don't process events that don't match filters 612 // don't process events that don't match filters
608 .filter(|e| filters.iter().any(|f| f.match_event(e))) 613 .filter(|e| {
614 filters
615 .iter()
616 .any(|f| f.match_event(e, MatchEventOptions::default()))
617 })
609 .cloned() 618 .cloned()
610 .collect(); 619 .collect();
611 // TODO: try reconcile 620 // TODO: try reconcile
@@ -880,6 +889,26 @@ pub async fn fetch_public_key(signer: &Arc<dyn NostrSigner>) -> Result<nostr::Pu
880 } 889 }
881} 890}
882 891
892pub async fn nip05_query(nip05_addr: &str) -> Result<Nip05Profile> {
893 let addr_deconstructed = Nip05Address::parse(nip05_addr)
894 .context(format!("cannot parse nip05 address: {nip05_addr}"))?;
895 let json_res: Value = reqwest::Client::new()
896 .get(addr_deconstructed.url().to_string())
897 .send()
898 .await
899 .context(format!(
900 "nip05 server is not responding for address: {nip05_addr}"
901 ))?
902 .json()
903 .await
904 .context(format!(
905 "nip05 server response did not respond with json when querying address: {nip05_addr}"
906 ))?;
907 Nip05Profile::from_json(&addr_deconstructed, &json_res).context(format!(
908 "cannot get public key for nip05 address: {nip05_addr}"
909 ))
910}
911
883fn pb_style() -> Result<ProgressStyle> { 912fn pb_style() -> Result<ProgressStyle> {
884 Ok( 913 Ok(
885 ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")?.with_key( 914 ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")?.with_key(
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs
index e9b482f..5e92a84 100644
--- a/src/lib/git/nostr_url.rs
+++ b/src/lib/git/nostr_url.rs
@@ -2,10 +2,11 @@ use core::fmt;
2use std::{collections::HashMap, str::FromStr}; 2use std::{collections::HashMap, str::FromStr};
3 3
4use anyhow::{Context, Error, Result, anyhow, bail}; 4use anyhow::{Context, Error, Result, anyhow, bail};
5use nostr::nips::{nip01::Coordinate, nip05, nip19::Nip19Coordinate}; 5use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate};
6use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; 6use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url};
7 7
8use super::{Repo, get_git_config_item, save_git_config_item}; 8use super::{Repo, get_git_config_item, save_git_config_item};
9use crate::client::nip05_query;
9 10
10#[derive(Debug, PartialEq, Default, Clone)] 11#[derive(Debug, PartialEq, Default, Clone)]
11pub enum ServerProtocol { 12pub enum ServerProtocol {
@@ -206,7 +207,7 @@ impl NostrUrlDecoded {
206 if s.len() == 2 { s[1] } else { s[0] } 207 if s.len() == 2 { s[1] } else { s[0] }
207 }; 208 };
208 term.write_line(&format!("fetching pubic key info from {domain}..."))?; 209 term.write_line(&format!("fetching pubic key info from {domain}..."))?;
209 let res = nip05::profile(npub_or_nip05, None).await.context(format!( 210 let res = nip05_query(npub_or_nip05).await.context(format!(
210 "failed to get nostr public key for {npub_or_nip05} from {domain}" 211 "failed to get nostr public key for {npub_or_nip05} from {domain}"
211 ))?; 212 ))?;
212 term.clear_last_lines(1)?; 213 term.clear_last_lines(1)?;
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index 2e1f215..79f5772 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -184,7 +184,7 @@ pub async fn generate_patch_event(
184 event_tag_from_nip19_or_hex( 184 event_tag_from_nip19_or_hex(
185 &event_ref, 185 &event_ref,
186 "proposal", 186 "proposal",
187 Marker::Reply, 187 EventRefType::Reply,
188 false, 188 false,
189 false, 189 false,
190 )?, 190 )?,
@@ -277,10 +277,17 @@ pub async fn generate_patch_event(
277 .context("failed to sign event") 277 .context("failed to sign event")
278} 278}
279 279
280#[derive(Debug, PartialEq)]
281pub enum EventRefType {
282 Root,
283 Reply,
284 Quote,
285}
286
280pub fn event_tag_from_nip19_or_hex( 287pub fn event_tag_from_nip19_or_hex(
281 reference: &str, 288 reference: &str,
282 reference_name: &str, 289 reference_name: &str,
283 marker: Marker, 290 ref_type: EventRefType,
284 allow_npub_reference: bool, 291 allow_npub_reference: bool,
285 prompt_for_correction: bool, 292 prompt_for_correction: bool,
286) -> Result<nostr::Tag> { 293) -> Result<nostr::Tag> {
@@ -291,22 +298,41 @@ pub fn event_tag_from_nip19_or_hex(
291 PromptInputParms::default().with_prompt(format!("{reference_name} reference")), 298 PromptInputParms::default().with_prompt(format!("{reference_name} reference")),
292 )?; 299 )?;
293 } 300 }
301 let marker = match ref_type {
302 EventRefType::Root => Some(Marker::Root),
303 EventRefType::Reply => Some(Marker::Reply),
304 EventRefType::Quote => None,
305 };
294 if let Ok(nip19) = Nip19::from_bech32(&bech32) { 306 if let Ok(nip19) = Nip19::from_bech32(&bech32) {
295 match nip19 { 307 match nip19 {
296 Nip19::Event(n) => { 308 Nip19::Event(n) => {
309 if ref_type == EventRefType::Quote {
310 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Quote {
311 event_id: n.event_id,
312 relay_url: n.relays.first().cloned(),
313 public_key: None,
314 }));
315 }
297 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { 316 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
298 event_id: n.event_id, 317 event_id: n.event_id,
299 relay_url: n.relays.first().cloned(), 318 relay_url: n.relays.first().cloned(),
300 marker: Some(marker), 319 marker,
301 public_key: None, 320 public_key: None,
302 uppercase: false, 321 uppercase: false,
303 })); 322 }));
304 } 323 }
305 Nip19::EventId(id) => { 324 Nip19::EventId(id) => {
325 if ref_type == EventRefType::Quote {
326 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Quote {
327 event_id: id,
328 relay_url: None,
329 public_key: None,
330 }));
331 }
306 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { 332 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
307 event_id: id, 333 event_id: id,
308 relay_url: None, 334 relay_url: None,
309 marker: Some(marker), 335 marker,
310 public_key: None, 336 public_key: None,
311 uppercase: false, 337 uppercase: false,
312 })); 338 }));
@@ -335,7 +361,7 @@ pub fn event_tag_from_nip19_or_hex(
335 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { 361 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
336 event_id: id, 362 event_id: id,
337 relay_url: None, 363 relay_url: None,
338 marker: Some(marker), 364 marker,
339 public_key: None, 365 public_key: None,
340 uppercase: false, 366 uppercase: false,
341 })); 367 }));
@@ -574,7 +600,7 @@ pub async fn generate_cover_letter_and_patch_events(
574 Tag::hashtag("root"), 600 Tag::hashtag("root"),
575 Tag::hashtag("revision-root"), 601 Tag::hashtag("revision-root"),
576 // TODO check if id is for a root proposal (perhaps its for an issue?) 602 // TODO check if id is for a root proposal (perhaps its for an issue?)
577 event_tag_from_nip19_or_hex(&event_ref,"proposal",Marker::Reply, false, false)?, 603 event_tag_from_nip19_or_hex(&event_ref,"proposal",EventRefType::Reply, false, false)?,
578 ] 604 ]
579 } else { 605 } else {
580 vec![ 606 vec![
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs
index 358045a..a9cf845 100644
--- a/src/lib/login/fresh.rs
+++ b/src/lib/login/fresh.rs
@@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc, time::Duration};
3use anyhow::{Context, Result, bail}; 3use anyhow::{Context, Result, bail};
4use console::Style; 4use console::Style;
5use dialoguer::theme::{ColorfulTheme, Theme}; 5use dialoguer::theme::{ColorfulTheme, Theme};
6use nostr::nips::{nip05, nip46::NostrConnectURI}; 6use nostr::nips::nip46::NostrConnectURI;
7use nostr_connect::client::NostrConnect; 7use nostr_connect::client::NostrConnect;
8use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, RelayUrl, ToBech32}; 8use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, RelayUrl, ToBech32};
9use qrcode::QrCode; 9use qrcode::QrCode;
@@ -25,7 +25,7 @@ use crate::{
25 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms, 25 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms,
26 PromptInputParms, PromptPasswordParms, 26 PromptInputParms, PromptPasswordParms,
27 }, 27 },
28 client::{Connect, send_events}, 28 client::{Connect, nip05_query, send_events},
29 git::{Repo, RepoActions, remove_git_config_item, save_git_config_item}, 29 git::{Repo, RepoActions, remove_git_config_item, save_git_config_item},
30}; 30};
31 31
@@ -384,7 +384,7 @@ pub fn generate_nostr_connect_app(
384pub async fn fetch_nip46_uri_from_nip05(nip05: &str) -> Result<NostrConnectURI> { 384pub async fn fetch_nip46_uri_from_nip05(nip05: &str) -> Result<NostrConnectURI> {
385 let term = console::Term::stderr(); 385 let term = console::Term::stderr();
386 term.write_line("contacting login service provider...")?; 386 term.write_line("contacting login service provider...")?;
387 let res = nip05::profile(&nip05, None).await; 387 let res = nip05_query(nip05).await;
388 term.clear_last_lines(1)?; 388 term.clear_last_lines(1)?;
389 match res { 389 match res {
390 Ok(profile) => { 390 Ok(profile) => {