From db13ee769d674d9fd8b30e79dca974ff93c018c4 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Fri, 5 Jul 2024 15:21:03 +0100 Subject: Generate nostrconnect URI by default Instead of asking for the user to generate a nsecbunker in another NIP46 signer app and copy pasting here. The former behavior can still be achieved by passing --use-nsecbunker. --- README.md | 13 +++++++++---- src/main.rs | 50 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index aa4d1e3..bd10c92 100644 --- a/README.md +++ b/README.md @@ -50,15 +50,20 @@ Arguments: Options: -i, --interval watch interval in seconds [default: 60] --reset-nip46 remove previously cached NIP46 signer credentials and ask for new ones + --use-nsecbunker use an externally provided nsecbunker URI instead of generating a nostrconnectURI by default -h, --help Print help -V, --version Print version ``` -You can just run it without any arguments. It will ask for a [NIP46 nsecbunker -URI](https://github.com/nostr-protocol/nips/blob/master/46.md) which you can -easily obtain if using [Amber](https://github.com/greenart7c3/Amber), +You can just run it without any arguments. It will provide you with a in-client +auto generated +[NIP46 nostrconnect URI](https://github.com/nostr-protocol/nips/blob/master/46.md) +which you can use to login remotely using [Amber](https://github.com/greenart7c3/Amber), [Keystache](https://github.com/Resolvr-io/Keystache), -[nsec.app](https://nsec.app/) or [nsecbunker.com](https://nsecbunker.com/). +[nsec.app](https://nsec.app/) or [nsecbunker.com](https://nsecbunker.com/). If +the app does not have good support for generated `nostrconnect://` URIs, you can +pass `--use-nsecbunker` and paste a nsecbunker URI instead of scanning a QR +code. You just need to copy paste the URI on the first run, and it will then use your [NIP65 outbox relays](https://github.com/nostr-protocol/nips/blob/master/65.md) diff --git a/src/main.rs b/src/main.rs index 24ed7de..dcd28e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ use nostr_sdk::{ nip53::LiveEventStatus, nip65::{self, RelayMetadata}, }, - Client, Event, EventBuilder, Filter, Keys, Kind, Tag, TagKind, TagStandard, ToBech32, + Client, Event, EventBuilder, Filter, Keys, Kind, Tag, TagKind, TagStandard, ToBech32, Url, }; use nostr_signer::{Nip46Signer, NostrSigner}; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -57,6 +57,10 @@ struct Args { /// remove previously cached NIP46 signer credentials and ask for new ones #[arg(long)] reset_nip46: bool, + /// use an externally provided nsecbunker URI instead of generating a nostrconnectURI by + /// default + #[arg(long)] + use_nsecbunker: bool, /// specific naddrs of Live Events to update, if none, all user authored Live Events that are /// 'live' will be updated naddrs: Vec, @@ -69,12 +73,30 @@ struct ClientData { } impl ClientData { - async fn generate() -> Result { + async fn generate(use_nsecbunker: bool) -> Result { let keys = Keys::generate(); - println!("Paste NSECBUNKER URI (this only needs to be done once):"); - let mut line = String::new(); - stdin().read_line(&mut line)?; - let nip46_uri = line.trim_end().to_string(); + + let nip46_uri = match use_nsecbunker { + true => { + println!("Paste NSECBUNKER URI (this only needs to be done once):"); + let mut line = String::new(); + stdin().read_line(&mut line)?; + line.trim_end().to_string() + } + + false => { + let uri = NostrConnectURI::client( + keys.public_key(), + [Url::parse("wss://relay.nsec.app")?], + env!("CARGO_PKG_NAME"), + ) + .to_string(); + println!( + "Use your NIP46 signer app (e.g. Amber) to connect by using this URI:\n{uri}" + ); + uri + } + }; Ok(ClientData { client_nsec: keys.secret_key()?.to_bech32()?, @@ -99,6 +121,7 @@ async fn do_main() -> Result<()> { let client = setup_nostr_client( args.reset_nip46, + args.use_nsecbunker, Duration::from_secs(NIP46_TIMEOUT_SEC), ZAP_STREAM_RELAYS, ) @@ -151,10 +174,11 @@ fn set_signal_handlers() -> Result<()> { async fn setup_nostr_client( reset_nip46: bool, + use_nsecbunker: bool, nip46_timeout: Duration, client_relays: &[&str], ) -> Result { - let signer = create_signer(reset_nip46, nip46_timeout).await?; + let signer = create_signer(reset_nip46, use_nsecbunker, nip46_timeout).await?; let signer_pubkey = signer.signer_public_key(); let client = Client::new(NostrSigner::from(signer)); @@ -165,7 +189,11 @@ async fn setup_nostr_client( Ok(client) } -async fn create_signer(reset_nip46: bool, nip46_timeout: Duration) -> Result { +async fn create_signer( + reset_nip46: bool, + use_nsecbunker: bool, + nip46_timeout: Duration, +) -> Result { if reset_nip46 { let path = get_client_data_path(); let path_str = path @@ -173,7 +201,7 @@ async fn create_signer(reset_nip46: bool, nip46_timeout: Duration) -> Result Result Result { +async fn get_or_generate_client_data(use_nsecbunker: bool) -> Result { let path = get_client_data_path(); match File::open(&path) { Ok(file) => { @@ -195,7 +223,7 @@ async fn get_or_generate_client_data() -> Result { .with_context(|| format!("cannot read client data from '{}'", path.display())) } Err(_) => { - let nostr_data = ClientData::generate().await?; + let nostr_data = ClientData::generate(use_nsecbunker).await?; let mut file = File::create(&path)?; file.write_all(to_string(&nostr_data)?.as_bytes()) .with_context(|| format!("could not write client data to '{}'", path.display()))?; -- cgit v1.2.3-70-g09d2