app

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

commit f6258f829c64d6f9ec1a34a595c88b4ae078312b
parent bc072421f5bf0c99586deca88d018dca01e9f33a
Author: triesap <triesap@radroots.dev>
Date:   Mon, 19 Jan 2026 00:50:00 +0000

app-core: add keystore traits

- define keystore value/result aliases for client APIs
- add async keystore trait with backup integration
- add nostr keystore trait for key lifecycle actions
- include unit test for optional keystore values

Diffstat:
Mcrates/core/src/keystore/mod.rs | 7+++++++
Acrates/core/src/keystore/types.rs | 46++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/crates/core/src/keystore/mod.rs b/crates/core/src/keystore/mod.rs @@ -1,3 +1,10 @@ pub mod error; +pub mod types; pub use error::{RadrootsClientKeystoreError, RadrootsClientKeystoreErrorMessage}; +pub use types::{ + RadrootsClientKeystore, + RadrootsClientKeystoreNostr, + RadrootsClientKeystoreResult, + RadrootsClientKeystoreValue, +}; diff --git a/crates/core/src/keystore/types.rs b/crates/core/src/keystore/types.rs @@ -0,0 +1,46 @@ +use async_trait::async_trait; + +use crate::backup::RadrootsClientBackupKeystorePayload; + +use super::RadrootsClientKeystoreError; + +pub type RadrootsClientKeystoreValue = Option<String>; +pub type RadrootsClientKeystoreResult<T> = Result<T, RadrootsClientKeystoreError>; + +#[async_trait(?Send)] +pub trait RadrootsClientKeystore { + async fn add(&self, key: &str, value: &str) -> RadrootsClientKeystoreResult<String>; + async fn remove(&self, key: &str) -> RadrootsClientKeystoreResult<String>; + async fn read(&self, key: Option<&str>) -> RadrootsClientKeystoreResult<RadrootsClientKeystoreValue>; + async fn keys(&self) -> RadrootsClientKeystoreResult<Vec<String>>; + async fn reset(&self) -> RadrootsClientKeystoreResult<()>; + fn get_store_id(&self) -> &str; + async fn export_backup( + &self, + ) -> RadrootsClientKeystoreResult<RadrootsClientBackupKeystorePayload>; + async fn import_backup( + &self, + payload: RadrootsClientBackupKeystorePayload, + ) -> RadrootsClientKeystoreResult<()>; +} + +#[async_trait(?Send)] +pub trait RadrootsClientKeystoreNostr { + async fn generate(&self) -> RadrootsClientKeystoreResult<String>; + async fn add(&self, secret_key: &str) -> RadrootsClientKeystoreResult<String>; + async fn read(&self, public_key: &str) -> RadrootsClientKeystoreResult<String>; + async fn keys(&self) -> RadrootsClientKeystoreResult<Vec<String>>; + async fn remove(&self, public_key: &str) -> RadrootsClientKeystoreResult<String>; + async fn reset(&self) -> RadrootsClientKeystoreResult<()>; +} + +#[cfg(test)] +mod tests { + use super::RadrootsClientKeystoreValue; + + #[test] + fn keystore_value_allows_none() { + let value: RadrootsClientKeystoreValue = None; + assert!(value.is_none()); + } +}