app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 2f2a6d787d3a44c962d4cb9b724e6318dec40c71
parent 25d9dccc1574274d217d6592e206f9369dfa5388
Author: triesap <triesap@radroots.dev>
Date:   Mon, 19 Jan 2026 19:39:13 +0000

app: add keystore reset to init reset

- extend app_init_reset to accept a keystore reference
- clear keystore on reset alongside bootstrap data
- map keystore reset errors into init errors
- add unit tests for reset error handling

Diffstat:
Mapp/src/app.rs | 8+++++++-
Mapp/src/init.rs | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/app/src/app.rs b/app/src/app.rs @@ -137,7 +137,13 @@ pub fn App() -> impl IntoView { let datastore = radroots_app_core::datastore::RadrootsClientWebDatastore::new( Some(config.datastore.idb_config), ); - match app_init_reset(Some(&datastore), Some(&config.datastore.key_maps)).await { + match app_init_reset( + Some(&datastore), + Some(&config.datastore.key_maps), + None::<&radroots_app_core::keystore::RadrootsClientWebKeystoreNostr>, + ) + .await + { Ok(()) => reset_status.set(Some("reset_done".to_string())), Err(err) => reset_status.set(Some(err.to_string())), } diff --git a/app/src/init.rs b/app/src/init.rs @@ -12,7 +12,11 @@ use radroots_app_core::idb::{ RadrootsClientIdbStoreError, RADROOTS_IDB_DATABASE, }; -use radroots_app_core::keystore::{RadrootsClientKeystoreError, RadrootsClientWebKeystoreNostr}; +use radroots_app_core::keystore::{ + RadrootsClientKeystoreError, + RadrootsClientKeystoreNostr, + RadrootsClientWebKeystoreNostr, +}; use crate::{ app_datastore_clear_bootstrap, @@ -156,13 +160,17 @@ pub fn app_init_mark_completed() { } } -pub async fn app_init_reset<T: RadrootsClientDatastore>( +pub async fn app_init_reset<T: RadrootsClientDatastore, K: RadrootsClientKeystoreNostr>( datastore: Option<&T>, key_maps: Option<&AppKeyMapConfig>, + keystore: Option<&K>, ) -> AppInitResult<()> { if let (Some(datastore), Some(key_maps)) = (datastore, key_maps) { app_datastore_clear_bootstrap(datastore, key_maps).await?; } + if let Some(keystore) = keystore { + keystore.reset().await.map_err(AppInitError::Keystore)?; + } #[cfg(target_arch = "wasm32")] { let window = window(); @@ -240,7 +248,12 @@ mod tests { use crate::app_config_default; use radroots_app_core::datastore::RadrootsClientDatastoreError; use radroots_app_core::idb::RadrootsClientIdbStoreError; - use radroots_app_core::keystore::RadrootsClientKeystoreError; + use radroots_app_core::keystore::{ + RadrootsClientKeystoreError, + RadrootsClientKeystoreNostr, + RadrootsClientKeystoreResult, + }; + use async_trait::async_trait; use crate::AppConfigError; #[test] @@ -291,10 +304,54 @@ mod tests { super::app_init_mark_completed(); let result = futures::executor::block_on(super::app_init_reset::< radroots_app_core::datastore::RadrootsClientWebDatastore, - >(None, None)); + TestKeystore, + >(None, None, None)); assert!(result.is_ok()); } + struct TestKeystore; + + #[async_trait(?Send)] + impl RadrootsClientKeystoreNostr for TestKeystore { + async fn generate(&self) -> RadrootsClientKeystoreResult<String> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + + async fn add(&self, _secret_key: &str) -> RadrootsClientKeystoreResult<String> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + + async fn read(&self, _public_key: &str) -> RadrootsClientKeystoreResult<String> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + + async fn keys(&self) -> RadrootsClientKeystoreResult<Vec<String>> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + + async fn remove(&self, _public_key: &str) -> RadrootsClientKeystoreResult<String> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + + async fn reset(&self) -> RadrootsClientKeystoreResult<()> { + Err(RadrootsClientKeystoreError::IdbUndefined) + } + } + + #[test] + fn app_init_reset_maps_keystore_errors() { + let keystore = TestKeystore; + let err = futures::executor::block_on(super::app_init_reset::< + radroots_app_core::datastore::RadrootsClientWebDatastore, + TestKeystore, + >(None, None, Some(&keystore))) + .expect_err("keystore reset should error on native"); + assert_eq!( + err, + AppInitError::Keystore(RadrootsClientKeystoreError::IdbUndefined) + ); + } + #[test] fn app_init_stage_roundtrip() { let stage = AppInitStage::Ready;