diff --git a/novawallet.xcodeproj/project.pbxproj b/novawallet.xcodeproj/project.pbxproj index 5279c1e7d..ca5a829e0 100644 --- a/novawallet.xcodeproj/project.pbxproj +++ b/novawallet.xcodeproj/project.pbxproj @@ -1167,6 +1167,7 @@ 2D5A61CD2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A61CC2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift */; }; 2D5A61D02C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A61CF2C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift */; }; 2D5EBEB02D37D4090016AC4E /* WalletStorageCleanerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5EBEAF2D37D4090016AC4E /* WalletStorageCleanerFactory.swift */; }; + 2D5EBEB22D37DE440016AC4E /* DAppSettingsCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */; }; 2D5FC1A42C5220900013352B /* AccountVoteFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5FC1A32C5220900013352B /* AccountVoteFactory.swift */; }; 2D60C9BD2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D60C9BC2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift */; }; 2D60C9BF2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D60C9BE2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift */; }; @@ -6597,6 +6598,7 @@ 2D5A61CC2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworksEmptyPlaceholderView.swift; sourceTree = ""; }; 2D5A61CF2C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrateNetworksBanner.swift; sourceTree = ""; }; 2D5EBEAF2D37D4090016AC4E /* WalletStorageCleanerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageCleanerFactory.swift; sourceTree = ""; }; + 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppSettingsCleaner.swift; sourceTree = ""; }; 2D5FC1A32C5220900013352B /* AccountVoteFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountVoteFactory.swift; sourceTree = ""; }; 2D60C9BC2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalCardPresentationConfiguration.swift; sourceTree = ""; }; 2D60C9BE2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalCardPresentationStyle.swift; sourceTree = ""; }; @@ -13319,6 +13321,7 @@ isa = PBXGroup; children = ( 2D20F1C62D364938003E9CF2 /* WalletBrowserStateCleaner.swift */, + 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */, ); path = Cleaners; sourceTree = ""; @@ -28365,6 +28368,7 @@ 8498430926592E5D006BBB9F /* CrowdloansViewModel.swift in Sources */, 8482F62D280C5B040006C3A0 /* DAppsAuthSettingsWalletCell.swift in Sources */, 5DDD2206DF795CF205610455 /* AccountExportPasswordPresenter.swift in Sources */, + 2D5EBEB22D37DE440016AC4E /* DAppSettingsCleaner.swift in Sources */, 800FCAF66DC8A24020D16A9C /* AccountExportPasswordInteractor.swift in Sources */, 841E553A282D23AE00C8438F /* StakingRelaychainWireframe.swift in Sources */, 0C3205BB2A8679F0002EB914 /* EvmGasPriceProvider.swift in Sources */, diff --git a/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift new file mode 100644 index 000000000..5525571b8 --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift @@ -0,0 +1,42 @@ +import Foundation +import Operation_iOS + +final class DAppSettingsCleaner { + private let authorizedDAppRepository: AnyDataProviderRepository + + init(authorizedDAppRepository: AnyDataProviderRepository) { + self.authorizedDAppRepository = authorizedDAppRepository + } +} + +// MARK: WalletStorageCleaning + +extension DAppSettingsCleaner: WalletStorageCleaning { + func cleanStorage( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper { + let fetchOptions = RepositoryFetchOptions() + let fetchSettingsOperation = authorizedDAppRepository.fetchAllOperation(with: fetchOptions) + + let deletionBlock: () throws -> [String] = { + let removedWallets = Set(try removedItems().map(\.metaId)) + let dappSettingsIds = try fetchSettingsOperation.extractNoCancellableResultData() + .compactMap(\.metaId) + .filter { removedWallets.contains($0) } + + return dappSettingsIds + } + + let removeSettingsOperation = authorizedDAppRepository.saveOperation( + { [] }, + deletionBlock + ) + + removeSettingsOperation.addDependency(fetchSettingsOperation) + + return CompoundOperationWrapper( + targetOperation: removeSettingsOperation, + dependencies: [fetchSettingsOperation] + ) + } +} diff --git a/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift b/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift index 64fc10163..aaf341725 100644 --- a/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift +++ b/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift @@ -1,13 +1,16 @@ import Foundation +import Operation_iOS final class WalletStorageCleanerFactory { static func createWalletStorageCleaner(using operationQueue: OperationQueue) -> WalletStorageCleaning { let browserStateCleaner = createBrowserStateCleaner(using: operationQueue) + let dAppSettingsCleaner = createDAppSettingsCleaner() // Add every cleaner to the array // in the same order it should get called let cleaners = [ - browserStateCleaner + browserStateCleaner, + dAppSettingsCleaner ] let mainCleaner = RemovedWalletStorageCleaner(cleanersCascade: cleaners) @@ -29,4 +32,20 @@ final class WalletStorageCleanerFactory { return browserStateCleaner } + + private static func createDAppSettingsCleaner() -> WalletStorageCleaning { + let mapper = DAppSettingsMapper() + let storageFacade = UserDataStorageFacade.shared + + let repository = storageFacade.createRepository( + filter: nil, + sortDescriptors: [], + mapper: AnyCoreDataMapper(mapper) + ) + let authorizedDAppRepository = AnyDataProviderRepository(repository) + + let dappSettingsCleaner = DAppSettingsCleaner(authorizedDAppRepository: authorizedDAppRepository) + + return dappSettingsCleaner + } } diff --git a/novawallet/Common/Storage/WalletsUpdateMediator.swift b/novawallet/Common/Storage/WalletsUpdateMediator.swift index 9d2100ef4..471430ee0 100644 --- a/novawallet/Common/Storage/WalletsUpdateMediator.swift +++ b/novawallet/Common/Storage/WalletsUpdateMediator.swift @@ -213,7 +213,7 @@ extension WalletUpdateMediator: WalletUpdateMediating { newSelectedWalletOperation.addDependency(proxiedsRemovalOperation) - var walletsStateCleaningWrapper = removedWalletsCleaner.cleanStorage { + let walletsStateCleaningWrapper = removedWalletsCleaner.cleanStorage { let changesResult = try newSelectedWalletOperation.extractNoCancellableResultData() return changesResult.changes.removedItems.map(\.info) @@ -231,17 +231,18 @@ extension WalletUpdateMediator: WalletUpdateMediating { return changesResult.changes.removedItems.map(\.identifier) }) - saveOperation.addDependency(walletsStateCleaningWrapper.targetOperation) + saveOperation.addDependency(newSelectedWalletOperation) let selectedWalletUpdateOperation = selectedWalletUpdateOperation( in: selectedWalletSettings, dependingOn: newSelectedWalletOperation ) - selectedWalletUpdateOperation.addDependency(saveOperation) + selectedWalletUpdateOperation.addDependency(newSelectedWalletOperation) let resultOperation = ClosureOperation { try saveOperation.extractNoCancellableResultData() + try walletsStateCleaningWrapper.targetOperation.extractNoCancellableResultData() let isWalletSwitched = try selectedWalletUpdateOperation.extractNoCancellableResultData() let currentWallet = try newSelectedWalletOperation.extractNoCancellableResultData().selectedWallet @@ -249,6 +250,7 @@ extension WalletUpdateMediator: WalletUpdateMediating { } resultOperation.addDependency(saveOperation) + resultOperation.addDependency(walletsStateCleaningWrapper.targetOperation) resultOperation.addDependency(selectedWalletUpdateOperation) resultOperation.addDependency(newSelectedWalletOperation) diff --git a/novawalletTests/Helper/WalletStorageCleanerFactory.swift b/novawalletTests/Helper/WalletStorageCleanerFactory.swift index 54a570ef6..258052f67 100644 --- a/novawalletTests/Helper/WalletStorageCleanerFactory.swift +++ b/novawalletTests/Helper/WalletStorageCleanerFactory.swift @@ -6,6 +6,26 @@ extension WalletStorageCleanerFactory { static func createTestCleaner( operationQueue: OperationQueue, storageFacade: UserDataStorageTestFacade + ) -> WalletStorageCleaning { + let browserStateCleaner = createBrowserStateCleaner( + operationQueue: operationQueue, + storageFacade: storageFacade + ) + let dAppSettingsCleaner = createDAppSettingsCleaner(storageFacade: storageFacade) + + let cleaners = [ + browserStateCleaner, + dAppSettingsCleaner + ] + + let mainCleaner = RemovedWalletStorageCleaner(cleanersCascade: cleaners) + + return mainCleaner + } + + private static func createBrowserStateCleaner( + operationQueue: OperationQueue, + storageFacade: StorageFacadeProtocol ) -> WalletStorageCleaning { let mapper = DAppBrowserTabMapper() @@ -43,12 +63,27 @@ extension WalletStorageCleanerFactory { logger: logger ) - let walletStorageCleaner = WalletBrowserStateCleaner( + let browserStateCleaner = WalletBrowserStateCleaner( browserTabManager: tabManager, webViewPoolEraser: WebViewPool.shared, operationQueue: operationQueue ) - return walletStorageCleaner + return browserStateCleaner + } + + private static func createDAppSettingsCleaner(storageFacade: StorageFacadeProtocol) -> WalletStorageCleaning { + let mapper = DAppSettingsMapper() + + let repository = storageFacade.createRepository( + filter: nil, + sortDescriptors: [], + mapper: AnyCoreDataMapper(mapper) + ) + let authorizedDAppRepository = AnyDataProviderRepository(repository) + + let dappSettingsCleaner = DAppSettingsCleaner(authorizedDAppRepository: authorizedDAppRepository) + + return dappSettingsCleaner } }