field_lib

Cross-platform Rust runtime for Radroots iOS and Android apps
git clone https://radroots.dev/git/field_lib.git
Log | Files | Refs | README | LICENSE

commit cabb6376c9b77ad313df5e3b08e25f655c85ff3d
parent 383d56b6bf0887610c878f5e000d2b6323b87fe8
Author: triesap <tyson@radroots.org>
Date:   Fri, 12 Jun 2026 00:05:40 -0700

field: add nostr identity reset ffi

- expose a single reset-all operation for field Nostr identities

- clear selected and unselected identities through the rr-rs accounts manager

- cover default and no-Nostr feature behavior

Diffstat:
Mcrates/field_core/src/runtime/key_management.rs | 30++++++++++++++++++++++++++++++
Acrates/field_core/tests/key_management.rs | 46++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/field_core/tests/no_nostr_runtime.rs | 1+
3 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/crates/field_core/src/runtime/key_management.rs b/crates/field_core/src/runtime/key_management.rs @@ -319,4 +319,34 @@ impl RadrootsRuntime { Err(RadrootsAppError::Msg("nostr disabled".into())) } } + + pub fn nostr_identity_reset_all(&self) -> Result<(), RadrootsAppError> { + #[cfg(feature = "nostr-client")] + { + let mut guard = match self.net.lock() { + Ok(guard) => guard, + Err(err) => return Err(RadrootsAppError::Msg(format!("{err}"))), + }; + let accounts = guard + .accounts + .list_accounts() + .map_err(|e| RadrootsAppError::Msg(format!("{e}")))?; + for account in accounts { + guard + .accounts + .remove_account(&account.account_id) + .map_err(|e| RadrootsAppError::Msg(format!("{e}")))?; + } + guard + .accounts + .clear_default_account() + .map_err(|e| RadrootsAppError::Msg(format!("{e}")))?; + guard.nostr = None; + Ok(()) + } + #[cfg(not(feature = "nostr-client"))] + { + Err(RadrootsAppError::Msg("nostr disabled".into())) + } + } } diff --git a/crates/field_core/tests/key_management.rs b/crates/field_core/tests/key_management.rs @@ -0,0 +1,46 @@ +#![cfg(feature = "nostr-client")] + +use radroots_field_core::RadrootsRuntime; + +#[test] +fn identity_reset_all_removes_selected_and_unselected_identities() { + let runtime = RadrootsRuntime::new().expect("runtime"); + + let selected_id = runtime + .nostr_identity_generate(Some("selected".to_string()), true) + .expect("selected identity"); + let other_id = runtime + .nostr_identity_generate(Some("other".to_string()), false) + .expect("other identity"); + + let snapshot = runtime.nostr_identity_snapshot().expect("snapshot"); + assert!(snapshot.has_selected_signing_identity); + assert_eq!( + snapshot.selected_identity_id.as_deref(), + Some(selected_id.as_str()) + ); + assert_eq!(snapshot.identities.len(), 2); + assert!( + runtime + .nostr_identity_export_selected_secret_hex() + .expect("export") + .is_some() + ); + + runtime.nostr_identity_reset_all().expect("reset all"); + + let snapshot = runtime.nostr_identity_snapshot().expect("reset snapshot"); + assert!(!snapshot.has_selected_signing_identity); + assert_eq!(snapshot.selected_identity_id, None); + assert_eq!(snapshot.selected_npub, None); + assert!(snapshot.identities.is_empty()); + assert!(runtime.nostr_identity_list().expect("list").is_empty()); + assert_eq!( + runtime + .nostr_identity_export_selected_secret_hex() + .expect("export after reset"), + None + ); + + assert!(runtime.nostr_identity_remove(other_id).is_err()); +} diff --git a/crates/field_core/tests/no_nostr_runtime.rs b/crates/field_core/tests/no_nostr_runtime.rs @@ -48,6 +48,7 @@ fn key_management_disabled_paths_are_exercised() { expect_disabled(runtime.nostr_identity_export_selected_secret_hex()); expect_disabled(runtime.nostr_identity_select("account-1".to_string())); expect_disabled(runtime.nostr_identity_remove("account-1".to_string())); + expect_disabled(runtime.nostr_identity_reset_all()); } #[test]