commit 1e05fa551d878dd5dbe89cea446f384aa1ff4dba
parent 69b651bbc5ebf6251f4dd4c3923f056894f4e488
Author: kernelkind <kernelkind@gmail.com>
Date: Sat, 15 Mar 2025 15:06:40 -0400
simplify key storage
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
6 files changed, 66 insertions(+), 145 deletions(-)
diff --git a/crates/notedeck/src/accounts.rs b/crates/notedeck/src/accounts.rs
@@ -1,8 +1,7 @@
use tracing::{debug, error, info};
use crate::{
- KeyStorageResponse, KeyStorageType, MuteFun, Muted, RelaySpec, SingleUnkIdAction, UnknownIds,
- UserAccount,
+ FileKeyStorage, MuteFun, Muted, RelaySpec, SingleUnkIdAction, UnknownIds, UserAccount,
};
use enostr::{ClientMessage, FilledKeypair, Keypair, RelayPool};
use nostrdb::{Filter, Ndb, Note, NoteBuilder, NoteKey, Subscription, Transaction};
@@ -309,7 +308,7 @@ pub struct AccountData {
pub struct Accounts {
currently_selected_account: Option<usize>,
accounts: Vec<UserAccount>,
- key_store: KeyStorageType,
+ key_store: Option<FileKeyStorage>,
account_data: BTreeMap<[u8; 32], AccountData>,
forced_relays: BTreeSet<RelaySpec>,
bootstrap_relays: BTreeSet<RelaySpec>,
@@ -317,14 +316,24 @@ pub struct Accounts {
}
impl Accounts {
- pub fn new(key_store: KeyStorageType, forced_relays: Vec<String>) -> Self {
- let accounts = if let KeyStorageResponse::ReceivedResult(res) = key_store.get_keys() {
- res.unwrap_or_default()
+ pub fn new(key_store: Option<FileKeyStorage>, forced_relays: Vec<String>) -> Self {
+ let accounts = match &key_store {
+ Some(keystore) => match keystore.get_keys() {
+ Ok(k) => k,
+ Err(e) => {
+ tracing::error!("could not get keys: {e}");
+ Vec::new()
+ }
+ },
+ None => Vec::new(),
+ };
+
+ let currently_selected_account = if let Some(key_store) = &key_store {
+ get_selected_index(&accounts, key_store)
} else {
- Vec::new()
+ None
};
- let currently_selected_account = get_selected_index(&accounts, &key_store);
let account_data = BTreeMap::new();
let forced_relays: BTreeSet<RelaySpec> = forced_relays
.into_iter()
@@ -367,7 +376,12 @@ impl Accounts {
pub fn remove_account(&mut self, index: usize) {
if let Some(account) = self.accounts.get(index) {
- let _ = self.key_store.remove_key(account);
+ if let Some(key_store) = &self.key_store {
+ if let Err(e) = key_store.remove_key(account) {
+ tracing::error!("Could not remove account at index {index}: {e}");
+ }
+ }
+
self.accounts.remove(index);
if let Some(selected_index) = self.currently_selected_account {
@@ -426,7 +440,12 @@ impl Accounts {
"user provided nsec, but we already have npub {}. Upgrading to nsec",
pubkey
);
- let _ = self.key_store.add_key(&account);
+
+ if let Some(key_store) = &self.key_store {
+ if let Err(e) = key_store.add_key(&account) {
+ tracing::error!("Could not add key for {:?}: {e}", account.pubkey);
+ }
+ }
self.accounts[contains_acc.index] = account;
} else {
@@ -435,7 +454,11 @@ impl Accounts {
contains_acc.index
} else {
info!("adding new account {}", pubkey);
- let _ = self.key_store.add_key(&account);
+ if let Some(key_store) = &self.key_store {
+ if let Err(e) = key_store.add_key(&account) {
+ tracing::error!("Could not add key for {:?}: {e}", account.pubkey);
+ }
+ }
self.accounts.push(account);
self.accounts.len() - 1
};
@@ -493,13 +516,21 @@ impl Accounts {
pub fn select_account(&mut self, index: usize) {
if let Some(account) = self.accounts.get(index) {
self.currently_selected_account = Some(index);
- self.key_store.select_key(Some(account.pubkey));
+ if let Some(key_store) = &self.key_store {
+ if let Err(e) = key_store.select_key(Some(account.pubkey)) {
+ tracing::error!("Could not select key {:?}: {e}", account.pubkey);
+ }
+ }
}
}
pub fn clear_selected_account(&mut self) {
self.currently_selected_account = None;
- self.key_store.select_key(None);
+ if let Some(key_store) = &self.key_store {
+ if let Err(e) = key_store.select_key(None) {
+ tracing::error!("Could not select None key: {e}");
+ }
+ }
}
pub fn mutefun(&self) -> Box<MuteFun> {
@@ -794,14 +825,13 @@ enum RelayAction {
Remove,
}
-fn get_selected_index(accounts: &[UserAccount], keystore: &KeyStorageType) -> Option<usize> {
+fn get_selected_index(accounts: &[UserAccount], keystore: &FileKeyStorage) -> Option<usize> {
match keystore.get_selected_key() {
- KeyStorageResponse::ReceivedResult(Ok(Some(pubkey))) => {
+ Ok(Some(pubkey)) => {
return accounts.iter().position(|account| account.pubkey == pubkey);
}
-
- KeyStorageResponse::ReceivedResult(Err(e)) => error!("Error getting selected key: {}", e),
- KeyStorageResponse::Waiting | KeyStorageResponse::ReceivedResult(Ok(None)) => {}
+ Ok(None) => {}
+ Err(e) => error!("Error getting selected key: {}", e),
};
None
diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs
@@ -1,7 +1,7 @@
use crate::persist::{AppSizeHandler, ZoomHandler};
use crate::{
Accounts, AppContext, Args, DataPath, DataPathType, Directory, FileKeyStorage, Images,
- KeyStorageType, NoteCache, RelayDebugView, ThemeHandler, UnknownIds,
+ NoteCache, RelayDebugView, ThemeHandler, UnknownIds,
};
use egui::ThemePreference;
use egui_winit::clipboard::Clipboard;
@@ -149,12 +149,12 @@ impl Notedeck {
let keystore = if parsed_args.use_keystore {
let keys_path = path.path(DataPathType::Keys);
let selected_key_path = path.path(DataPathType::SelectedKey);
- KeyStorageType::FileSystem(FileKeyStorage::new(
+ Some(FileKeyStorage::new(
Directory::new(keys_path),
Directory::new(selected_key_path),
))
} else {
- KeyStorageType::None
+ None
};
let mut accounts = Accounts::new(keystore, parsed_args.relays.clone());
diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs
@@ -44,9 +44,7 @@ pub use persist::*;
pub use relay_debug::RelayDebugView;
pub use relayspec::RelaySpec;
pub use result::Result;
-pub use storage::{
- DataPath, DataPathType, Directory, FileKeyStorage, KeyStorageResponse, KeyStorageType,
-};
+pub use storage::{DataPath, DataPathType, Directory, FileKeyStorage};
pub use style::NotedeckTextStyle;
pub use theme::ColorTheme;
pub use time::time_ago_since;
diff --git a/crates/notedeck/src/storage/file_key_storage.rs b/crates/notedeck/src/storage/file_key_storage.rs
@@ -1,10 +1,7 @@
use crate::Result;
use enostr::{Keypair, Pubkey, SerializableKeypair};
-use super::{
- file_storage::{delete_file, write_file, Directory},
- key_storage_impl::KeyStorageResponse,
-};
+use super::file_storage::{delete_file, write_file, Directory};
static SELECTED_PUBKEY_FILE_NAME: &str = "selected_pubkey";
@@ -23,7 +20,7 @@ impl FileKeyStorage {
}
}
- fn add_key_internal(&self, key: &Keypair) -> Result<()> {
+ pub fn add_key(&self, key: &Keypair) -> Result<()> {
write_file(
&self.keys_directory.file_path,
key.pubkey.hex(),
@@ -31,7 +28,7 @@ impl FileKeyStorage {
)
}
- fn get_keys_internal(&self) -> Result<Vec<Keypair>> {
+ pub fn get_keys(&self) -> Result<Vec<Keypair>> {
let keys = self
.keys_directory
.get_files()?
@@ -42,11 +39,11 @@ impl FileKeyStorage {
Ok(keys)
}
- fn remove_key_internal(&self, key: &Keypair) -> Result<()> {
+ pub fn remove_key(&self, key: &Keypair) -> Result<()> {
delete_file(&self.keys_directory.file_path, key.pubkey.hex())
}
- fn get_selected_pubkey(&self) -> Result<Option<Pubkey>> {
+ pub fn get_selected_key(&self) -> Result<Option<Pubkey>> {
match self
.selected_key_directory
.get_file(SELECTED_PUBKEY_FILE_NAME.to_owned())
@@ -57,7 +54,7 @@ impl FileKeyStorage {
}
}
- fn select_pubkey(&self, pubkey: Option<Pubkey>) -> Result<()> {
+ pub fn select_key(&self, pubkey: Option<Pubkey>) -> Result<()> {
if let Some(pubkey) = pubkey {
write_file(
&self.selected_key_directory.file_path,
@@ -80,28 +77,6 @@ impl FileKeyStorage {
}
}
-impl FileKeyStorage {
- pub fn get_keys(&self) -> KeyStorageResponse<Vec<enostr::Keypair>> {
- KeyStorageResponse::ReceivedResult(self.get_keys_internal())
- }
-
- pub fn add_key(&self, key: &enostr::Keypair) -> KeyStorageResponse<()> {
- KeyStorageResponse::ReceivedResult(self.add_key_internal(key))
- }
-
- pub fn remove_key(&self, key: &enostr::Keypair) -> KeyStorageResponse<()> {
- KeyStorageResponse::ReceivedResult(self.remove_key_internal(key))
- }
-
- pub fn get_selected_key(&self) -> KeyStorageResponse<Option<Pubkey>> {
- KeyStorageResponse::ReceivedResult(self.get_selected_pubkey())
- }
-
- pub fn select_key(&self, key: Option<Pubkey>) -> KeyStorageResponse<()> {
- KeyStorageResponse::ReceivedResult(self.select_pubkey(key))
- }
-}
-
#[cfg(test)]
mod tests {
use std::path::PathBuf;
@@ -128,27 +103,21 @@ mod tests {
let storage = FileKeyStorage::mock().unwrap();
let resp = storage.add_key(&kp);
- assert_eq!(resp, KeyStorageResponse::ReceivedResult(Ok(())));
+ assert!(resp.is_ok());
assert_num_storage(&storage.get_keys(), 1);
- assert_eq!(
- storage.remove_key(&kp),
- KeyStorageResponse::ReceivedResult(Ok(()))
- );
+ assert!(storage.remove_key(&kp).is_ok());
assert_num_storage(&storage.get_keys(), 0);
}
- fn assert_num_storage(keys_response: &KeyStorageResponse<Vec<Keypair>>, n: usize) {
+ fn assert_num_storage(keys_response: &Result<Vec<Keypair>>, n: usize) {
match keys_response {
- KeyStorageResponse::ReceivedResult(Ok(keys)) => {
+ Ok(keys) => {
assert_eq!(keys.len(), n);
}
- KeyStorageResponse::ReceivedResult(Err(_e)) => {
+ Err(_e) => {
panic!("could not get keys");
}
- KeyStorageResponse::Waiting => {
- panic!("did not receive result");
- }
}
}
@@ -160,10 +129,10 @@ mod tests {
let _ = storage.add_key(&kp);
assert_num_storage(&storage.get_keys(), 1);
- let resp = storage.select_pubkey(Some(kp.pubkey));
+ let resp = storage.select_key(Some(kp.pubkey));
assert!(resp.is_ok());
- let resp = storage.get_selected_pubkey();
+ let resp = storage.get_selected_key();
assert!(resp.is_ok());
}
@@ -174,7 +143,7 @@ mod tests {
// Should return Ok(None) when no key has been selected
match storage.get_selected_key() {
- KeyStorageResponse::ReceivedResult(Ok(None)) => (), // This is what we expect
+ Ok(None) => (), // This is what we expect
other => panic!("Expected Ok(None), got {:?}", other),
}
}
diff --git a/crates/notedeck/src/storage/key_storage_impl.rs b/crates/notedeck/src/storage/key_storage_impl.rs
@@ -1,73 +0,0 @@
-use enostr::{Keypair, Pubkey};
-
-use super::file_key_storage::FileKeyStorage;
-use crate::Result;
-
-#[derive(Debug, PartialEq)]
-pub enum KeyStorageType {
- None,
- FileSystem(FileKeyStorage),
-}
-
-#[allow(dead_code)]
-#[derive(Debug)]
-pub enum KeyStorageResponse<R> {
- Waiting,
- ReceivedResult(Result<R>),
-}
-
-impl<R: PartialEq> PartialEq for KeyStorageResponse<R> {
- fn eq(&self, other: &Self) -> bool {
- match (self, other) {
- (KeyStorageResponse::Waiting, KeyStorageResponse::Waiting) => true,
- (
- KeyStorageResponse::ReceivedResult(Ok(r1)),
- KeyStorageResponse::ReceivedResult(Ok(r2)),
- ) => r1 == r2,
- (
- KeyStorageResponse::ReceivedResult(Err(_)),
- KeyStorageResponse::ReceivedResult(Err(_)),
- ) => true,
- _ => false,
- }
- }
-}
-
-impl KeyStorageType {
- pub fn get_keys(&self) -> KeyStorageResponse<Vec<Keypair>> {
- match self {
- Self::None => KeyStorageResponse::ReceivedResult(Ok(Vec::new())),
- Self::FileSystem(f) => f.get_keys(),
- }
- }
-
- pub fn add_key(&self, key: &Keypair) -> KeyStorageResponse<()> {
- let _ = key;
- match self {
- Self::None => KeyStorageResponse::ReceivedResult(Ok(())),
- Self::FileSystem(f) => f.add_key(key),
- }
- }
-
- pub fn remove_key(&self, key: &Keypair) -> KeyStorageResponse<()> {
- let _ = key;
- match self {
- Self::None => KeyStorageResponse::ReceivedResult(Ok(())),
- Self::FileSystem(f) => f.remove_key(key),
- }
- }
-
- pub fn get_selected_key(&self) -> KeyStorageResponse<Option<Pubkey>> {
- match self {
- Self::None => KeyStorageResponse::ReceivedResult(Ok(None)),
- Self::FileSystem(f) => f.get_selected_key(),
- }
- }
-
- pub fn select_key(&self, key: Option<Pubkey>) -> KeyStorageResponse<()> {
- match self {
- Self::None => KeyStorageResponse::ReceivedResult(Ok(())),
- Self::FileSystem(f) => f.select_key(key),
- }
- }
-}
diff --git a/crates/notedeck/src/storage/mod.rs b/crates/notedeck/src/storage/mod.rs
@@ -3,6 +3,3 @@ mod file_storage;
pub use file_key_storage::FileKeyStorage;
pub use file_storage::{delete_file, write_file, DataPath, DataPathType, Directory};
-
-pub mod key_storage_impl;
-pub use key_storage_impl::{KeyStorageResponse, KeyStorageType};