notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 4bfa26fd8c7a6bd24c584532efd46030746120c4
parent c3bbc6b977d752c4dec036e69336d7edc7cc9aff
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 12 Dec 2024 10:55:44 -0500

Revert "move login logic from promise to async fns"

This reverts commit baaa7cc05d97dc0b5e18a79c2e2c2aba2a89c940.

Closes: https://github.com/damus-io/notedeck/pull/567

Diffstat:
Mcrates/notedeck_columns/src/key_parsing.rs | 139++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mcrates/notedeck_columns/src/login_manager.rs | 7+++----
2 files changed, 80 insertions(+), 66 deletions(-)

diff --git a/crates/notedeck_columns/src/key_parsing.rs b/crates/notedeck_columns/src/key_parsing.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use std::str::FromStr; use crate::Error; +use ehttp::{Request, Response}; use enostr::{Keypair, Pubkey, SecretKey}; use poll_promise::Promise; -use reqwest::{Request, Response}; use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq)] @@ -32,13 +32,9 @@ pub struct Nip05Result { pub relays: Option<HashMap<String, Vec<String>>>, } -async fn parse_nip05_response(response: Response) -> Result<Nip05Result, Error> { - match response.bytes().await { - Ok(bytes) => { - serde_json::from_slice::<Nip05Result>(&bytes).map_err(|e| Error::Generic(e.to_string())) - } - Err(e) => Err(Error::Generic(e.to_string())), - } +fn parse_nip05_response(response: Response) -> Result<Nip05Result, Error> { + serde_json::from_slice::<Nip05Result>(&response.bytes) + .map_err(|e| Error::Generic(e.to_string())) } fn get_pubkey_from_result(result: Nip05Result, user: String) -> Result<Pubkey, Error> { @@ -50,56 +46,70 @@ fn get_pubkey_from_result(result: Nip05Result, user: String) -> Result<Pubkey, E } } -async fn get_nip05_pubkey(id: &str) -> Result<Pubkey, Error> { +fn get_nip05_pubkey(id: &str) -> Promise<Result<Pubkey, Error>> { + let (sender, promise) = Promise::new(); let mut parts = id.split('@'); let user = match parts.next() { Some(user) => user, None => { - return Err(Error::Generic( + sender.send(Err(Error::Generic( "Address does not contain username.".to_string(), - )); + ))); + return promise; } }; let host = match parts.next() { Some(host) => host, None => { - return Err(Error::Generic( + sender.send(Err(Error::Generic( "Nip05 address does not contain host.".to_string(), - )); + ))); + return promise; } }; if parts.next().is_some() { - return Err(Error::Generic( + sender.send(Err(Error::Generic( "Nip05 address contains extraneous parts.".to_string(), - )); + ))); + return promise; } let url = format!("https://{host}/.well-known/nostr.json?name={user}"); - let request = Request::new(reqwest::Method::GET, url.parse().unwrap()); - let cloned_user = user.to_string(); + let request = Request::get(url); - let client = reqwest::Client::new(); - match client.execute(request).await { - Ok(resp) => match parse_nip05_response(resp).await { - Ok(result) => match get_pubkey_from_result(result, cloned_user) { - Ok(pubkey) => Ok(pubkey), - Err(e) => Err(Error::Generic(e.to_string())), - }, + let cloned_user = user.to_string(); + ehttp::fetch(request, move |response: Result<Response, String>| { + let result = match response { + Ok(resp) => parse_nip05_response(resp) + .and_then(move |result| get_pubkey_from_result(result, cloned_user)), Err(e) => Err(Error::Generic(e.to_string())), - }, - Err(e) => Err(Error::Generic(e.to_string())), - } + }; + sender.send(result); + }); + + promise } fn retrieving_nip05_pubkey(key: &str) -> bool { key.contains('@') } -pub fn perform_key_retrieval(key: &str) -> Promise<Result<Keypair, AcquireKeyError>> { - let key_string = String::from(key); - Promise::spawn_async(async move { get_key(&key_string).await }) +fn nip05_promise_wrapper(id: &str) -> Promise<Result<Keypair, AcquireKeyError>> { + let (sender, promise) = Promise::new(); + let original_promise = get_nip05_pubkey(id); + + std::thread::spawn(move || { + let result = original_promise.block_and_take(); + let transformed_result = match result { + Ok(public_key) => Ok(Keypair::only_pubkey(public_key)), + Err(e) => Err(AcquireKeyError::Nip05Failed(e.to_string())), + }; + sender.send(transformed_result); + }); + + promise } /// Attempts to turn a string slice key from the user into a Nostr-Sdk Keypair object. @@ -110,7 +120,7 @@ pub fn perform_key_retrieval(key: &str) -> Promise<Result<Keypair, AcquireKeyErr /// - Private hex key: "5dab..." /// - NIP-05 address: "example@nostr.com" /// -pub async fn get_key(key: &str) -> Result<Keypair, AcquireKeyError> { +pub fn perform_key_retrieval(key: &str) -> Promise<Result<Keypair, AcquireKeyError>> { let tmp_key: &str = if let Some(stripped) = key.strip_prefix('@') { stripped } else { @@ -118,18 +128,19 @@ pub async fn get_key(key: &str) -> Result<Keypair, AcquireKeyError> { }; if retrieving_nip05_pubkey(tmp_key) { - match get_nip05_pubkey(tmp_key).await { - Ok(pubkey) => Ok(Keypair::only_pubkey(pubkey)), - Err(e) => Err(AcquireKeyError::Nip05Failed(e.to_string())), - } - } else if let Ok(pubkey) = Pubkey::try_from_bech32_string(tmp_key, true) { - Ok(Keypair::only_pubkey(pubkey)) - } else if let Ok(pubkey) = Pubkey::try_from_hex_str_with_verify(tmp_key) { - Ok(Keypair::only_pubkey(pubkey)) - } else if let Ok(secret_key) = SecretKey::from_str(tmp_key) { - Ok(Keypair::from_secret(secret_key)) + nip05_promise_wrapper(tmp_key) } else { - Err(AcquireKeyError::InvalidKey) + let res = if let Ok(pubkey) = Pubkey::try_from_bech32_string(tmp_key, true) { + Ok(Keypair::only_pubkey(pubkey)) + } else if let Ok(pubkey) = Pubkey::try_from_hex_str_with_verify(tmp_key) { + Ok(Keypair::only_pubkey(pubkey)) + } else if let Ok(secret_key) = SecretKey::from_str(tmp_key) { + Ok(Keypair::from_secret(secret_key)) + } else { + Err(AcquireKeyError::InvalidKey) + }; + + Promise::from_ready(res) } } @@ -138,18 +149,8 @@ mod tests { use super::*; use crate::promise_assert; - #[tokio::test] - async fn test_pubkey_async() { - let pubkey_str = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"; - let expected_pubkey = - Pubkey::try_from_bech32_string(pubkey_str, false).expect("Should not have errored."); - let login_key_result = get_key(pubkey_str).await; - - assert_eq!(Ok(Keypair::only_pubkey(expected_pubkey)), login_key_result); - } - - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_pubkey() { + #[test] + fn test_pubkey() { let pubkey_str = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"; let expected_pubkey = Pubkey::try_from_bech32_string(pubkey_str, false).expect("Should not have errored."); @@ -162,8 +163,8 @@ mod tests { ); } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_hex_pubkey() { + #[test] + fn test_hex_pubkey() { let pubkey_str = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"; let expected_pubkey = Pubkey::from_hex(pubkey_str).expect("Should not have errored."); let login_key_result = perform_key_retrieval(pubkey_str); @@ -175,8 +176,8 @@ mod tests { ); } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_privkey() { + #[test] + fn test_privkey() { let privkey_str = "nsec1g8wt3hlwjpa4827xylr3r0lccufxltyekhraexes8lqmpp2hensq5aujhs"; let expected_privkey = SecretKey::from_str(privkey_str).expect("Should not have errored."); let login_key_result = perform_key_retrieval(privkey_str); @@ -188,8 +189,8 @@ mod tests { ); } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_hex_privkey() { + #[test] + fn test_hex_privkey() { let privkey_str = "41dcb8dfee907b53abc627c711bff8c7126fac99b5c7dc9b303fc1b08557cce0"; let expected_privkey = SecretKey::from_str(privkey_str).expect("Should not have errored."); let login_key_result = perform_key_retrieval(privkey_str); @@ -201,8 +202,8 @@ mod tests { ); } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_nip05() { + #[test] + fn test_nip05() { let nip05_str = "damus@damus.io"; let expected_pubkey = Pubkey::try_from_bech32_string( "npub18m76awca3y37hkvuneavuw6pjj4525fw90necxmadrvjg0sdy6qsngq955", @@ -217,4 +218,18 @@ mod tests { &login_key_result ); } + + #[test] + fn test_nip05_pubkey() { + let nip05_str = "damus@damus.io"; + let expected_pubkey = Pubkey::try_from_bech32_string( + "npub18m76awca3y37hkvuneavuw6pjj4525fw90necxmadrvjg0sdy6qsngq955", + false, + ) + .expect("Should not have errored."); + let login_key_result = get_nip05_pubkey(nip05_str); + + let res = login_key_result.block_and_take().expect("Should not error"); + assert_eq!(expected_pubkey, res); + } } diff --git a/crates/notedeck_columns/src/login_manager.rs b/crates/notedeck_columns/src/login_manager.rs @@ -45,7 +45,6 @@ impl<'a> AcquireKeyState { } } - /// Whether to indicate to the user that there is a network operation occuring pub fn is_awaiting_network(&self) -> bool { self.promise_query.is_some() } @@ -98,8 +97,8 @@ mod tests { use super::*; use std::time::{Duration, Instant}; - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_retrieve_key() { + #[test] + fn test_retrieve_key() { let mut manager = AcquireKeyState::new(); let expected_str = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"; let expected_key = Keypair::only_pubkey(Pubkey::from_hex(expected_str).unwrap()); @@ -141,6 +140,6 @@ mod tests { } } - panic!("Test failed to get expected key."); + panic!(); } }