From bc65c877affded3ac6b75a7bd822a70103ea4965 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Tue, 12 May 2026 17:17:58 -0300 Subject: [PATCH] fix private shared account preparation --- integration_tests/tests/shared_accounts.rs | 5 ++++- key_protocol/src/key_protocol_core/mod.rs | 1 + wallet/src/lib.rs | 13 +++++++++++-- wallet/src/privacy_preserving_tx.rs | 18 ++++++------------ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/integration_tests/tests/shared_accounts.rs b/integration_tests/tests/shared_accounts.rs index c5d937e0..80ea1bd4 100644 --- a/integration_tests/tests/shared_accounts.rs +++ b/integration_tests/tests/shared_accounts.rs @@ -155,7 +155,6 @@ async fn group_invite_join_key_agreement() -> Result<()> { /// Fund a shared account from a public account via auth-transfer, then sync. /// TODO: Requires auth-transfer init to work with shared accounts (authorization flow). #[test] -#[ignore = "Requires auth-transfer init to work with shared accounts (authorization flow)"] async fn fund_shared_account_from_public() -> Result<()> { let mut ctx = TestContext::new().await?; @@ -190,6 +189,10 @@ async fn fund_shared_account_from_public() -> Result<()> { tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; + // Sync private accounts + let command = Command::Account(AccountSubcommand::SyncPrivate); + wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?; + // Fund from a public account let from_public = ctx.existing_public_accounts()[0]; let command = Command::AuthTransfer(AuthTransferSubcommand::Send { diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index e973655e..b228e3ef 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -178,6 +178,7 @@ impl NSSAUserData { } /// Returns the key chain and account data for the given private account ID. + /// Does not cover shared private accounts — use `shared_private_account` for those. #[must_use] pub fn get_private_account( &self, diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 24ac19b9..db3e320d 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -505,8 +505,17 @@ impl WalletCore { #[must_use] pub fn get_private_account_commitment(&self, account_id: AccountId) -> Option { - let (_keys, account, _identifier) = - self.storage.user_data.get_private_account(account_id)?; + let account = self + .storage + .user_data + .get_private_account(account_id) + .map(|(_keys, account, _identifier)| account) + .or_else(|| { + self.storage + .user_data + .shared_private_account(&account_id) + .map(|entry| entry.account.clone()) + })?; Some(Commitment::new(&account_id, &account)) } diff --git a/wallet/src/privacy_preserving_tx.rs b/wallet/src/privacy_preserving_tx.rs index 603fdd0c..6d118c0c 100644 --- a/wallet/src/privacy_preserving_tx.rs +++ b/wallet/src/privacy_preserving_tx.rs @@ -381,24 +381,18 @@ async fn private_shared_acc_preparation( .map(|e| e.account.clone()) .unwrap_or_default(); - let exists = acc != nssa_core::account::Account::default(); - let pre_state = AccountWithMetadata::new(acc, exists, account_id); + let pre_state = AccountWithMetadata::new(acc, true, account_id); - let proof = if exists { - wallet - .check_private_account_initialized(account_id) - .await - .unwrap_or(None) - } else { - None - }; + let proof = wallet + .check_private_account_initialized(account_id) + .await + .unwrap_or(None); let eph_holder = EphemeralKeyHolder::new(&npk); let ssk = eph_holder.calculate_shared_secret_sender(&vpk); let epk = eph_holder.generate_ephemeral_public_key(); - Ok(AccountPreparedData { - nsk: exists.then_some(nsk), + nsk: Some(nsk), npk, identifier, vpk,