diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/client.rs | 43 | ||||
| -rw-r--r-- | src/lib/git/nostr_url.rs | 5 | ||||
| -rw-r--r-- | src/lib/git_events.rs | 38 | ||||
| -rw-r--r-- | src/lib/login/fresh.rs | 6 |
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::*; | |||
| 32 | use nostr::{ | 32 | use 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 | }; |
| 39 | use nostr_database::{NostrEventsDatabase, SaveEventStatus}; | 43 | use nostr_database::{NostrDatabase, SaveEventStatus}; |
| 40 | use nostr_lmdb::NostrLMDB; | 44 | use nostr_lmdb::NostrLMDB; |
| 41 | use nostr_relay_pool::relay::ReqExitPolicy; | 45 | use nostr_relay_pool::relay::ReqExitPolicy; |
| 42 | use nostr_sdk::{ | 46 | use 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 | }; |
| 50 | use serde_json::Value; | ||
| 46 | 51 | ||
| 47 | use crate::{ | 52 | use 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 | ||
| 892 | pub 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 | |||
| 883 | fn pb_style() -> Result<ProgressStyle> { | 912 | fn 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; | |||
| 2 | use std::{collections::HashMap, str::FromStr}; | 2 | use std::{collections::HashMap, str::FromStr}; |
| 3 | 3 | ||
| 4 | use anyhow::{Context, Error, Result, anyhow, bail}; | 4 | use anyhow::{Context, Error, Result, anyhow, bail}; |
| 5 | use nostr::nips::{nip01::Coordinate, nip05, nip19::Nip19Coordinate}; | 5 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; |
| 6 | use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; | 6 | use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; |
| 7 | 7 | ||
| 8 | use super::{Repo, get_git_config_item, save_git_config_item}; | 8 | use super::{Repo, get_git_config_item, save_git_config_item}; |
| 9 | use crate::client::nip05_query; | ||
| 9 | 10 | ||
| 10 | #[derive(Debug, PartialEq, Default, Clone)] | 11 | #[derive(Debug, PartialEq, Default, Clone)] |
| 11 | pub enum ServerProtocol { | 12 | pub 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)] | ||
| 281 | pub enum EventRefType { | ||
| 282 | Root, | ||
| 283 | Reply, | ||
| 284 | Quote, | ||
| 285 | } | ||
| 286 | |||
| 280 | pub fn event_tag_from_nip19_or_hex( | 287 | pub 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}; | |||
| 3 | use anyhow::{Context, Result, bail}; | 3 | use anyhow::{Context, Result, bail}; |
| 4 | use console::Style; | 4 | 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::nip46::NostrConnectURI; |
| 7 | use nostr_connect::client::NostrConnect; | 7 | use nostr_connect::client::NostrConnect; |
| 8 | use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, RelayUrl, ToBech32}; | 8 | use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, RelayUrl, ToBech32}; |
| 9 | use qrcode::QrCode; | 9 | use 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( | |||
| 384 | pub async fn fetch_nip46_uri_from_nip05(nip05: &str) -> Result<NostrConnectURI> { | 384 | pub 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) => { |