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:
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]