commit 0e123a2f9f47664ec175115e10aba9785d4bf674
parent e5762fa32e6973d78415680e437a763da8cbc9f4
Author: triesap <triesap@radroots.dev>
Date: Mon, 19 Jan 2026 19:42:41 +0000
app: persist nostr public key in app data
- add helper to read app data from datastore
- store active_key from keystore during init
- write updated app data when missing or stale
- add unit test for app data read errors
Diffstat:
3 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/app/src/bootstrap.rs b/app/src/bootstrap.rs
@@ -48,6 +48,17 @@ pub async fn app_datastore_write_app_data<T: RadrootsClientDatastore>(
.map_err(AppInitError::Datastore)
}
+pub async fn app_datastore_read_app_data<T: RadrootsClientDatastore>(
+ datastore: &T,
+ key_maps: &AppKeyMapConfig,
+) -> AppInitResult<AppAppData> {
+ let key = app_datastore_obj_key_app_data(key_maps).map_err(AppInitError::Config)?;
+ datastore
+ .get_obj::<AppAppData>(key)
+ .await
+ .map_err(AppInitError::Datastore)
+}
+
pub async fn app_datastore_has_app_data<T: RadrootsClientDatastore>(
datastore: &T,
key_maps: &AppKeyMapConfig,
@@ -81,11 +92,12 @@ pub async fn app_datastore_clear_bootstrap<T: RadrootsClientDatastore>(
mod tests {
use super::{
app_datastore_clear_bootstrap,
- app_datastore_has_app_data,
- app_datastore_has_config,
- app_datastore_write_app_data,
- app_datastore_write_config,
- };
+ app_datastore_has_app_data,
+ app_datastore_has_config,
+ app_datastore_read_app_data,
+ app_datastore_write_app_data,
+ app_datastore_write_config,
+};
use crate::{app_key_maps_default, AppAppData, AppConfigData, AppInitError};
use radroots_app_core::datastore::{RadrootsClientDatastoreError, RadrootsClientWebDatastore};
@@ -118,6 +130,18 @@ mod tests {
}
#[test]
+ fn app_data_read_maps_idb_errors() {
+ let datastore = RadrootsClientWebDatastore::new(None);
+ let key_maps = app_key_maps_default();
+ let err = futures::executor::block_on(app_datastore_read_app_data(
+ &datastore,
+ &key_maps,
+ ))
+ .expect_err("idb undefined");
+ assert_eq!(err, AppInitError::Datastore(RadrootsClientDatastoreError::IdbUndefined));
+ }
+
+ #[test]
fn clear_bootstrap_maps_idb_errors() {
let datastore = RadrootsClientWebDatastore::new(None);
let key_maps = app_key_maps_default();
diff --git a/app/src/init.rs b/app/src/init.rs
@@ -23,6 +23,7 @@ use crate::{
app_datastore_has_app_data,
app_datastore_has_config,
app_datastore_key_nostr_key,
+ app_datastore_read_app_data,
app_datastore_write_app_data,
app_datastore_write_config,
app_keystore_nostr_ensure_key,
@@ -198,12 +199,6 @@ pub async fn app_init_backends(config: AppConfig) -> AppInitResult<AppBackends>
app_datastore_write_config(&datastore, &config.datastore.key_maps, &config_data)
.await?;
}
- let has_app_data = app_datastore_has_app_data(&datastore, &config.datastore.key_maps).await?;
- if !has_app_data {
- let app_data = AppAppData::default();
- let _ = app_datastore_write_app_data(&datastore, &config.datastore.key_maps, &app_data)
- .await?;
- }
let nostr_keystore = RadrootsClientWebKeystoreNostr::new(Some(config.keystore.nostr_store));
let nostr_public_key = app_keystore_nostr_ensure_key(&nostr_keystore)
.await
@@ -229,6 +224,19 @@ pub async fn app_init_backends(config: AppConfig) -> AppInitResult<AppBackends>
}
Err(err) => return Err(AppInitError::Datastore(err)),
}
+ let has_app_data = app_datastore_has_app_data(&datastore, &config.datastore.key_maps).await?;
+ let mut app_data = if has_app_data {
+ app_datastore_read_app_data(&datastore, &config.datastore.key_maps).await?
+ } else {
+ AppAppData::default()
+ };
+ let should_write = !has_app_data || app_data.active_key != nostr_public_key;
+ if should_write {
+ app_data.active_key = nostr_public_key;
+ let _ =
+ app_datastore_write_app_data(&datastore, &config.datastore.key_maps, &app_data)
+ .await?;
+ }
Ok(AppBackends {
config,
datastore,
diff --git a/app/src/lib.rs b/app/src/lib.rs
@@ -15,6 +15,7 @@ pub use bootstrap::{
app_datastore_clear_bootstrap,
app_datastore_has_app_data,
app_datastore_has_config,
+ app_datastore_read_app_data,
app_datastore_write_app_data,
app_datastore_write_config,
};