myc

Self-custodial remote signer for Radroots apps
git clone https://radroots.dev/git/myc.git
Log | Files | Refs | README | LICENSE

commit 580ec6f4d69a55c59b478f3c5ac6d1774419c715
parent b9f5675ae6322c0c7fde42f185b34419ab3f56b0
Author: triesap <tyson@radroots.org>
Date:   Sun, 12 Apr 2026 18:40:42 +0000

myc: consume shared identity file storage

Diffstat:
MCargo.lock | 4+++-
MCargo.toml | 1-
Msrc/app/backend.rs | 2+-
Msrc/app/mod.rs | 2+-
Msrc/app/runtime.rs | 2+-
Msrc/cli.rs | 2+-
Msrc/control.rs | 2+-
Msrc/custody.rs | 55+++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/discovery.rs | 2+-
Asrc/identity_files.rs | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/identity_storage.rs | 287-------------------------------------------------------------------------------
Msrc/lib.rs | 2+-
Msrc/operability/mod.rs | 2+-
Msrc/persistence.rs | 4++--
Msrc/transport/nip46.rs | 2+-
Mtests/discovery_cli.rs | 16++++++++--------
Mtests/logging_run.rs | 2+-
Mtests/nip46_e2e.rs | 28++++++++++++++--------------
Mtests/operability_cli.rs | 6+++---
Mtests/operability_e2e.rs | 2+-
Mtests/operability_server.rs | 2+-
Mtests/persistence_cli.rs | 10+++++-----
22 files changed, 197 insertions(+), 339 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1360,7 +1360,6 @@ dependencies = [ "radroots_nostr_accounts", "radroots_nostr_connect", "radroots_nostr_signer", - "radroots_protected_store", "radroots_runtime_paths", "radroots_secret_vault", "radroots_sql_core", @@ -1765,8 +1764,10 @@ version = "0.1.0-alpha.2" dependencies = [ "nostr", "radroots_events", + "radroots_protected_store", "radroots_runtime", "radroots_runtime_paths", + "radroots_secret_vault", "serde", "serde_json", "thiserror 1.0.69", @@ -1804,6 +1805,7 @@ version = "0.1.0-alpha.2" dependencies = [ "radroots_identity", "radroots_nostr_signer", + "radroots_protected_store", "radroots_runtime", "radroots_secret_vault", "serde", diff --git a/Cargo.toml b/Cargo.toml @@ -25,7 +25,6 @@ radroots_nostr_accounts = { path = "../lib/crates/nostr_accounts", default-featu radroots_nostr = { path = "../lib/crates/nostr", features = ["client", "events"] } radroots_nostr_connect = { path = "../lib/crates/nostr_connect" } radroots_nostr_signer = { path = "../lib/crates/nostr_signer", features = ["native"] } -radroots_protected_store = { path = "../lib/crates/protected_store", features = ["std"] } radroots_runtime_paths = { path = "../lib/crates/runtime_paths" } radroots_secret_vault = { path = "../lib/crates/secret_vault", features = ["std", "os-keyring"] } radroots_sql_core = { path = "../lib/crates/sql_core", features = ["native"] } diff --git a/src/app/backend.rs b/src/app/backend.rs @@ -360,7 +360,7 @@ mod tests { fn write_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn test_runtime() -> MycRuntime { diff --git a/src/app/mod.rs b/src/app/mod.rs @@ -52,7 +52,7 @@ mod tests { fn write_test_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } #[test] diff --git a/src/app/runtime.rs b/src/app/runtime.rs @@ -1275,7 +1275,7 @@ mod tests { fn write_test_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } fn write_external_command_helper(path: &std::path::Path, secret_key: &str) -> RadrootsIdentity { diff --git a/src/cli.rs b/src/cli.rs @@ -1059,7 +1059,7 @@ mod tests { fn write_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn runtime() -> MycRuntime { diff --git a/src/control.rs b/src/control.rs @@ -803,7 +803,7 @@ mod tests { fn write_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn runtime_with_config<F>(approval: MycConnectionApproval, configure: F) -> MycRuntime diff --git a/src/custody.rs b/src/custody.rs @@ -1,4 +1,5 @@ use std::fs; +use std::path::Path; use std::path::PathBuf; use std::process::{Command, Stdio}; use std::sync::Arc; @@ -19,9 +20,9 @@ use zeroize::Zeroizing; use crate::config::{MycConfig, MycIdentityBackend, MycIdentitySourceSpec}; use crate::error::MycError; -use crate::identity_storage::{ +use crate::identity_files::{ load_encrypted_identity, load_identity_profile, rotate_encrypted_identity, - store_encrypted_identity, store_identity_profile, store_plaintext_identity, store_secret_text, + store_encrypted_identity, store_identity_profile, }; #[derive(Clone)] @@ -31,6 +32,46 @@ pub struct MycActiveIdentity { operations: Arc<dyn MycIdentityOperations>, } +fn store_plaintext_identity( + path: impl AsRef<Path>, + identity: &RadrootsIdentity, +) -> Result<(), MycError> { + identity.save_json(path).map_err(MycError::from) +} + +fn store_secret_text(path: impl AsRef<Path>, value: &str) -> Result<(), MycError> { + let path = path.as_ref(); + if let Some(parent) = path.parent() + && !parent.as_os_str().is_empty() + { + fs::create_dir_all(parent).map_err(|source| MycError::CreateDir { + path: parent.to_path_buf(), + source, + })?; + } + + fs::write(path, value).map_err(|source| MycError::PersistenceIo { + path: path.to_path_buf(), + source, + })?; + set_secret_permissions(path)?; + Ok(()) +} + +fn set_secret_permissions(path: &Path) -> Result<(), MycError> { + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + + let permissions = std::fs::Permissions::from_mode(0o600); + fs::set_permissions(path, permissions).map_err(|source| MycError::PersistenceIo { + path: path.to_path_buf(), + source, + })?; + } + Ok(()) +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize)] #[serde(rename_all = "snake_case")] pub enum MycManagedAccountSelectionState { @@ -674,7 +715,9 @@ impl MycIdentityProvider { pub fn load_identity(&self) -> Result<RadrootsIdentity, MycError> { match &self.backend { - MycIdentityProviderBackend::EncryptedFile { path } => load_encrypted_identity(path), + MycIdentityProviderBackend::EncryptedFile { path } => { + Ok(load_encrypted_identity(path)?) + } MycIdentityProviderBackend::PlaintextFile { path } => { RadrootsIdentity::load_from_path_auto(path).map_err(Into::into) } @@ -1019,7 +1062,7 @@ impl MycIdentityProvider { fn store_identity(&self, identity: &RadrootsIdentity) -> Result<(), MycError> { match &self.backend { MycIdentityProviderBackend::EncryptedFile { path } => { - store_encrypted_identity(path, identity) + Ok(store_encrypted_identity(path, identity)?) } MycIdentityProviderBackend::PlaintextFile { path } => { store_plaintext_identity(path, identity) @@ -1637,7 +1680,7 @@ mod tests { fn write_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn fixture_source(path: &Path) -> MycIdentitySourceSpec { @@ -1897,7 +1940,7 @@ mod tests { "1111111111111111111111111111111111111111111111111111111111111111", ) .expect("identity"); - crate::identity_storage::store_identity_profile(&profile_path, &identity) + crate::identity_files::store_identity_profile(&profile_path, &identity) .expect("save profile"); let account_id = identity.id(); diff --git a/src/discovery.rs b/src/discovery.rs @@ -2121,7 +2121,7 @@ mod tests { fn write_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn runtime() -> MycRuntime { diff --git a/src/identity_files.rs b/src/identity_files.rs @@ -0,0 +1,101 @@ +use std::path::{Path, PathBuf}; + +use radroots_identity::{ + IdentityError, RadrootsIdentity, RadrootsIdentityPublic, + encrypted_identity_wrapping_key_path as shared_encrypted_identity_wrapping_key_path, + load_encrypted_identity_with_key_slot, load_identity_profile as load_shared_identity_profile, + rotate_encrypted_identity_with_key_slot, store_encrypted_identity_with_key_slot, + store_identity_profile as store_shared_identity_profile, +}; + +const MYC_ENCRYPTED_IDENTITY_KEY_SLOT: &str = "myc_identity"; + +pub fn encrypted_identity_wrapping_key_path(path: impl AsRef<Path>) -> PathBuf { + shared_encrypted_identity_wrapping_key_path(path) +} + +pub fn store_encrypted_identity( + path: impl AsRef<Path>, + identity: &RadrootsIdentity, +) -> Result<(), IdentityError> { + store_encrypted_identity_with_key_slot(path, MYC_ENCRYPTED_IDENTITY_KEY_SLOT, identity) +} + +pub fn rotate_encrypted_identity(path: impl AsRef<Path>) -> Result<(), IdentityError> { + rotate_encrypted_identity_with_key_slot(path, MYC_ENCRYPTED_IDENTITY_KEY_SLOT) +} + +pub fn load_encrypted_identity(path: impl AsRef<Path>) -> Result<RadrootsIdentity, IdentityError> { + load_encrypted_identity_with_key_slot(path, MYC_ENCRYPTED_IDENTITY_KEY_SLOT) +} + +pub fn load_identity_profile( + path: impl AsRef<Path>, +) -> Result<RadrootsIdentityPublic, IdentityError> { + load_shared_identity_profile(path) +} + +pub fn store_identity_profile( + path: impl AsRef<Path>, + identity: &RadrootsIdentity, +) -> Result<(), IdentityError> { + store_shared_identity_profile(path, identity) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn encrypted_identity_round_trips() { + let temp = tempfile::tempdir().expect("tempdir"); + let path = temp.path().join("identity.enc.json"); + let identity = RadrootsIdentity::from_secret_key_str( + "1111111111111111111111111111111111111111111111111111111111111111", + ) + .expect("identity"); + + store_encrypted_identity(&path, &identity).expect("store encrypted identity"); + + let loaded = load_encrypted_identity(&path).expect("load encrypted identity"); + assert_eq!(loaded.id(), identity.id()); + assert_eq!(loaded.secret_key_hex(), identity.secret_key_hex()); + assert!(encrypted_identity_wrapping_key_path(&path).is_file()); + } + + #[test] + fn encrypted_identity_rotation_rewraps_key() { + let temp = tempfile::tempdir().expect("tempdir"); + let path = temp.path().join("identity.enc.json"); + let identity = RadrootsIdentity::from_secret_key_str( + "1111111111111111111111111111111111111111111111111111111111111111", + ) + .expect("identity"); + + store_encrypted_identity(&path, &identity).expect("store encrypted identity"); + let key_path = encrypted_identity_wrapping_key_path(&path); + let before = std::fs::read(&key_path).expect("key before"); + + rotate_encrypted_identity(&path).expect("rotate encrypted identity"); + + let after = std::fs::read(&key_path).expect("key after"); + assert_ne!(before, after); + let loaded = load_encrypted_identity(&path).expect("load rotated identity"); + assert_eq!(loaded.secret_key_hex(), identity.secret_key_hex()); + } + + #[test] + fn identity_profile_round_trips() { + let temp = tempfile::tempdir().expect("tempdir"); + let path = temp.path().join("profile.json"); + let identity = RadrootsIdentity::from_secret_key_str( + "1111111111111111111111111111111111111111111111111111111111111111", + ) + .expect("identity"); + + store_identity_profile(&path, &identity).expect("store profile"); + + let loaded = load_identity_profile(&path).expect("load profile"); + assert_eq!(loaded.id, identity.id()); + } +} diff --git a/src/identity_storage.rs b/src/identity_storage.rs @@ -1,287 +0,0 @@ -use std::fs; -use std::path::{Path, PathBuf}; - -use radroots_identity::{RadrootsIdentity, RadrootsIdentityFile, RadrootsIdentityPublic}; -use radroots_protected_store::{ - RadrootsProtectedFileKeySource, RadrootsProtectedStoreEnvelope, sidecar_path, -}; -use radroots_secret_vault::RadrootsSecretVaultAccessError; - -use crate::error::MycError; - -const ENCRYPTED_IDENTITY_KEY_SLOT: &str = "myc_identity"; -const ENCRYPTED_IDENTITY_KEY_SUFFIX: &str = ".key"; - -pub fn encrypted_identity_wrapping_key_path(path: impl AsRef<Path>) -> PathBuf { - sidecar_path(path, ENCRYPTED_IDENTITY_KEY_SUFFIX) -} - -pub fn store_encrypted_identity( - path: impl AsRef<Path>, - identity: &RadrootsIdentity, -) -> Result<(), MycError> { - let path = path.as_ref(); - if let Some(parent) = path.parent() - && !parent.as_os_str().is_empty() - { - fs::create_dir_all(parent).map_err(|source| MycError::CreateDir { - path: parent.to_path_buf(), - source, - })?; - } - - let payload = serde_json::to_vec(&identity.to_file())?; - let key_source = - RadrootsProtectedFileKeySource::from_sidecar_suffix(path, ENCRYPTED_IDENTITY_KEY_SUFFIX); - let envelope = RadrootsProtectedStoreEnvelope::seal_with_wrapped_key( - &key_source, - ENCRYPTED_IDENTITY_KEY_SLOT, - &payload, - ) - .map_err(|error| { - MycError::InvalidOperation(format!( - "failed to seal encrypted identity {}: {error}", - path.display() - )) - })?; - let encoded = envelope.encode_json().map_err(|error| { - MycError::InvalidOperation(format!( - "failed to encode encrypted identity {}: {error}", - path.display() - )) - })?; - fs::write(path, encoded).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - set_secret_permissions(path).map_err(secret_permission_error(path))?; - Ok(()) -} - -pub fn rotate_encrypted_identity(path: impl AsRef<Path>) -> Result<(), MycError> { - let path = path.as_ref(); - let identity = load_encrypted_identity(path)?; - let envelope_backup = fs::read(path).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - let key_path = encrypted_identity_wrapping_key_path(path); - let key_backup = if key_path.exists() { - Some( - fs::read(&key_path).map_err(|source| MycError::PersistenceIo { - path: key_path.clone(), - source, - })?, - ) - } else { - None - }; - - if key_path.exists() { - fs::remove_file(&key_path).map_err(|source| MycError::PersistenceIo { - path: key_path.clone(), - source, - })?; - } - - if let Err(error) = store_encrypted_identity(path, &identity) { - let _ = fs::write(path, &envelope_backup); - let _ = set_secret_permissions(path); - match key_backup { - Some(key_backup) => { - let _ = fs::write(&key_path, &key_backup); - let _ = set_secret_permissions(&key_path); - } - None => { - let _ = fs::remove_file(&key_path); - } - } - return Err(error); - } - - Ok(()) -} - -pub fn load_encrypted_identity(path: impl AsRef<Path>) -> Result<RadrootsIdentity, MycError> { - let path = path.as_ref(); - let encoded = fs::read(path).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - let key_source = - RadrootsProtectedFileKeySource::from_sidecar_suffix(path, ENCRYPTED_IDENTITY_KEY_SUFFIX); - let envelope = RadrootsProtectedStoreEnvelope::decode_json(&encoded).map_err(|error| { - MycError::InvalidOperation(format!( - "failed to decode encrypted identity {}: {error}", - path.display() - )) - })?; - let plaintext = envelope - .open_with_wrapped_key(&key_source) - .map_err(|error| { - MycError::InvalidOperation(format!( - "failed to open encrypted identity {}: {error}", - path.display() - )) - })?; - let file: RadrootsIdentityFile = serde_json::from_slice(&plaintext).map_err(|error| { - MycError::InvalidOperation(format!( - "failed to parse encrypted identity {}: {error}", - path.display() - )) - })?; - RadrootsIdentity::try_from(file).map_err(MycError::from) -} - -pub fn store_plaintext_identity( - path: impl AsRef<Path>, - identity: &RadrootsIdentity, -) -> Result<(), MycError> { - identity.save_json(path).map_err(MycError::from) -} - -pub fn store_identity_profile( - path: impl AsRef<Path>, - identity: &RadrootsIdentity, -) -> Result<(), MycError> { - let path = path.as_ref(); - if let Some(parent) = path.parent() - && !parent.as_os_str().is_empty() - { - fs::create_dir_all(parent).map_err(|source| MycError::CreateDir { - path: parent.to_path_buf(), - source, - })?; - } - - let encoded = serde_json::to_vec_pretty(&identity.to_public())?; - fs::write(path, encoded).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - set_secret_permissions(path).map_err(secret_permission_error(path))?; - Ok(()) -} - -pub fn load_identity_profile(path: impl AsRef<Path>) -> Result<RadrootsIdentityPublic, MycError> { - let path = path.as_ref(); - let encoded = fs::read(path).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - if let Ok(public_identity) = serde_json::from_slice::<RadrootsIdentityPublic>(&encoded) { - return Ok(public_identity); - } - RadrootsIdentity::load_from_path_auto(path) - .map(|identity| identity.to_public()) - .map_err(MycError::from) -} - -pub fn store_secret_text(path: impl AsRef<Path>, value: &str) -> Result<(), MycError> { - let path = path.as_ref(); - if let Some(parent) = path.parent() - && !parent.as_os_str().is_empty() - { - fs::create_dir_all(parent).map_err(|source| MycError::CreateDir { - path: parent.to_path_buf(), - source, - })?; - } - - fs::write(path, value).map_err(|source| MycError::PersistenceIo { - path: path.to_path_buf(), - source, - })?; - set_secret_permissions(path).map_err(secret_permission_error(path))?; - Ok(()) -} - -fn io_backend_error(source: std::io::Error) -> RadrootsSecretVaultAccessError { - RadrootsSecretVaultAccessError::Backend(source.to_string()) -} - -fn secret_permission_error( - path: &Path, -) -> impl FnOnce(RadrootsSecretVaultAccessError) -> MycError + '_ { - move |error| { - MycError::InvalidOperation(format!( - "failed to update permissions for {}: {error}", - path.display() - )) - } -} - -#[cfg(unix)] -fn set_secret_permissions(path: &Path) -> Result<(), RadrootsSecretVaultAccessError> { - use std::os::unix::fs::PermissionsExt; - - let permissions = std::fs::Permissions::from_mode(0o600); - fs::set_permissions(path, permissions).map_err(io_backend_error) -} - -#[cfg(not(unix))] -fn set_secret_permissions(_path: &Path) -> Result<(), RadrootsSecretVaultAccessError> { - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn encrypted_identity_round_trips() { - let temp = tempfile::tempdir().expect("tempdir"); - let path = temp.path().join("identity.enc.json"); - let identity = RadrootsIdentity::from_secret_key_str( - "1111111111111111111111111111111111111111111111111111111111111111", - ) - .expect("identity"); - - store_encrypted_identity(&path, &identity).expect("store encrypted identity"); - - let loaded = load_encrypted_identity(&path).expect("load encrypted identity"); - assert_eq!(loaded.id(), identity.id()); - assert_eq!(loaded.secret_key_hex(), identity.secret_key_hex()); - assert!(encrypted_identity_wrapping_key_path(&path).is_file()); - } - - #[test] - fn encrypted_identity_rotation_rewraps_key() { - let temp = tempfile::tempdir().expect("tempdir"); - let path = temp.path().join("identity.enc.json"); - let identity = RadrootsIdentity::from_secret_key_str( - "1111111111111111111111111111111111111111111111111111111111111111", - ) - .expect("identity"); - - store_encrypted_identity(&path, &identity).expect("store encrypted identity"); - let key_path = encrypted_identity_wrapping_key_path(&path); - let before = fs::read(&key_path).expect("key before"); - - rotate_encrypted_identity(&path).expect("rotate encrypted identity"); - - let after = fs::read(&key_path).expect("key after"); - assert_ne!(before, after); - let loaded = load_encrypted_identity(&path).expect("load rotated identity"); - assert_eq!(loaded.id(), identity.id()); - } - - #[test] - fn identity_profile_round_trips_as_public_projection() { - let temp = tempfile::tempdir().expect("tempdir"); - let path = temp.path().join("identity.profile.json"); - let identity = RadrootsIdentity::from_secret_key_str( - "1111111111111111111111111111111111111111111111111111111111111111", - ) - .expect("identity"); - - store_identity_profile(&path, &identity).expect("store profile"); - - let encoded = fs::read_to_string(&path).expect("read profile"); - assert!(!encoded.contains("secret_key")); - - let loaded = load_identity_profile(&path).expect("load profile"); - assert_eq!(loaded.id, identity.id()); - assert_eq!(loaded.public_key_hex, identity.public_key_hex()); - } -} diff --git a/src/lib.rs b/src/lib.rs @@ -9,7 +9,7 @@ pub mod control; pub mod custody; pub mod discovery; pub mod error; -pub mod identity_storage; +pub mod identity_files; pub mod logging; pub mod operability; pub mod outbox; diff --git a/src/operability/mod.rs b/src/operability/mod.rs @@ -1614,7 +1614,7 @@ mod tests { fn write_test_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } #[test] diff --git a/src/persistence.rs b/src/persistence.rs @@ -21,7 +21,7 @@ use crate::config::{ }; use crate::custody::MycIdentityProvider; use crate::error::MycError; -use crate::identity_storage::encrypted_identity_wrapping_key_path; +use crate::identity_files::encrypted_identity_wrapping_key_path; use crate::outbox::{ MycDeliveryOutboxKind, MycDeliveryOutboxRecord, MycDeliveryOutboxStatus, MycDeliveryOutboxStore, }; @@ -1454,7 +1454,7 @@ mod tests { fn write_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn identity(secret_key: &str) -> RadrootsIdentity { diff --git a/src/transport/nip46.rs b/src/transport/nip46.rs @@ -995,7 +995,7 @@ mod tests { fn write_identity(path: &std::path::Path, secret_key: &str) { let identity = radroots_identity::RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - crate::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + crate::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn runtime() -> MycRuntime { diff --git a/tests/discovery_cli.rs b/tests/discovery_cli.rs @@ -305,7 +305,7 @@ async fn accept_published_event( fn write_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn write_env_file( @@ -505,7 +505,7 @@ async fn discovery_sync_commands_work_through_the_cli() -> TestResult<()> { &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -619,7 +619,7 @@ async fn conflicted_refresh_requires_force_through_the_cli() -> TestResult<()> { &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -771,7 +771,7 @@ async fn refresh_reports_partial_repair_and_audit_summary_through_the_cli() -> T &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -872,7 +872,7 @@ async fn failed_refresh_publish_surfaces_attempt_id_and_exact_audit_lookup() -> &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -971,7 +971,7 @@ async fn discovery_repair_attempt_commands_correlate_multiple_refresh_runs() -> &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -1154,7 +1154,7 @@ async fn discovery_diff_surfaces_relay_provenance_through_the_cli() -> TestResul &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, @@ -1293,7 +1293,7 @@ async fn refresh_requires_force_when_a_discovery_relay_is_unavailable_through_th &user_identity_path, "2222222222222222222222222222222222222222222222222222222222222222", ); - myc::identity_storage::store_encrypted_identity(&app_identity_path, &app_identity)?; + myc::identity_files::store_encrypted_identity(&app_identity_path, &app_identity)?; write_env_file( &env_path, &state_dir, diff --git a/tests/logging_run.rs b/tests/logging_run.rs @@ -7,7 +7,7 @@ use std::time::{Duration, Instant}; fn write_test_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } fn wait_for_log_contents( diff --git a/tests/nip46_e2e.rs b/tests/nip46_e2e.rs @@ -495,7 +495,7 @@ impl MycTestRuntime { fn write_identity(path: &std::path::Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn identity(secret_key: &str) -> RadrootsIdentity { @@ -2880,7 +2880,7 @@ async fn explicit_nip89_publish_uses_app_identity_and_records_audit() -> TestRes let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3107,7 +3107,7 @@ async fn explicit_nip89_publish_retries_cleanly_after_rejection() -> TestResult< let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3353,7 +3353,7 @@ async fn diff_live_nip89_reports_matched_after_publish() -> TestResult<()> { let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3396,7 +3396,7 @@ async fn refresh_nip89_publishes_when_live_handler_is_missing() -> TestResult<() let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3479,7 +3479,7 @@ async fn refresh_nip89_repairs_missing_relays_without_republishing_matched_relay MycConnectionApproval::ExplicitUser, ); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3563,7 +3563,7 @@ async fn refresh_nip89_skips_when_live_handler_matches() -> TestResult<()> { let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3623,7 +3623,7 @@ async fn refresh_nip89_republishes_when_live_handler_drifted() -> TestResult<()> let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3700,7 +3700,7 @@ async fn refresh_nip89_repairs_drifted_relays_without_force_when_other_relays_ma MycConnectionApproval::ExplicitUser, ); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3791,7 +3791,7 @@ async fn refresh_nip89_reports_remaining_relays_after_mixed_targeted_repair() -> MycConnectionApproval::ExplicitUser, ); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3904,7 +3904,7 @@ async fn diff_live_nip89_reports_conflicted_when_live_groups_disagree() -> TestR let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -3945,7 +3945,7 @@ async fn diff_live_nip89_surfaces_relay_divergence_with_provenance() -> TestResu MycConnectionApproval::ExplicitUser, ); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -4050,7 +4050,7 @@ async fn refresh_nip89_requires_force_when_any_discovery_relay_is_unavailable() MycConnectionApproval::ExplicitUser, ); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery @@ -4129,7 +4129,7 @@ async fn refresh_nip89_requires_force_when_live_handler_is_conflicted() -> TestR let test_runtime = MycTestRuntime::new_with_discovery(relay.url(), MycConnectionApproval::ExplicitUser); let runtime = test_runtime.runtime; - let app_identity = myc::identity_storage::load_encrypted_identity( + let app_identity = myc::identity_files::load_encrypted_identity( runtime .config() .discovery diff --git a/tests/operability_cli.rs b/tests/operability_cli.rs @@ -12,7 +12,7 @@ use serde_json::{Value, json}; fn write_test_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } fn write_env_file(temp: &tempfile::TempDir) -> std::path::PathBuf { @@ -253,7 +253,7 @@ fn custody_export_import_and_rotate_nip49_for_encrypted_file_backend() { let env_path = write_env_file(&temp); let signer_path = temp.path().join("signer.json"); let export_path = temp.path().join("signer.ncryptsec"); - let key_path = myc::identity_storage::encrypted_identity_wrapping_key_path(&signer_path); + let key_path = myc::identity_files::encrypted_identity_wrapping_key_path(&signer_path); let export_output = Command::new(env!("CARGO_BIN_EXE_myc")) .env("MYC_TEST_PASSWORD", "correct horse battery staple") @@ -301,7 +301,7 @@ fn custody_export_import_and_rotate_nip49_for_encrypted_file_backend() { serde_json::from_slice(&import_output.stdout).expect("import-nip49 json"); assert_eq!(import_value["format"], "nip49"); assert_eq!(import_value["status"]["resolved"], true); - let restored = myc::identity_storage::load_encrypted_identity(&signer_path) + let restored = myc::identity_files::load_encrypted_identity(&signer_path) .expect("load restored encrypted identity"); assert_eq!( restored.id().to_string(), diff --git a/tests/operability_e2e.rs b/tests/operability_e2e.rs @@ -118,7 +118,7 @@ impl Drop for HangingRelay { fn write_test_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } fn signed_delivery_event(identity: &MycActiveIdentity, content: &str) -> nostr::Event { diff --git a/tests/operability_server.rs b/tests/operability_server.rs @@ -111,7 +111,7 @@ impl Drop for HangingRelay { fn write_test_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity from secret"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("write identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("write identity"); } fn free_loopback_addr() -> SocketAddr { diff --git a/tests/persistence_cli.rs b/tests/persistence_cli.rs @@ -12,7 +12,7 @@ use serde_json::Value; fn write_identity(path: &Path, secret_key: &str) { let identity = RadrootsIdentity::from_secret_key_str(secret_key).expect("identity"); - myc::identity_storage::store_encrypted_identity(path, &identity).expect("save identity"); + myc::identity_files::store_encrypted_identity(path, &identity).expect("save identity"); } fn copy_dir_recursive(source: &Path, destination: &Path) { @@ -339,13 +339,13 @@ fn persistence_restore_cli_restores_backup_and_verify_restore_passes() { assert!(restored_config.paths.signer_identity_path.is_file()); assert!(restored_config.paths.user_identity_path.is_file()); assert!( - myc::identity_storage::encrypted_identity_wrapping_key_path( + myc::identity_files::encrypted_identity_wrapping_key_path( &restored_config.paths.signer_identity_path ) .is_file() ); assert!( - myc::identity_storage::encrypted_identity_wrapping_key_path( + myc::identity_files::encrypted_identity_wrapping_key_path( &restored_config.paths.user_identity_path ) .is_file() @@ -479,10 +479,10 @@ fn persistence_verify_restore_cli_rejects_signer_identity_mismatch() { std::fs::copy(&sqlite_config.paths.user_identity_path, &restored_user) .expect("copy user identity"); std::fs::copy( - myc::identity_storage::encrypted_identity_wrapping_key_path( + myc::identity_files::encrypted_identity_wrapping_key_path( &sqlite_config.paths.user_identity_path, ), - myc::identity_storage::encrypted_identity_wrapping_key_path(&restored_user), + myc::identity_files::encrypted_identity_wrapping_key_path(&restored_user), ) .expect("copy user identity wrapping key");