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>2024-11-22 11:19:28 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-11-22 11:19:28 +0000
commit89b16f0ff5cf4774043caa23b83add21c91df14f (patch)
tree8cfd08ace4506695f183b42f7c958c43dfa146b6 /src/lib
parentb5b28fe742423933b1fee5a5f94f276f7cbd0abf (diff)
feat(login): add create account
for the simpliest UX it creates and publishes a profile and relay list event.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/login/fresh.rs94
1 files changed, 88 insertions, 6 deletions
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs
index b0fbe3f..524f419 100644
--- a/src/lib/login/fresh.rs
+++ b/src/lib/login/fresh.rs
@@ -5,7 +5,7 @@ use console::Style;
5use dialoguer::theme::{ColorfulTheme, Theme}; 5use dialoguer::theme::{ColorfulTheme, Theme};
6use nostr::nips::{nip05, nip46::NostrConnectURI}; 6use nostr::nips::{nip05, nip46::NostrConnectURI};
7use nostr_connect::client::NostrConnect; 7use nostr_connect::client::NostrConnect;
8use nostr_sdk::{Keys, NostrSigner, PublicKey, ToBech32, Url}; 8use nostr_sdk::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, ToBech32, Url};
9use qrcode::QrCode; 9use qrcode::QrCode;
10use tokio::{signal, sync::Mutex}; 10use tokio::{signal, sync::Mutex};
11 11
@@ -24,7 +24,7 @@ use crate::{
24 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms, 24 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms,
25 PromptInputParms, PromptPasswordParms, 25 PromptInputParms, PromptPasswordParms,
26 }, 26 },
27 client::Connect, 27 client::{send_events, Connect},
28 git::{remove_git_config_item, save_git_config_item, Repo, RepoActions}, 28 git::{remove_git_config_item, save_git_config_item, Repo, RepoActions},
29}; 29};
30 30
@@ -63,10 +63,14 @@ pub async fn fresh_login_or_signup(
63 continue; 63 continue;
64 } 64 }
65 }, 65 },
66 2 => { 66 2 => match signup(client).await {
67 eprintln!("TODO create account..."); 67 Ok(Some(res)) => break res,
68 continue; 68 Ok(None) => continue,
69 } 69 Err(e) => {
70 eprintln!("error getting fresh signer from signup: {e}");
71 continue;
72 }
73 },
70 _ => { 74 _ => {
71 display_login_help_content().await; 75 display_login_help_content().await;
72 continue; 76 continue;
@@ -566,6 +570,84 @@ fn silently_save_to_git_config(
566 Ok(()) 570 Ok(())
567} 571}
568 572
573async fn signup(
574 #[cfg(test)] client: Option<&MockConnect>,
575 #[cfg(not(test))] client: Option<&Client>,
576) -> Result<
577 Option<(
578 Arc<dyn NostrSigner>,
579 PublicKey,
580 SignerInfo,
581 SignerInfoSource,
582 )>,
583> {
584 eprintln!("create account");
585 loop {
586 let name = Interactor::default()
587 .input(
588 PromptInputParms::default()
589 .with_prompt("user display name")
590 .optional()
591 .dont_report(),
592 )
593 .context("failed to get display name input from interactor")?;
594 if name.is_empty() {
595 show_prompt_error("emtpy display name", "");
596 match Interactor::default().choice(
597 PromptChoiceParms::default()
598 .with_default(0)
599 .with_choices(vec![
600 "enter non-empty display name".to_string(),
601 "back to login menu".to_string(),
602 ])
603 .dont_report(),
604 )? {
605 0 => continue,
606 _ => break Ok(None),
607 }
608 }
609 let keys = nostr::Keys::generate();
610 let nsec = keys.secret_key().to_bech32()?;
611 show_prompt_success("user display name", &name);
612 let signer_info = SignerInfo::Nsec {
613 nsec,
614 password: None,
615 npub: Some(keys.public_key().to_bech32()?),
616 };
617 let public_key = keys.public_key();
618 if let Some(client) = client {
619 let profile =
620 EventBuilder::metadata(&Metadata::new().name(name)).sign_with_keys(&keys)?;
621 let relay_list = EventBuilder::relay_list(
622 client
623 .get_fallback_relays()
624 .iter()
625 .map(|s| (Url::parse(s).unwrap(), None)),
626 )
627 .sign_with_keys(&keys)?;
628 eprintln!("publishing user profile to relays");
629 send_events(
630 client,
631 None,
632 vec![profile, relay_list],
633 client.get_fallback_relays().clone(),
634 vec![],
635 true,
636 false,
637 )
638 .await?;
639 }
640 eprintln!("TODO: advice about using in other clients");
641 break Ok(Some((
642 Arc::new(keys),
643 public_key,
644 signer_info,
645 // TODO factor in source
646 SignerInfoSource::GitGlobal,
647 )));
648 }
649}
650
569async fn display_login_help_content() { 651async fn display_login_help_content() {
570 let mut printer = Printer::default(); 652 let mut printer = Printer::default();
571 let title_style = Style::new().bold().fg(console::Color::Yellow); 653 let title_style = Style::new().bold().fg(console::Color::Yellow);