diff --git a/src/sdk/Angor.Sdk/Wallet/Infrastructure/Impl/WalletAppService.cs b/src/sdk/Angor.Sdk/Wallet/Infrastructure/Impl/WalletAppService.cs index db2afb9d0..3b3c77f40 100644 --- a/src/sdk/Angor.Sdk/Wallet/Infrastructure/Impl/WalletAppService.cs +++ b/src/sdk/Angor.Sdk/Wallet/Infrastructure/Impl/WalletAppService.cs @@ -1,4 +1,8 @@ using Angor.Sdk.Common; +using Angor.Data.Documents.Interfaces; +using Angor.Sdk.Funding.Founder.Domain; +using Angor.Sdk.Funding.Investor.Domain; +using Angor.Sdk.Funding.Shared; using Angor.Sdk.Wallet.Application; using Angor.Sdk.Wallet.Domain; using Angor.Sdk.Wallet.Infrastructure.History; @@ -7,6 +11,7 @@ using Angor.Shared.Models; using Blockcore.NBitcoin.BIP39; using CSharpFunctionalExtensions; +using Microsoft.Extensions.Logging; namespace Angor.Sdk.Wallet.Infrastructure.Impl; @@ -18,7 +23,12 @@ public class WalletAppService( IPsbtOperations psbtOperations, ITransactionHistory transactionHistory, IHttpClientFactory httpClientFactory, - IWalletAccountBalanceService accountBalanceService) + IWalletAccountBalanceService accountBalanceService, + IGenericDocumentCollection derivedProjectKeys, + IGenericDocumentCollection founderProjects, + IGenericDocumentCollection investmentRecords, + IGenericDocumentCollection investmentHandshakes, + ILogger logger) : IWalletAppService { //public static readonly WalletId SingleWalletId = new("8E3C5250-4E26-4A13-8075-0A189AEAF793"); @@ -239,17 +249,16 @@ public async Task DeleteWallet(WalletId walletId) } var wallets = walletsResult.Value.ToList(); - var wallet = wallets.FirstOrDefault(w => w.Id == walletId.Value); - - if (wallet == null) - return Result.Failure("Wallet not found"); - - var deleteAccountResult = await accountBalanceService.DeleteAccountBalanceInfoAsync(walletId); - - if (deleteAccountResult.IsFailure) - return Result.Failure(deleteAccountResult.Error); - + + if (wallet is null) + { + var cleanupMissing = await DeleteRelatedDocumentsAsync(walletId); + return cleanupMissing.IsSuccess + ? Result.Failure("Wallet not found") + : cleanupMissing; + } + wallets.Remove(wallet); var saveResult = await walletStore.SaveAll(wallets); @@ -260,6 +269,76 @@ public async Task DeleteWallet(WalletId walletId) sensitiveWalletDataProvider.RemoveSensitiveData(walletId); + var cleanup = await DeleteRelatedDocumentsAsync(walletId); + if (cleanup.IsFailure) + { + logger.LogWarning("Wallet {WalletId} was deleted from wallet storage, but related document cleanup failed: {Error}", walletId.Value, cleanup.Error); + } + + return Result.Success(); + } + + // Removes related documents for wallet + private async Task DeleteRelatedDocumentsAsync(WalletId walletId) + { + var errors = new System.Collections.Generic.List(); + + var delDerived = await derivedProjectKeys.DeleteAsync(walletId.Value); + if (delDerived.IsFailure) + { + var error = $"Failed to delete DerivedProjectKeys {delDerived.Error}"; + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, error); + errors.Add(error); + } + + var delFounder = await founderProjects.DeleteAsync(walletId.Value); + if (delFounder.IsFailure) + { + var error = $"Failed to delete FounderProjectsDocument {delFounder.Error}"; + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, error); + errors.Add(error); + } + + var delInvestments = await investmentRecords.DeleteAsync(walletId.Value); + if (delInvestments.IsFailure) + { + var error = $"Failed to delete InvestmentRecordsDocument {delInvestments.Error}"; + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, error); + errors.Add(error); + } + + var handshakes = await investmentHandshakes.FindAsync(h => h.WalletId == walletId.Value); + if (handshakes.IsFailure) + { + var error = $"Failed to query InvestmentHandshakes {handshakes.Error}"; + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, error); + errors.Add(error); + } + else + { + foreach (var hs in handshakes.Value) + { + var delHs = await investmentHandshakes.DeleteAsync(hs.Id); + if (delHs.IsFailure) + { + var error = $"Failed to delete InvestmentHandshake {hs.Id}: {delHs.Error}"; + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, error); + errors.Add(error); + } + } + } + + var deleteAccountResult = await accountBalanceService.DeleteAccountBalanceInfoAsync(walletId); + if (deleteAccountResult.IsFailure) + { + logger.LogWarning("Wallet cleanup issue for {WalletId}: {Error}", walletId.Value, deleteAccountResult.Error); + errors.Add(deleteAccountResult.Error); + } + + if (errors.Count > 0) + { + return Result.Failure(string.Join("; ", errors)); + } return Result.Success(); }