diff --git a/Features/Assets/Package.resolved b/Features/Assets/Package.resolved deleted file mode 100644 index cf928ba06..000000000 --- a/Features/Assets/Package.resolved +++ /dev/null @@ -1,50 +0,0 @@ -{ - "originHash" : "00c1c6d304380587522e3db87e31443c482e0ed0f776e0d31235ee16e7345b60", - "pins" : [ - { - "identity" : "bigint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/gemwalletcom/BigInt.git", - "state" : { - "revision" : "e07e00fa1fd435143a2dcf8b7eec9a7710b2fdfe", - "version" : "5.7.0" - } - }, - { - "identity" : "grdb.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/groue/GRDB.swift.git", - "state" : { - "revision" : "aa0079aeb82a4bf00324561a40bffe68c6fe1c26", - "version" : "7.9.0" - } - }, - { - "identity" : "grdbquery", - "kind" : "remoteSourceControl", - "location" : "https://github.com/groue/GRDBQuery.git", - "state" : { - "revision" : "540dc48e86af2972b4f1815616aa1ed8ac97845a", - "version" : "0.11.0" - } - }, - { - "identity" : "reown-swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/gemwalletcom/reown-swift.git", - "state" : { - "revision" : "e902bbb0de2208777c8e9c09591f4bdd39fc13ae" - } - }, - { - "identity" : "starscream", - "kind" : "remoteSourceControl", - "location" : "https://github.com/gemwalletcom/Starscream.git", - "state" : { - "revision" : "a063fda2b8145a231953c20e7a646be254365396", - "version" : "3.1.2" - } - } - ], - "version" : 3 -} diff --git a/Features/Assets/Package.swift b/Features/Assets/Package.swift index 179844416..9b6bb9475 100644 --- a/Features/Assets/Package.swift +++ b/Features/Assets/Package.swift @@ -53,6 +53,7 @@ let package = Package( .product(name: "AssetsService", package: "FeatureServices"), .product(name: "TransactionsService", package: "FeatureServices"), .product(name: "WalletsService", package: "FeatureServices"), + .product(name: "BalanceService", package: "FeatureServices"), .product(name: "PriceService", package: "FeatureServices"), .product(name: "BannerService", package: "FeatureServices"), .product(name: "ChainService", package: "ChainServices"), @@ -79,6 +80,7 @@ let package = Package( .product(name: "PrimitivesTestKit", package: "Primitives"), .product(name: "WalletsServiceTestKit", package: "FeatureServices"), .product(name: "AssetsServiceTestKit", package: "FeatureServices"), + .product(name: "BalanceServiceTestKit", package: "FeatureServices"), .product(name: "TransactionsServiceTestKit", package: "FeatureServices"), .product(name: "PriceServiceTestKit", package: "FeatureServices"), .product(name: "PriceAlertServiceTestKit", package: "FeatureServices"), diff --git a/Features/Assets/Sources/ViewModels/AssetSceneViewModel.swift b/Features/Assets/Sources/ViewModels/AssetSceneViewModel.swift index ad47da965..fe7b29cd5 100644 --- a/Features/Assets/Sources/ViewModels/AssetSceneViewModel.swift +++ b/Features/Assets/Sources/ViewModels/AssetSceneViewModel.swift @@ -13,6 +13,7 @@ import ExplorerService import AssetsService import TransactionsService import WalletsService +import BalanceService import PriceService import BannerService import Formatters @@ -21,7 +22,9 @@ import Store @Observable @MainActor public final class AssetSceneViewModel: Sendable { - private let walletsService: WalletsService + private let assetsEnabler: any AssetsEnabler + private let assetSyncService: any AssetSyncServiceable + private let balanceService: BalanceService private let assetsService: AssetsService private let transactionsService: TransactionsService private let priceObserverService: PriceObserverService @@ -50,7 +53,9 @@ public final class AssetSceneViewModel: Sendable { private var wallet: Wallet { walletModel.wallet } public init( - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, + assetSyncService: any AssetSyncServiceable, + balanceService: BalanceService, assetsService: AssetsService, transactionsService: TransactionsService, priceObserverService: PriceObserverService, @@ -59,7 +64,9 @@ public final class AssetSceneViewModel: Sendable { input: AssetSceneInput, isPresentingSelectedAssetInput: Binding ) { - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler + self.assetSyncService = assetSyncService + self.balanceService = balanceService self.assetsService = assetsService self.transactionsService = transactionsService self.priceObserverService = priceObserverService @@ -340,7 +347,7 @@ extension AssetSceneViewModel { do { let pinned = !assetData.metadata.isPinned isPresentingToastMessage = .pin(asset.name, pinned: pinned) - try walletsService.setPinned(pinned, walletId: wallet.walletId, assetId: asset.id) + try balanceService.setPinned(pinned, walletId: wallet.walletId, assetId: asset.id) if !assetData.metadata.isBalanceEnabled { onSelectEnable() } @@ -353,7 +360,7 @@ extension AssetSceneViewModel { Task { let enabled = !assetData.metadata.isBalanceEnabled do { - try await walletsService.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: enabled) + try await assetsEnabler.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: enabled) isPresentingToastMessage = .showAsset(visible: enabled) } catch { debugLog("onSelectEnable error: \(error)") @@ -445,7 +452,7 @@ extension AssetSceneViewModel { private func updateWallet() async { do { - async let updateAsset: () = try walletsService.updateAssets( + async let updateAsset: () = try assetSyncService.updateAssets( walletId: walletModel.wallet.walletId, assetIds: [assetModel.asset.id] ) diff --git a/Features/Assets/Sources/ViewModels/SelectAssetViewModel.swift b/Features/Assets/Sources/ViewModels/SelectAssetViewModel.swift index c3ca00a94..b193abd76 100644 --- a/Features/Assets/Sources/ViewModels/SelectAssetViewModel.swift +++ b/Features/Assets/Sources/ViewModels/SelectAssetViewModel.swift @@ -20,7 +20,7 @@ public final class SelectAssetViewModel { let preferences: Preferences let selectType: SelectAssetType let searchService: AssetSearchService - let walletsService: WalletsService + let assetsEnabler: any AssetsEnabler let priceAlertService: PriceAlertService let activityService: ActivityService @@ -51,7 +51,7 @@ public final class SelectAssetViewModel { wallet: Wallet, selectType: SelectAssetType, searchService: AssetSearchService, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, priceAlertService: PriceAlertService, activityService: ActivityService, selectAssetAction: AssetAction = .none @@ -60,7 +60,7 @@ public final class SelectAssetViewModel { self.wallet = wallet self.selectType = selectType self.searchService = searchService - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler self.priceAlertService = priceAlertService self.activityService = activityService self.onSelectAssetAction = selectAssetAction @@ -239,7 +239,7 @@ extension SelectAssetViewModel { switch selectType { case .manage: do { - try await walletsService.enableAssets(walletId: wallet.walletId, assetIds: [assetId], enabled: enabled) + try await assetsEnabler.enableAssets(walletId: wallet.walletId, assetIds: [assetId], enabled: enabled) } catch { debugLog("SelectAssetViewModel handleAction error: \(error)") } diff --git a/Features/Assets/TestKit/SelectAssetViewModel+AssetsTestKit.swift b/Features/Assets/TestKit/SelectAssetViewModel+AssetsTestKit.swift index 9e9e80199..b61bfce24 100644 --- a/Features/Assets/TestKit/SelectAssetViewModel+AssetsTestKit.swift +++ b/Features/Assets/TestKit/SelectAssetViewModel+AssetsTestKit.swift @@ -24,7 +24,7 @@ extension SelectAssetViewModel { wallet: wallet, selectType: selectType, searchService: .mock(), - walletsService: .mock(), + assetsEnabler: .mock(), priceAlertService: .mock(), activityService: .mock() ) diff --git a/Features/Assets/Tests/AssetsTests/AssetSceneViewModelTests.swift b/Features/Assets/Tests/AssetsTests/AssetSceneViewModelTests.swift index 353feb9f3..fb26b34d4 100644 --- a/Features/Assets/Tests/AssetsTests/AssetSceneViewModelTests.swift +++ b/Features/Assets/Tests/AssetsTests/AssetSceneViewModelTests.swift @@ -6,6 +6,7 @@ import Primitives import PrimitivesTestKit import WalletsServiceTestKit import AssetsServiceTestKit +import BalanceServiceTestKit import TransactionsServiceTestKit import PriceServiceTestKit import PriceAlertServiceTestKit @@ -60,7 +61,9 @@ struct AssetSceneViewModelTests { extension AssetSceneViewModel { static func mock(_ assetData: AssetData = AssetData.mock()) -> AssetSceneViewModel { let model = AssetSceneViewModel( - walletsService: .mock(), + assetsEnabler: .mock(), + assetSyncService: .mock(), + balanceService: .mock(), assetsService: .mock(), transactionsService: .mock(), priceObserverService: .mock(), diff --git a/Features/Settings/Package.swift b/Features/Settings/Package.swift index e12fab53b..fdf694edc 100644 --- a/Features/Settings/Package.swift +++ b/Features/Settings/Package.swift @@ -42,6 +42,7 @@ let package = Package( "GemstonePrimitives", "Keystore", .product(name: "WalletsService", package: "FeatureServices"), + .product(name: "WalletSessionService", package: "FeatureServices"), .product(name: "BannerService", package: "FeatureServices"), .product(name: "StakeService", package: "ChainServices"), .product(name: "AssetsService", package: "FeatureServices"), diff --git a/Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift b/Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift index 8b033a223..cc3722117 100644 --- a/Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift +++ b/Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift @@ -8,7 +8,7 @@ import Primitives import Localization import Style import Preferences -import WalletsService +import WalletSessionService import PrimitivesComponents import Components @@ -16,16 +16,16 @@ import Components @MainActor public final class SettingsViewModel { private let walletId: WalletId - private let walletsService: WalletsService + private let walletSessionService: WalletSessionService private let observablePrefereces: ObservablePreferences public init( walletId: WalletId, - walletsService: WalletsService, + walletSessionService: WalletSessionService, observablePrefereces: ObservablePreferences ) { self.walletId = walletId - self.walletsService = walletsService + self.walletSessionService = walletSessionService self.observablePrefereces = observablePrefereces } @@ -37,7 +37,7 @@ public final class SettingsViewModel { var walletsTitle: String { Localized.Wallets.title } var walletsValue: String { - let count = (try? walletsService.walletsCount()) ?? .zero + let count = (try? walletSessionService.walletsCount()) ?? .zero return "\(count)" } var walletsImage: AssetImage { AssetImage.image(Images.Settings.wallets) } @@ -59,7 +59,7 @@ public final class SettingsViewModel { var rewardsTitle: String { Localized.Rewards.title } var rewardsImage: AssetImage { AssetImage.image(Images.Settings.gem) } - var showsRewards: Bool { walletsService.hasMulticoinWallet() } + var showsRewards: Bool { walletSessionService.hasMulticoinWallet() } private let links: [SocialUrl] = [.x, .discord, .telegram, .gitHub, .youTube] var linksViewModel: SocialLinksViewModel { diff --git a/Features/Swap/Package.swift b/Features/Swap/Package.swift index 2a43e64b6..875244159 100644 --- a/Features/Swap/Package.swift +++ b/Features/Swap/Package.swift @@ -63,6 +63,7 @@ let package = Package( .product(name: "ChainServiceTestKit", package: "ChainServices"), .product(name: "GemAPITestKit", package: "GemAPI"), .product(name: "StoreTestKit", package: "Store"), + .product(name: "PreferencesTestKit", package: "Preferences"), "Swap" ] ) diff --git a/Features/Swap/Sources/ViewModels/SwapSceneViewModel.swift b/Features/Swap/Sources/ViewModels/SwapSceneViewModel.swift index 8d6582336..e836b7d65 100644 --- a/Features/Swap/Sources/ViewModels/SwapSceneViewModel.swift +++ b/Features/Swap/Sources/ViewModels/SwapSceneViewModel.swift @@ -23,7 +23,7 @@ public final class SwapSceneViewModel { static let inputPercentSuggestions = [25, 50, 100].map { PercentageSuggestion(value: $0) } public let wallet: Wallet - public let walletsService: WalletsService + public let assetSyncService: any AssetSyncServiceable public var swapState: SwapState = .init() public var isPresentingInfoSheet: SwapSheetType? @@ -53,7 +53,7 @@ public final class SwapSceneViewModel { public init( preferences: Preferences = Preferences.standard, input: SwapInput, - walletsService: WalletsService, + assetSyncService: any AssetSyncServiceable, swapQuotesProvider: SwapQuotesProvidable, swapQuoteDataProvider: any SwapQuoteDataProvidable, onSwap: TransferDataAction = nil @@ -63,7 +63,7 @@ public final class SwapSceneViewModel { self.pairSelectorModel = pairSelectorModel self.preferences = preferences self.wallet = input.wallet - self.walletsService = walletsService + self.assetSyncService = assetSyncService self.fromAssetQuery = ObservableQuery(AssetRequestOptional(walletId: input.wallet.walletId, assetId: pairSelectorModel.fromAssetId), initialValue: nil) self.toAssetQuery = ObservableQuery(AssetRequestOptional(walletId: input.wallet.walletId, assetId: pairSelectorModel.toAssetId), initialValue: nil) @@ -302,7 +302,7 @@ extension SwapSceneViewModel { Task { let assetIds = [fromAsset?.asset.id, toAsset?.asset.id].compactMap { $0 } - try await walletsService.addPrices(assetIds: assetIds) + try await assetSyncService.addPrices(assetIds: assetIds) } } @@ -363,7 +363,7 @@ extension SwapSceneViewModel { private func performUpdate(for assetIds: [AssetId]) async { do { - try await walletsService.updateAssets( + try await assetSyncService.updateAssets( walletId: wallet.walletId, assetIds: assetIds ) diff --git a/Features/Swap/Tests/SwapTests/SwapSceneViewModelTests.swift b/Features/Swap/Tests/SwapTests/SwapSceneViewModelTests.swift index a0f3d689b..0bf8e2df8 100644 --- a/Features/Swap/Tests/SwapTests/SwapSceneViewModelTests.swift +++ b/Features/Swap/Tests/SwapTests/SwapSceneViewModelTests.swift @@ -13,6 +13,7 @@ import enum Gemstone.SwapperError import Keystore import KeystoreTestKit import Primitives +import PreferencesTestKit @testable import Swap @testable import Store @@ -150,7 +151,7 @@ extension SwapSceneViewModel { wallet: .mock(accounts: [.mock(chain: .ethereum)]), pairSelector: SwapPairSelectorViewModel(fromAssetId: .mockEthereum(), toAssetId: nil) ), - walletsService: .mock(), + assetSyncService: .mock(), swapQuotesProvider: SwapQuotesProvider(swapService: .mock(swapper: swapper)), swapQuoteDataProvider: SwapQuoteDataProvider(keystore: LocalKeystore.mock(), swapService: .mock(swapper: swapper)) ) diff --git a/Features/Transfer/Sources/Services/ConfirmServiceFactory.swift b/Features/Transfer/Sources/Services/ConfirmServiceFactory.swift index 5dfc2eb16..5174e7a70 100644 --- a/Features/Transfer/Sources/Services/ConfirmServiceFactory.swift +++ b/Features/Transfer/Sources/Services/ConfirmServiceFactory.swift @@ -19,7 +19,7 @@ public struct ConfirmServiceFactory { public static func create( keystore: any Keystore, chainServiceFactory: any ChainServiceFactorable, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, scanService: ScanService, balanceService: BalanceService, priceService: PriceService, @@ -44,7 +44,8 @@ public struct ConfirmServiceFactory { transferExecutor: TransferExecutor( signer: TransactionSigner(keystore: keystore), chainService: chainService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, + balanceService: balanceService, transactionStateService: transactionStateService ), keystore: keystore, diff --git a/Features/Transfer/Sources/Services/TransferExecutor.swift b/Features/Transfer/Sources/Services/TransferExecutor.swift index f2239daf8..508048213 100644 --- a/Features/Transfer/Sources/Services/TransferExecutor.swift +++ b/Features/Transfer/Sources/Services/TransferExecutor.swift @@ -1,6 +1,7 @@ // Copyright (c). Gem Wallet. All rights reserved. import Blockchain +import BalanceService import Foundation import Primitives import Signer @@ -14,18 +15,21 @@ public protocol TransferExecutable: Sendable { public struct TransferExecutor: TransferExecutable { private let signer: any TransactionSigneable private let chainService: any ChainServiceable - private let walletsService: WalletsService + private let assetsEnabler: any AssetsEnabler + private let balanceService: BalanceService private let transactionStateService: TransactionStateService public init( signer: any TransactionSigneable, chainService: any ChainServiceable, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, + balanceService: BalanceService, transactionStateService: TransactionStateService ) { self.signer = signer self.chainService = chainService - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler + self.balanceService = balanceService self.transactionStateService = transactionStateService } @@ -67,10 +71,9 @@ public struct TransferExecutor: TransferExecutable { try transactionStateService.addTransactions(wallet: input.wallet, transactions: transactions) Task { - let walletId = input.wallet.walletId do { - try walletsService.addBalancesIfMissing(for: walletId, assetIds: assetIds, isEnabled: true) - try await walletsService.enableAssets(walletId: walletId, assetIds: assetIds, enabled: true) + try balanceService.addAssetsBalancesIfMissing(assetIds: assetIds, wallet: input.wallet, isEnabled: true) + try await assetsEnabler.enableAssets(walletId: input.wallet.walletId, assetIds: assetIds, enabled: true) } catch { debugLog("TransferExecutor post-transfer asset update error: \(error)") } diff --git a/Features/Transfer/Sources/ViewModels/ReceiveViewModel.swift b/Features/Transfer/Sources/ViewModels/ReceiveViewModel.swift index 80ebe3480..0abc4e7a5 100644 --- a/Features/Transfer/Sources/ViewModels/ReceiveViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/ReceiveViewModel.swift @@ -17,7 +17,7 @@ public final class ReceiveViewModel: Sendable { let assetModel: AssetViewModel let walletId: WalletId let address: String - let walletsService: WalletsService + let assetsEnabler: any AssetsEnabler let generator = QRCodeGenerator() public var isPresentingShareSheet: Bool = false @@ -28,12 +28,12 @@ public final class ReceiveViewModel: Sendable { assetModel: AssetViewModel, walletId: WalletId, address: String, - walletsService: WalletsService + assetsEnabler: any AssetsEnabler ) { self.assetModel = assetModel self.walletId = walletId self.address = address - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler } var title: String { @@ -88,7 +88,7 @@ public final class ReceiveViewModel: Sendable { func enableAsset() async { do { - try await walletsService.enableAssets(walletId: walletId, assetIds: [assetModel.asset.id], enabled: true) + try await assetsEnabler.enableAssets(walletId: walletId, assetIds: [assetModel.asset.id], enabled: true) } catch { debugLog("ReceiveViewModel enableAsset error: \(error)") } diff --git a/Features/Transfer/Tests/Services/TransferExecutorTests.swift b/Features/Transfer/Tests/Services/TransferExecutorTests.swift index d91e3c1b9..03e34276e 100644 --- a/Features/Transfer/Tests/Services/TransferExecutorTests.swift +++ b/Features/Transfer/Tests/Services/TransferExecutorTests.swift @@ -8,6 +8,7 @@ import Blockchain import BlockchainTestKit import SignerTestKit import WalletsServiceTestKit +import BalanceServiceTestKit import TransactionStateService import TransactionStateServiceTestKit import Store @@ -23,7 +24,8 @@ struct TransferExecutorTests { let executor = TransferExecutor( signer: TransactionSignerMock(signedData: ["setup1", "setup2", "setup3", "actual_order"]), chainService: ChainServiceMock.mock(broadcastResponses: ["hash0", "hash1", "hash2", "hash3"]), - walletsService: .mock(), + assetsEnabler: .mock(), + balanceService: .mock(), transactionStateService: .mock(transactionStore: transactionStore) ) @@ -48,7 +50,8 @@ struct TransferExecutorTests { let executor = TransferExecutor( signer: TransactionSignerMock(signedData: ["approval_tx", "swap_tx"]), chainService: ChainServiceMock.mock(broadcastResponses: ["hash0", "hash1"]), - walletsService: .mock(), + assetsEnabler: .mock(), + balanceService: .mock(), transactionStateService: .mock(transactionStore: transactionStore) ) @@ -73,7 +76,8 @@ struct TransferExecutorTests { let executor = TransferExecutor( signer: TransactionSignerMock(signedData: ["tx"]), chainService: ChainServiceMock.mock(broadcastResponses: ["hash"]), - walletsService: .mock(), + assetsEnabler: .mock(), + balanceService: .mock(), transactionStateService: .mock(transactionStore: transactionStore) ) diff --git a/Features/Transfer/Tests/ViewModels/ConfirmTransferSceneViewModelTests.swift b/Features/Transfer/Tests/ViewModels/ConfirmTransferSceneViewModelTests.swift index 5d723e67a..075b614c0 100644 --- a/Features/Transfer/Tests/ViewModels/ConfirmTransferSceneViewModelTests.swift +++ b/Features/Transfer/Tests/ViewModels/ConfirmTransferSceneViewModelTests.swift @@ -340,7 +340,7 @@ private extension ConfirmTransferSceneViewModel { confirmService: ConfirmServiceFactory.create( keystore: KeystoreMock(), chainServiceFactory: ChainServiceFactoryMock(), - walletsService: .mock(), + assetsEnabler: .mock(), scanService: .mock(), balanceService: .mock(), priceService: .mock(), diff --git a/Features/WalletTab/Package.swift b/Features/WalletTab/Package.swift index f6b8802d0..8a3430992 100644 --- a/Features/WalletTab/Package.swift +++ b/Features/WalletTab/Package.swift @@ -47,6 +47,7 @@ let package = Package( "Store", "Preferences", .product(name: "WalletsService", package: "FeatureServices"), + .product(name: "BalanceService", package: "FeatureServices"), .product(name: "BannerService", package: "FeatureServices"), .product(name: "WalletService", package: "FeatureServices"), .product(name: "ActivityService", package: "FeatureServices"), @@ -61,6 +62,7 @@ let package = Package( name: "WalletTabTestKit", dependencies: [ .product(name: "WalletsServiceTestKit", package: "FeatureServices"), + .product(name: "BalanceServiceTestKit", package: "FeatureServices"), .product(name: "PriceServiceTestKit", package: "FeatureServices"), .product(name: "BannerServiceTestKit", package: "FeatureServices"), .product(name: "PreferencesTestKit", package: "Preferences"), diff --git a/Features/WalletTab/Sources/ViewModels/AssetsResultsSceneViewModel.swift b/Features/WalletTab/Sources/ViewModels/AssetsResultsSceneViewModel.swift index 12b58d1a9..3fca85216 100644 --- a/Features/WalletTab/Sources/ViewModels/AssetsResultsSceneViewModel.swift +++ b/Features/WalletTab/Sources/ViewModels/AssetsResultsSceneViewModel.swift @@ -7,6 +7,7 @@ import Store import Preferences import Localization import WalletsService +import BalanceService import PrimitivesComponents import Components import Style @@ -16,7 +17,8 @@ import Style public final class AssetsResultsSceneViewModel { public static let defaultLimit = 100 - private let walletsService: WalletsService + private let assetsEnabler: any AssetsEnabler + private let balanceService: BalanceService private let preferences: Preferences private let wallet: Wallet @@ -28,13 +30,15 @@ public final class AssetsResultsSceneViewModel { public init( wallet: Wallet, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, + balanceService: BalanceService, preferences: Preferences, request: WalletSearchRequest, onSelectAsset: @escaping (Asset) -> Void ) { self.wallet = wallet - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler + self.balanceService = balanceService self.preferences = preferences self.searchQuery = ObservableQuery(request, initialValue: .empty) self.onSelectAssetAction = onSelectAsset @@ -70,7 +74,7 @@ extension AssetsResultsSceneViewModel { private func onAddToWallet(_ asset: Asset) { Task { do { - try await walletsService.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: true) + try await assetsEnabler.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: true) isPresentingToastMessage = .addedToWallet() } catch { debugLog("AssetsResultsSceneViewModel add to wallet error: \(error)") @@ -80,7 +84,7 @@ extension AssetsResultsSceneViewModel { private func onPinAsset(_ assetData: AssetData, value: Bool) { do { - try walletsService.setPinned(value, walletId: wallet.walletId, assetId: assetData.asset.id) + try balanceService.setPinned(value, walletId: wallet.walletId, assetId: assetData.asset.id) isPresentingToastMessage = .pin(assetData.asset.name, pinned: value) } catch { debugLog("AssetsResultsSceneViewModel pin asset error: \(error)") diff --git a/Features/WalletTab/Sources/ViewModels/WalletSceneViewModel.swift b/Features/WalletTab/Sources/ViewModels/WalletSceneViewModel.swift index da6dd1980..b8856ea08 100644 --- a/Features/WalletTab/Sources/ViewModels/WalletSceneViewModel.swift +++ b/Features/WalletTab/Sources/ViewModels/WalletSceneViewModel.swift @@ -5,6 +5,7 @@ import SwiftUI import Style import Primitives import WalletsService +import BalanceService import BannerService import Store import Preferences @@ -18,7 +19,8 @@ import Formatters @Observable @MainActor public final class WalletSceneViewModel: Sendable { - private let walletsService: WalletsService + private let assetSyncService: any AssetSyncServiceable + private let balanceService: BalanceService private let bannerService: BannerService private let walletService: WalletService @@ -52,7 +54,8 @@ public final class WalletSceneViewModel: Sendable { public var isLoadingAssets: Bool = false public init( - walletsService: WalletsService, + assetSyncService: any AssetSyncServiceable, + balanceService: BalanceService, bannerService: BannerService, walletService: WalletService, observablePreferences: ObservablePreferences, @@ -60,7 +63,8 @@ public final class WalletSceneViewModel: Sendable { isPresentingSelectedAssetInput: Binding ) { self.wallet = wallet - self.walletsService = walletsService + self.assetSyncService = assetSyncService + self.balanceService = balanceService self.bannerService = bannerService self.walletService = walletService self.observablePreferences = observablePreferences @@ -186,7 +190,7 @@ extension WalletSceneViewModel { func onHideAsset(_ assetId: AssetId) { do { - try walletsService.hideAsset(walletId: wallet.walletId, assetId: assetId) + try balanceService.hideAsset(walletId: wallet.walletId, assetId: assetId) } catch { debugLog("WalletSceneViewModel hide Asset error: \(error)") } @@ -194,7 +198,7 @@ extension WalletSceneViewModel { func onPinAsset(_ asset: Asset, value: Bool) { do { - try walletsService.setPinned(value, walletId: wallet.walletId, assetId: asset.id) + try balanceService.setPinned(value, walletId: wallet.walletId, assetId: asset.id) isPresentingToastMessage = .pin(asset.name, pinned: value) } catch { debugLog("WalletSceneViewModel pin asset error: \(error)") @@ -242,7 +246,7 @@ extension WalletSceneViewModel { assetIds: [AssetId] ) async { do { - try await walletsService.fetch( + try await assetSyncService.fetch( walletId: walletId, assetIds: assetIds ) diff --git a/Features/WalletTab/Sources/ViewModels/WalletSearchSceneViewModel.swift b/Features/WalletTab/Sources/ViewModels/WalletSearchSceneViewModel.swift index 7183563be..ab579bfd2 100644 --- a/Features/WalletTab/Sources/ViewModels/WalletSearchSceneViewModel.swift +++ b/Features/WalletTab/Sources/ViewModels/WalletSearchSceneViewModel.swift @@ -12,6 +12,7 @@ import Style import Localization import ActivityService import WalletsService +import BalanceService import PerpetualService import Recents @@ -21,7 +22,8 @@ public final class WalletSearchSceneViewModel: Sendable { private let searchService: WalletSearchService private let activityService: ActivityService - private let walletsService: WalletsService + private let assetsEnabler: any AssetsEnabler + private let balanceService: BalanceService private let perpetualService: PerpetualService private let preferences: ObservablePreferences @@ -51,7 +53,8 @@ public final class WalletSearchSceneViewModel: Sendable { wallet: Wallet, searchService: WalletSearchService, activityService: ActivityService, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, + balanceService: BalanceService, perpetualService: PerpetualService, preferences: ObservablePreferences = .default, onDismissSearch: VoidAction, @@ -61,7 +64,8 @@ public final class WalletSearchSceneViewModel: Sendable { self.wallet = wallet self.searchService = searchService self.activityService = activityService - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler + self.balanceService = balanceService self.perpetualService = perpetualService self.preferences = preferences self.onDismissSearch = onDismissSearch @@ -191,7 +195,7 @@ extension WalletSearchSceneViewModel { func onSelectAddToWallet(_ asset: Asset) { Task { do { - try await walletsService.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: true) + try await assetsEnabler.enableAssets(walletId: wallet.walletId, assetIds: [asset.id], enabled: true) isPresentingToastMessage = .addedToWallet() } catch { debugLog("WalletSearchSceneViewModel add to wallet error: \(error)") @@ -201,7 +205,7 @@ extension WalletSearchSceneViewModel { func onSelectPinAsset(_ assetData: AssetData, value: Bool) { do { - try walletsService.setPinned(value, walletId: wallet.walletId, assetId: assetData.asset.id) + try balanceService.setPinned(value, walletId: wallet.walletId, assetId: assetData.asset.id) isPresentingToastMessage = .pin(assetData.asset.name, pinned: value) } catch { debugLog("WalletSearchSceneViewModel pin asset error: \(error)") diff --git a/Features/WalletTab/TestKit/WalletSceneViewModel+TestKit.swift b/Features/WalletTab/TestKit/WalletSceneViewModel+TestKit.swift index 950f8fb03..86b2eaf3d 100644 --- a/Features/WalletTab/TestKit/WalletSceneViewModel+TestKit.swift +++ b/Features/WalletTab/TestKit/WalletSceneViewModel+TestKit.swift @@ -3,6 +3,7 @@ import Foundation import WalletTab import WalletsServiceTestKit +import BalanceServiceTestKit import BannerServiceTestKit import WalletServiceTestKit import PreferencesTestKit @@ -11,7 +12,8 @@ import PrimitivesTestKit public extension WalletSceneViewModel { static func mock() -> WalletSceneViewModel { WalletSceneViewModel( - walletsService: .mock(), + assetSyncService: .mock(), + balanceService: .mock(), bannerService: .mock(), walletService: .mock(), observablePreferences: .mock(), diff --git a/Features/WalletTab/TestKit/WalletSearchSceneViewModel+TestKit.swift b/Features/WalletTab/TestKit/WalletSearchSceneViewModel+TestKit.swift index fcfcece1e..915c8dd41 100644 --- a/Features/WalletTab/TestKit/WalletSearchSceneViewModel+TestKit.swift +++ b/Features/WalletTab/TestKit/WalletSearchSceneViewModel+TestKit.swift @@ -7,6 +7,8 @@ import AssetsService import AssetsServiceTestKit import ActivityService import ActivityServiceTestKit +import BalanceService +import BalanceServiceTestKit import Preferences import PreferencesTestKit import WalletsService @@ -20,7 +22,8 @@ public extension WalletSearchSceneViewModel { wallet: Wallet = .mock(), searchService: WalletSearchService = .mock(), activityService: ActivityService = .mock(), - walletsService: WalletsService = .mock(), + assetsEnabler: any AssetsEnabler = .mock(), + balanceService: BalanceService = .mock(), perpetualService: PerpetualService = .mock(), preferences: ObservablePreferences = .mock() ) -> WalletSearchSceneViewModel { @@ -28,7 +31,8 @@ public extension WalletSearchSceneViewModel { wallet: wallet, searchService: searchService, activityService: activityService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, + balanceService: balanceService, perpetualService: perpetualService, preferences: preferences, onDismissSearch: {}, diff --git a/Features/WalletTab/Tests/WalletSceneViewModelTests.swift b/Features/WalletTab/Tests/WalletSceneViewModelTests.swift index c6ac3cec6..a3111f68f 100644 --- a/Features/WalletTab/Tests/WalletSceneViewModelTests.swift +++ b/Features/WalletTab/Tests/WalletSceneViewModelTests.swift @@ -5,6 +5,7 @@ import Primitives import Preferences import WalletsServiceTestKit +import BalanceServiceTestKit import BannerServiceTestKit import WalletServiceTestKit import PrimitivesTestKit @@ -19,14 +20,14 @@ struct WalletSceneViewModelTests { func isLoading() { let model = WalletSceneViewModel.mock() #expect(model.isLoadingAssets == false) - + model.shouldStartLoadingAssets() #expect(model.isLoadingAssets) - + model.fetch() #expect(!model.isLoadingAssets == false) } - + @Test func priorityBannerReturnsHighestPriority() { let model = WalletSceneViewModel.mock() @@ -69,7 +70,8 @@ struct WalletSceneViewModelTests { extension WalletSceneViewModel { static func mock(wallet: Wallet = .mock()) -> WalletSceneViewModel { WalletSceneViewModel( - walletsService: .mock(), + assetSyncService: .mock(), + balanceService: .mock(), bannerService: .mock(), walletService: .mock(), observablePreferences: .mock(), diff --git a/Gem/App.swift b/Gem/App.swift index 4690e834d..8f3e8b49a 100644 --- a/Gem/App.swift +++ b/Gem/App.swift @@ -36,7 +36,7 @@ struct GemApp: App { navigationHandler: resolver.services.navigationHandler, lockWindowManager: LockWindowManager(lockModel: LockSceneViewModel()), walletService: resolver.services.walletService, - walletsService: resolver.services.walletsService, + walletSetupService: resolver.services.walletSetupService, nameService: resolver.services.nameService, releaseAlertService: resolver.services.releaseAlertService, rateService: resolver.services.rateService, diff --git a/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift b/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift index 6445a739e..faa0cb493 100644 --- a/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift +++ b/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift @@ -19,7 +19,7 @@ import Recents struct SelectAssetSceneNavigationStack: View { @Environment(\.viewModelFactory) private var viewModelFactory @Environment(\.chainServiceFactory) private var chainServiceFactory - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.keystore) private var keystore @Environment(\.scanService) private var scanService @Environment(\.balanceService) private var balanceService @@ -80,7 +80,7 @@ struct SelectAssetSceneNavigationStack: View { confirmService: ConfirmServiceFactory.create( keystore: keystore, chainServiceFactory: chainServiceFactory, - walletsService: walletsService, + assetsEnabler: assetsEnabler, scanService: scanService, balanceService: balanceService, priceService: priceService, @@ -108,7 +108,7 @@ struct SelectAssetSceneNavigationStack: View { assetModel: AssetViewModel(asset: input.asset), walletId: model.wallet.walletId, address: input.assetAddress.address, - walletsService: walletsService + assetsEnabler: assetsEnabler ) ) case .buy: diff --git a/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift b/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift index 5f7c2f8c5..43cc0adea 100644 --- a/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift +++ b/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift @@ -20,7 +20,7 @@ struct SelectedAssetNavigationStack: View { @Environment(\.viewModelFactory) private var viewModelFactory @Environment(\.keystore) private var keystore @Environment(\.chainServiceFactory) private var chainServiceFactory - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.scanService) private var scanService @Environment(\.balanceService) private var balanceService @Environment(\.priceService) private var priceService @@ -54,7 +54,7 @@ struct SelectedAssetNavigationStack: View { confirmService: ConfirmServiceFactory.create( keystore: keystore, chainServiceFactory: chainServiceFactory, - walletsService: walletsService, + assetsEnabler: assetsEnabler, scanService: scanService, balanceService: balanceService, priceService: priceService, @@ -82,7 +82,7 @@ struct SelectedAssetNavigationStack: View { assetModel: AssetViewModel(asset: input.asset), walletId: wallet.walletId, address: input.address, - walletsService: walletsService, + assetsEnabler: assetsEnabler, ) ) case let .buy(_, amount): diff --git a/Gem/Navigation/NFT/CollectionsNavigationStack.swift b/Gem/Navigation/NFT/CollectionsNavigationStack.swift index 5d347b66c..f6a88d6c6 100644 --- a/Gem/Navigation/NFT/CollectionsNavigationStack.swift +++ b/Gem/Navigation/NFT/CollectionsNavigationStack.swift @@ -12,7 +12,7 @@ import AssetsService struct CollectionsNavigationStack: View { @Environment(\.navigationState) private var navigationState - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.avatarService) private var avatarService @Environment(\.priceAlertService) private var priceAlertService @Environment(\.activityService) private var activityService @@ -74,7 +74,7 @@ struct CollectionsNavigationStack: View { wallet: model.wallet, selectType: $0, searchService: assetSearchService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, priceAlertService: priceAlertService, activityService: activityService ), diff --git a/Gem/Navigation/Price Alerts/PriceAlertsNavigationView.swift b/Gem/Navigation/Price Alerts/PriceAlertsNavigationView.swift index 3baabb534..e44cbee9b 100644 --- a/Gem/Navigation/Price Alerts/PriceAlertsNavigationView.swift +++ b/Gem/Navigation/Price Alerts/PriceAlertsNavigationView.swift @@ -11,7 +11,7 @@ import Components import AssetsService struct PriceAlertsNavigationView: View { - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.priceAlertService) private var priceAlertService @Environment(\.walletService) private var walletService @Environment(\.activityService) private var activityService @@ -39,7 +39,7 @@ struct PriceAlertsNavigationView: View { wallet: walletService.currentWallet!, selectType: .priceAlert, searchService: assetSearchService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, priceAlertService: priceAlertService, activityService: activityService, selectAssetAction: onSelectAsset diff --git a/Gem/Navigation/Settings/SettingsNavigationStack.swift b/Gem/Navigation/Settings/SettingsNavigationStack.swift index e5c56b9ba..c6d54991d 100644 --- a/Gem/Navigation/Settings/SettingsNavigationStack.swift +++ b/Gem/Navigation/Settings/SettingsNavigationStack.swift @@ -15,6 +15,7 @@ import InAppNotifications import NotificationService import ContactService import Contacts +import WalletSessionService struct SettingsNavigationStack: View { @Environment(\.navigationState) private var navigationState @@ -24,8 +25,9 @@ struct SettingsNavigationStack: View { @Environment(\.stakeService) private var stakeService @Environment(\.bannerService) private var bannerService @Environment(\.connectionsService) private var connectionsService - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.walletService) private var walletService + @Environment(\.walletSessionService) private var walletSessionService @Environment(\.priceAlertService) private var priceAlertService @Environment(\.priceService) private var priceService @Environment(\.nodeService) private var nodeService @@ -69,7 +71,7 @@ struct SettingsNavigationStack: View { SettingsScene( model: SettingsViewModel( walletId: walletId, - walletsService: walletsService, + walletSessionService: walletSessionService, observablePrefereces: observablePreferences ), isPresentingWallets: $isPresentingWallets, @@ -168,7 +170,7 @@ struct SettingsNavigationStack: View { RewardsScene( model: RewardsViewModel( rewardsService: rewardsService, - assetsEnabler: walletsService, + assetsEnabler: assetsEnabler, wallet: wallet, wallets: wallets, activateCode: scene.code, diff --git a/Gem/Navigation/Swap/SwapNavigationView.swift b/Gem/Navigation/Swap/SwapNavigationView.swift index 0442048c4..bfbb3ba42 100644 --- a/Gem/Navigation/Swap/SwapNavigationView.swift +++ b/Gem/Navigation/Swap/SwapNavigationView.swift @@ -13,6 +13,7 @@ struct SwapNavigationView: View { @Environment(\.priceAlertService) private var priceAlertService @Environment(\.activityService) private var activityService @Environment(\.assetSearchService) private var assetSearchService + @Environment(\.assetsEnabler) private var assetsEnabler @State private var model: SwapSceneViewModel @@ -32,7 +33,7 @@ struct SwapNavigationView: View { wallet: model.wallet, selectType: .swap(type), searchService: assetSearchService, - walletsService: model.walletsService, + assetsEnabler: assetsEnabler, priceAlertService: priceAlertService, activityService: activityService, selectAssetAction: model.onFinishAssetSelection diff --git a/Gem/Navigation/Transactions/TransactionsNavigationStack.swift b/Gem/Navigation/Transactions/TransactionsNavigationStack.swift index 35bdd94fb..caa0da51d 100644 --- a/Gem/Navigation/Transactions/TransactionsNavigationStack.swift +++ b/Gem/Navigation/Transactions/TransactionsNavigationStack.swift @@ -11,7 +11,7 @@ import AssetsService struct TransactionsNavigationStack: View { @Environment(\.navigationState) private var navigationState - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler @Environment(\.priceAlertService) private var priceAlertService @Environment(\.activityService) private var activityService @Environment(\.assetSearchService) private var assetSearchService @@ -66,7 +66,7 @@ struct TransactionsNavigationStack: View { wallet: model.wallet, selectType: $0, searchService: assetSearchService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, priceAlertService: priceAlertService, activityService: activityService ), diff --git a/Gem/Navigation/Wallet/WalletNavigationStack.swift b/Gem/Navigation/Wallet/WalletNavigationStack.swift index dbd2bc16c..68aa1fb4e 100644 --- a/Gem/Navigation/Wallet/WalletNavigationStack.swift +++ b/Gem/Navigation/Wallet/WalletNavigationStack.swift @@ -17,7 +17,9 @@ import PriceAlerts import AssetsService struct WalletNavigationStack: View { - @Environment(\.walletsService) private var walletsService + @Environment(\.assetsEnabler) private var assetsEnabler + @Environment(\.assetSyncService) private var assetSyncService + @Environment(\.balanceService) private var balanceService @Environment(\.navigationState) private var navigationState @Environment(\.priceService) private var priceService @Environment(\.priceAlertService) private var priceAlertService @@ -54,7 +56,8 @@ struct WalletNavigationStack: View { wallet: model.wallet, searchService: walletSearchService, activityService: activityService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, + balanceService: balanceService, perpetualService: perpetualService, onDismissSearch: model.onToggleSearch, onSelectAssetAction: onSelectAsset, @@ -87,7 +90,9 @@ struct WalletNavigationStack: View { .navigationDestination(for: Scenes.Asset.self) { AssetNavigationView( model: AssetSceneViewModel( - walletsService: walletsService, + assetsEnabler: assetsEnabler, + assetSyncService: assetSyncService, + balanceService: balanceService, assetsService: assetsService, transactionsService: transactionsService, priceObserverService: priceObserverService, @@ -134,7 +139,8 @@ struct WalletNavigationStack: View { AssetsResultsScene( model: AssetsResultsSceneViewModel( wallet: model.wallet, - walletsService: walletsService, + assetsEnabler: assetsEnabler, + balanceService: balanceService, preferences: preferences.preferences, request: WalletSearchRequest( walletId: model.wallet.walletId, @@ -171,7 +177,7 @@ struct WalletNavigationStack: View { wallet: model.wallet, selectType: $0, searchService: assetSearchService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, priceAlertService: priceAlertService, activityService: activityService ), diff --git a/Gem/Services/AppResolver+Services.swift b/Gem/Services/AppResolver+Services.swift index f12a14efd..36f2b8fb4 100644 --- a/Gem/Services/AppResolver+Services.swift +++ b/Gem/Services/AppResolver+Services.swift @@ -17,6 +17,7 @@ import TransactionsService import TransactionStateService import WalletsService import WalletService +import WalletSessionService import AppService import ScanService import NFTService @@ -51,7 +52,10 @@ extension AppResolver { let transactionsService: TransactionsService let transactionStateService: TransactionStateService let walletService: WalletService - let walletsService: WalletsService + let walletSessionService: WalletSessionService + let assetsEnabler: any AssetsEnabler + let assetSyncService: any AssetSyncServiceable + let walletSetupService: WalletSetupService let explorerService: ExplorerService let scanService: ScanService let nftService: NFTService @@ -98,7 +102,10 @@ extension AppResolver { transactionsService: TransactionsService, transactionStateService: TransactionStateService, walletService: WalletService, - walletsService: WalletsService, + walletSessionService: WalletSessionService, + assetsEnabler: any AssetsEnabler, + assetSyncService: any AssetSyncServiceable, + walletSetupService: WalletSetupService, explorerService: ExplorerService, scanService: ScanService, nftService: NFTService, @@ -144,7 +151,10 @@ extension AppResolver { self.transactionsService = transactionsService self.transactionStateService = transactionStateService self.walletService = walletService - self.walletsService = walletsService + self.walletSessionService = walletSessionService + self.assetsEnabler = assetsEnabler + self.assetSyncService = assetSyncService + self.walletSetupService = walletSetupService self.explorerService = explorerService self.scanService = scanService self.nftService = nftService diff --git a/Gem/Services/AppResolver+ViewInjection.swift b/Gem/Services/AppResolver+ViewInjection.swift index c30cde30a..8d197c9ce 100644 --- a/Gem/Services/AppResolver+ViewInjection.swift +++ b/Gem/Services/AppResolver+ViewInjection.swift @@ -15,7 +15,10 @@ extension View { self .environment(\.nodeService, services.nodeService) .environment(\.walletService, services.walletService) - .environment(\.walletsService, services.walletsService) + .environment(\.walletSessionService, services.walletSessionService) + .environment(\.assetsEnabler, services.assetsEnabler) + .environment(\.assetSyncService, services.assetSyncService) + .environment(\.walletSetupService, services.walletSetupService) .environment(\.deviceService, services.deviceService) .environment(\.transactionsService, services.transactionsService) .environment(\.assetsService, services.assetsService) diff --git a/Gem/Services/ServicesFactory.swift b/Gem/Services/ServicesFactory.swift index 998a331e7..b4ae561c0 100644 --- a/Gem/Services/ServicesFactory.swift +++ b/Gem/Services/ServicesFactory.swift @@ -174,14 +174,25 @@ struct ServicesFactory { ) let discoverAssetsService = DiscoverAssetsService(balanceService: balanceService, assetsService: apiService) - let walletsService = Self.makeWalletsService( - walletSessionService: walletSessionService, - assetsService: assetsService, + let balanceUpdater = BalanceUpdateService( balanceService: balanceService, - priceObserver: priceObserverService, + walletSessionService: walletSessionService + ) + let assetsEnabler = AssetsEnablerService( + assetsService: assetsService, + balanceUpdater: balanceUpdater, + priceUpdater: priceObserverService + ) + let assetSyncService = WalletAssetSyncService( deviceService: deviceService, - discoverAssetsService: discoverAssetsService + discoverAssetService: discoverAssetsService, + assetService: assetsService, + priceUpdater: priceObserverService, + balanceUpdater: balanceUpdater, + assetsEnabler: assetsEnabler, + walletSessionService: walletSessionService ) + let walletSetupService = WalletSetupService(balanceUpdater: balanceUpdater) let configService = ConfigService(apiService: apiService) let releaseService = AppReleaseService(configService: configService) @@ -267,7 +278,8 @@ struct ServicesFactory { chainServiceFactory: chainServiceFactory, scanService: scanService, swapService: swapService, - walletsService: walletsService, + assetsEnabler: assetsEnabler, + assetSyncService: assetSyncService, walletService: walletService, stakeService: stakeService, nameService: nameService, @@ -297,7 +309,10 @@ struct ServicesFactory { transactionsService: transactionsService, transactionStateService: transactionStateService, walletService: walletService, - walletsService: walletsService, + walletSessionService: walletSessionService, + assetsEnabler: assetsEnabler, + assetSyncService: assetSyncService, + walletSetupService: walletSetupService, explorerService: explorerService, scanService: scanService, nftService: nftService, @@ -502,24 +517,6 @@ extension ServicesFactory { ) } - private static func makeWalletsService( - walletSessionService: WalletSessionService, - assetsService: AssetsService, - balanceService: BalanceService, - priceObserver: PriceObserverService, - deviceService: DeviceService, - discoverAssetsService: DiscoverAssetsService - ) -> WalletsService { - WalletsService( - walletSessionService: walletSessionService, - assetsService: assetsService, - balanceService: balanceService, - priceObserver: priceObserver, - deviceService: deviceService, - discoverAssetsService: discoverAssetsService - ) - } - private static func makeOnstartService( assetStore: AssetStore, nodeStore: NodeStore, diff --git a/Gem/Services/ViewModelFactory.swift b/Gem/Services/ViewModelFactory.swift index a9f48678b..802958c30 100644 --- a/Gem/Services/ViewModelFactory.swift +++ b/Gem/Services/ViewModelFactory.swift @@ -32,7 +32,8 @@ public struct ViewModelFactory: Sendable { let chainServiceFactory: ChainServiceFactory let scanService: ScanService let swapService: SwapService - let walletsService: WalletsService + let assetsEnabler: any AssetsEnabler + let assetSyncService: any AssetSyncServiceable let walletService: WalletService let stakeService: StakeService let nameService: NameService @@ -49,7 +50,8 @@ public struct ViewModelFactory: Sendable { chainServiceFactory: ChainServiceFactory, scanService: ScanService, swapService: SwapService, - walletsService: WalletsService, + assetsEnabler: any AssetsEnabler, + assetSyncService: any AssetSyncServiceable, walletService: WalletService, stakeService: StakeService, nameService: NameService, @@ -65,7 +67,8 @@ public struct ViewModelFactory: Sendable { self.chainServiceFactory = chainServiceFactory self.scanService = scanService self.swapService = swapService - self.walletsService = walletsService + self.assetsEnabler = assetsEnabler + self.assetSyncService = assetSyncService self.walletService = walletService self.stakeService = stakeService self.nameService = nameService @@ -88,7 +91,7 @@ public struct ViewModelFactory: Sendable { let confirmService = ConfirmServiceFactory.create( keystore: keystore, chainServiceFactory: chainServiceFactory, - walletsService: walletsService, + assetsEnabler: assetsEnabler, scanService: scanService, balanceService: balanceService, priceService: priceService, @@ -163,7 +166,7 @@ public struct ViewModelFactory: Sendable { ) -> SwapSceneViewModel { SwapSceneViewModel( input: input, - walletsService: walletsService, + assetSyncService: assetSyncService, swapQuotesProvider: SwapQuotesProvider(swapService: swapService), swapQuoteDataProvider: SwapQuoteDataProvider(keystore: keystore, swapService: swapService), onSwap: onSwap diff --git a/Gem/Types/Environment.swift b/Gem/Types/Environment.swift index ef5a34d81..e10e2798f 100644 --- a/Gem/Types/Environment.swift +++ b/Gem/Types/Environment.swift @@ -23,6 +23,7 @@ import AssetsService import TransactionsService import WalletsService import WalletService +import WalletSessionService import AvatarService import AppService import ScanService @@ -42,8 +43,11 @@ extension EnvironmentValues { @Entry var priceService: PriceService = AppResolver.main.services.priceService @Entry var priceObserverService: PriceObserverService = AppResolver.main.services.priceObserverService @Entry var explorerService: ExplorerService = AppResolver.main.services.explorerService - @Entry var walletsService: WalletsService = AppResolver.main.services.walletsService + @Entry var assetsEnabler: any AssetsEnabler = AppResolver.main.services.assetsEnabler + @Entry var assetSyncService: any AssetSyncServiceable = AppResolver.main.services.assetSyncService + @Entry var walletSetupService: WalletSetupService = AppResolver.main.services.walletSetupService @Entry var walletService: WalletService = AppResolver.main.services.walletService + @Entry var walletSessionService: WalletSessionService = AppResolver.main.services.walletSessionService @Entry var priceAlertService: PriceAlertService = AppResolver.main.services.priceAlertService @Entry var deviceService: DeviceService = AppResolver.main.services.deviceService @Entry var balanceService: BalanceService = AppResolver.main.services.balanceService diff --git a/Gem/ViewModels/RootSceneViewModel.swift b/Gem/ViewModels/RootSceneViewModel.swift index 898f5a634..0022c5a96 100644 --- a/Gem/ViewModels/RootSceneViewModel.swift +++ b/Gem/ViewModels/RootSceneViewModel.swift @@ -34,7 +34,7 @@ final class RootSceneViewModel { private let deviceService: DeviceService let observablePreferences: ObservablePreferences - let walletsService: WalletsService + let walletSetupService: WalletSetupService let walletService: WalletService let nameService: NameService let avatarService: AvatarService @@ -81,7 +81,7 @@ final class RootSceneViewModel { navigationHandler: NavigationHandler, lockWindowManager: any LockWindowManageable, walletService: WalletService, - walletsService: WalletsService, + walletSetupService: WalletSetupService, nameService: NameService, releaseAlertService: ReleaseAlertService, rateService: RateService, @@ -98,7 +98,7 @@ final class RootSceneViewModel { self.navigationHandler = navigationHandler self.lockManager = lockWindowManager self.walletService = walletService - self.walletsService = walletsService + self.walletSetupService = walletSetupService self.nameService = nameService self.releaseAlertService = releaseAlertService self.rateService = rateService @@ -176,7 +176,7 @@ extension RootSceneViewModel { navigationHandler.wallet = wallet onstartWalletService.setup(wallet: wallet) do { - try walletsService.setup(wallet: wallet) + try walletSetupService.setup(wallet: wallet) } catch { debugLog("RootSceneViewModel setupWallet error: \(error)") } diff --git a/Gem/Views/MainTabView.swift b/Gem/Views/MainTabView.swift index ef489f394..0f30cdea6 100644 --- a/Gem/Views/MainTabView.swift +++ b/Gem/Views/MainTabView.swift @@ -14,7 +14,8 @@ import PriceAlerts import Components struct MainTabView: View { - @Environment(\.walletsService) private var walletsService + @Environment(\.assetSyncService) private var assetSyncService + @Environment(\.balanceService) private var balanceService @Environment(\.bannerService) private var bannerService @Environment(\.navigationState) private var navigationState @Environment(\.navigationPresenter) private var presenter @@ -43,7 +44,8 @@ struct MainTabView: View { TabView(selection: tabViewSelection) { WalletNavigationStack( model: WalletSceneViewModel( - walletsService: walletsService, + assetSyncService: assetSyncService, + balanceService: balanceService, bannerService: bannerService, walletService: walletService, observablePreferences: observablePreferences, diff --git a/Packages/FeatureServices/BalanceService/BalanceService.swift b/Packages/FeatureServices/BalanceService/BalanceService.swift index d6294ea53..bc8795d5d 100644 --- a/Packages/FeatureServices/BalanceService/BalanceService.swift +++ b/Packages/FeatureServices/BalanceService/BalanceService.swift @@ -38,6 +38,13 @@ extension BalanceService { public func unpinAsset(walletId: WalletId, assetId: AssetId) throws { try balanceStore.pinAsset(walletId: walletId, assetId: assetId, value: false) } + + public func setPinned(_ isPinned: Bool, walletId: WalletId, assetId: AssetId) throws { + switch isPinned { + case true: try pinAsset(walletId: walletId, assetId: assetId) + case false: try unpinAsset(walletId: walletId, assetId: assetId) + } + } } // MARK: - Balances diff --git a/Packages/FeatureServices/Package.swift b/Packages/FeatureServices/Package.swift index d6dce0cbe..a16bc956a 100644 --- a/Packages/FeatureServices/Package.swift +++ b/Packages/FeatureServices/Package.swift @@ -360,15 +360,8 @@ let package = Package( .target( name: "WalletsServiceTestKit", dependencies: [ - "DeviceServiceTestKit", - "DiscoverAssetsServiceTestKit", - .product(name: "StoreTestKit", package: "Store"), - .product(name: "PreferencesTestKit", package: "Preferences"), - "PriceServiceTestKit", - "BalanceServiceTestKit", - "WalletSessionService", - "WalletSessionServiceTestKit", - "WalletsService" + "WalletsService", + "Primitives" ], path: "WalletsService/TestKit" ), @@ -640,13 +633,9 @@ let package = Package( name: "WalletsServiceTests", dependencies: [ "WalletsService", - "WalletsServiceTestKit", "WalletSessionService", .product(name: "StoreTestKit", package: "Store"), "BalanceServiceTestKit", - "PriceServiceTestKit", - "AssetsServiceTestKit", - "DeviceServiceTestKit", .product(name: "PreferencesTestKit", package: "Preferences"), .product(name: "PrimitivesTestKit", package: "Primitives") ], diff --git a/Packages/FeatureServices/WalletSessionService/WalletSessionService.swift b/Packages/FeatureServices/WalletSessionService/WalletSessionService.swift index 8a393b753..b7b794473 100644 --- a/Packages/FeatureServices/WalletSessionService/WalletSessionService.swift +++ b/Packages/FeatureServices/WalletSessionService/WalletSessionService.swift @@ -46,4 +46,12 @@ public struct WalletSessionService: WalletSessionManageable { public func getWallets() throws -> [Wallet] { try walletStore.getWallets() } + + public func walletsCount() throws -> Int { + try getWallets().count + } + + public func hasMulticoinWallet() -> Bool { + (try? getWallets().contains { $0.type == .multicoin }) ?? false + } } diff --git a/Packages/FeatureServices/WalletsService/AssetsEnablerService.swift b/Packages/FeatureServices/WalletsService/AssetsEnablerService.swift index 778ba4e39..7327aa87a 100644 --- a/Packages/FeatureServices/WalletsService/AssetsEnablerService.swift +++ b/Packages/FeatureServices/WalletsService/AssetsEnablerService.swift @@ -4,12 +4,12 @@ import Foundation import Primitives import AssetsService -struct AssetsEnablerService: AssetsEnabler { +public struct AssetsEnablerService: AssetsEnabler { private let assetsService: AssetsService private let balanceUpdater: any BalanceUpdater private let priceUpdater: any PriceUpdater - init( + public init( assetsService: AssetsService, balanceUpdater: any BalanceUpdater, priceUpdater: any PriceUpdater @@ -19,7 +19,7 @@ struct AssetsEnablerService: AssetsEnabler { self.priceUpdater = priceUpdater } - func enableAssets(walletId: WalletId, assetIds: [AssetId], enabled: Bool) async throws { + public func enableAssets(walletId: WalletId, assetIds: [AssetId], enabled: Bool) async throws { for assetId in assetIds { try assetsService.addBalanceIfMissing(walletId: walletId, assetId: assetId) } @@ -33,7 +33,7 @@ struct AssetsEnablerService: AssetsEnabler { _ = try await (balanceUpdate, priceUpdate) } - func enableAssetId(walletId: WalletId, assetId: AssetId) async throws { + public func enableAssetId(walletId: WalletId, assetId: AssetId) async throws { let asset = try await assetsService.getOrFetchAsset(for: assetId) try await enableAssets(walletId: walletId, assetIds: [asset.id], enabled: true) } diff --git a/Packages/FeatureServices/WalletsService/BalanceUpdateService.swift b/Packages/FeatureServices/WalletsService/BalanceUpdateService.swift index 5c7e9e093..2f63cdb52 100644 --- a/Packages/FeatureServices/WalletsService/BalanceUpdateService.swift +++ b/Packages/FeatureServices/WalletsService/BalanceUpdateService.swift @@ -5,11 +5,11 @@ import Primitives import BalanceService import WalletSessionService -struct BalanceUpdateService: BalanceUpdater { +public struct BalanceUpdateService: BalanceUpdater { private let balanceService: BalanceService private let walletSessionService: any WalletSessionManageable - init( + public init( balanceService: BalanceService, walletSessionService: any WalletSessionManageable ) { @@ -17,7 +17,7 @@ struct BalanceUpdateService: BalanceUpdater { self.walletSessionService = walletSessionService } - func updateBalance(for walletId: WalletId, assetIds: [AssetId]) async throws { + public func updateBalance(for walletId: WalletId, assetIds: [AssetId]) async throws { await balanceService.updateBalance( for: try walletSessionService.getWallet(walletId: walletId), assetIds: assetIds @@ -25,7 +25,7 @@ struct BalanceUpdateService: BalanceUpdater { } // add asset to asset store and create balance store record - func addBalancesIfMissing(for walletId: WalletId, assetIds: [AssetId], isEnabled: Bool?) throws { + public func addBalancesIfMissing(for walletId: WalletId, assetIds: [AssetId], isEnabled: Bool?) throws { try balanceService.addAssetsBalancesIfMissing( assetIds: assetIds, wallet: walletSessionService.getWallet(walletId: walletId), diff --git a/Packages/FeatureServices/WalletsService/Protocols/AssetSyncServiceable.swift b/Packages/FeatureServices/WalletsService/Protocols/AssetSyncServiceable.swift new file mode 100644 index 000000000..681f9002f --- /dev/null +++ b/Packages/FeatureServices/WalletsService/Protocols/AssetSyncServiceable.swift @@ -0,0 +1,10 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Foundation +import Primitives + +public protocol AssetSyncServiceable: Sendable { + func fetch(walletId: WalletId, assetIds: [AssetId]) async throws + func updateAssets(walletId: WalletId, assetIds: [AssetId]) async throws + func addPrices(assetIds: [AssetId]) async throws +} diff --git a/Packages/FeatureServices/WalletsService/Protocols/AssetVisibilityManageable.swift b/Packages/FeatureServices/WalletsService/Protocols/AssetVisibilityManageable.swift deleted file mode 100644 index 18833d783..000000000 --- a/Packages/FeatureServices/WalletsService/Protocols/AssetVisibilityManageable.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c). Gem Wallet. All rights reserved. - -import Foundation -import Primitives -import BalanceService - -protocol AssetVisibilityServiceable: Sendable { - func hideAsset(walletId: WalletId, assetId: AssetId) throws - func setPinned(_ isPinned: Bool, walletId: WalletId, assetId: AssetId) throws -} - -extension BalanceService: AssetVisibilityServiceable { - func setPinned(_ isPinned: Bool, walletId: WalletId, assetId: AssetId) throws { - switch isPinned { - case true: try pinAsset(walletId: walletId, assetId: assetId) - case false: try unpinAsset(walletId: walletId, assetId: assetId) - } - } -} diff --git a/Packages/FeatureServices/WalletsService/Protocols/BalanceUpdater.swift b/Packages/FeatureServices/WalletsService/Protocols/BalanceUpdater.swift index 0cf0137e3..7e3941a37 100644 --- a/Packages/FeatureServices/WalletsService/Protocols/BalanceUpdater.swift +++ b/Packages/FeatureServices/WalletsService/Protocols/BalanceUpdater.swift @@ -3,7 +3,7 @@ import Foundation import Primitives -protocol BalanceUpdater: Sendable { +public protocol BalanceUpdater: Sendable { func updateBalance(for walletId: WalletId, assetIds: [AssetId]) async throws func addBalancesIfMissing(for walletId: WalletId, assetIds: [AssetId], isEnabled: Bool?) throws } diff --git a/Packages/FeatureServices/WalletsService/Protocols/PriceUpdater.swift b/Packages/FeatureServices/WalletsService/Protocols/PriceUpdater.swift index 4922ff21b..32e01f48d 100644 --- a/Packages/FeatureServices/WalletsService/Protocols/PriceUpdater.swift +++ b/Packages/FeatureServices/WalletsService/Protocols/PriceUpdater.swift @@ -4,12 +4,12 @@ import Foundation import Primitives import PriceService -protocol PriceUpdater: Sendable { +public protocol PriceUpdater: Sendable { func addPrices(assetIds: [AssetId]) async throws } extension PriceObserverService: PriceUpdater { - func addPrices(assetIds: [AssetId]) async throws { + public func addPrices(assetIds: [AssetId]) async throws { try await addAssets(assets: assetIds) } } diff --git a/Packages/FeatureServices/WalletsService/TestKit/AssetSyncServiceMock.swift b/Packages/FeatureServices/WalletsService/TestKit/AssetSyncServiceMock.swift new file mode 100644 index 000000000..335221265 --- /dev/null +++ b/Packages/FeatureServices/WalletsService/TestKit/AssetSyncServiceMock.swift @@ -0,0 +1,19 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Foundation +import Primitives +import WalletsService + +public struct AssetSyncServiceMock: AssetSyncServiceable { + public init() {} + + public func fetch(walletId: WalletId, assetIds: [AssetId]) async throws {} + public func updateAssets(walletId: WalletId, assetIds: [AssetId]) async throws {} + public func addPrices(assetIds: [AssetId]) async throws {} +} + +public extension AssetSyncServiceable where Self == AssetSyncServiceMock { + static func mock() -> AssetSyncServiceMock { + AssetSyncServiceMock() + } +} diff --git a/Packages/FeatureServices/WalletsService/TestKit/AssetsEnablerMock.swift b/Packages/FeatureServices/WalletsService/TestKit/AssetsEnablerMock.swift new file mode 100644 index 000000000..38f1236a9 --- /dev/null +++ b/Packages/FeatureServices/WalletsService/TestKit/AssetsEnablerMock.swift @@ -0,0 +1,18 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Foundation +import Primitives +import WalletsService + +public struct AssetsEnablerMock: AssetsEnabler { + public init() {} + + public func enableAssets(walletId: WalletId, assetIds: [AssetId], enabled: Bool) async throws {} + public func enableAssetId(walletId: WalletId, assetId: AssetId) async throws {} +} + +public extension AssetsEnabler where Self == AssetsEnablerMock { + static func mock() -> AssetsEnablerMock { + AssetsEnablerMock() + } +} diff --git a/Packages/FeatureServices/WalletsService/TestKit/WalletsService+TestKit.swift b/Packages/FeatureServices/WalletsService/TestKit/WalletsService+TestKit.swift deleted file mode 100644 index 388b417b7..000000000 --- a/Packages/FeatureServices/WalletsService/TestKit/WalletsService+TestKit.swift +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c). Gem Wallet. All rights reserved. - -import Foundation -import WalletsService -import Store -import StoreTestKit -import AssetsService -import AssetsServiceTestKit -import BalanceService -import BalanceServiceTestKit -import PriceService -import PriceServiceTestKit -import DeviceService -import DeviceServiceTestKit -import DiscoverAssetsService -import DiscoverAssetsServiceTestKit -import PreferencesTestKit -import WalletSessionService -import WalletSessionServiceTestKit - -public extension WalletsService { - static func mock( - walletSessionService: WalletSessionService = WalletSessionService(walletStore: .mock(), preferences: .mock()), - assetsService: AssetsService = .mock(), - balanceService: BalanceService = .mock(), - priceObserver: PriceObserverService = .mock(), - deviceService: DeviceService = .mock(), - discoverAssetsService: DiscoverAssetsService = .mock() - ) -> WalletsService { - WalletsService( - walletSessionService: walletSessionService, - assetsService: assetsService, - balanceService: balanceService, - priceObserver: priceObserver, - deviceService: deviceService, - discoverAssetsService: discoverAssetsService - ) - } -} diff --git a/Packages/FeatureServices/WalletsService/Tests/WalletsServiceTests.swift b/Packages/FeatureServices/WalletsService/Tests/WalletsServiceTests.swift index 918fce869..f0213ee39 100644 --- a/Packages/FeatureServices/WalletsService/Tests/WalletsServiceTests.swift +++ b/Packages/FeatureServices/WalletsService/Tests/WalletsServiceTests.swift @@ -1,7 +1,6 @@ // Copyright (c). Gem Wallet. All rights reserved. import Testing -import WalletsServiceTestKit import StoreTestKit import BalanceServiceTestKit import PrimitivesTestKit @@ -13,7 +12,7 @@ import GRDB @testable import Store @testable import WalletsService -struct WalletsServiceTests { +struct WalletSetupServiceTests { @Test func setupMulticoinWallet() throws { let (db, balanceStore, walletStore, service) = setupService() @@ -43,14 +42,16 @@ struct WalletsServiceTests { #expect(isEnabled == true) } - private func setupService() -> (DB, BalanceStore, WalletStore, WalletsService) { + private func setupService() -> (DB, BalanceStore, WalletStore, WalletSetupService) { let db = DB.mock() let balanceStore = BalanceStore.mock(db: db) let walletStore = WalletStore.mock(db: db) - let service = WalletsService.mock( - walletSessionService: WalletSessionService(walletStore: walletStore, preferences: .mock()), - balanceService: .mock(balanceStore: balanceStore) + let walletSessionService = WalletSessionService(walletStore: walletStore, preferences: .mock()) + let balanceUpdater = BalanceUpdateService( + balanceService: .mock(balanceStore: balanceStore), + walletSessionService: walletSessionService ) + let service = WalletSetupService(balanceUpdater: balanceUpdater) return (db, balanceStore, walletStore, service) } diff --git a/Packages/FeatureServices/WalletsService/WalletAssetSyncService.swift b/Packages/FeatureServices/WalletsService/WalletAssetSyncService.swift index 6962413fd..69d5e46c0 100644 --- a/Packages/FeatureServices/WalletsService/WalletAssetSyncService.swift +++ b/Packages/FeatureServices/WalletsService/WalletAssetSyncService.swift @@ -8,7 +8,7 @@ import Preferences import WalletSessionService import DeviceService -actor WalletAssetSyncService: DiscoveryAssetsProcessing { +public actor WalletAssetSyncService: AssetSyncServiceable, DiscoveryAssetsProcessing { private let deviceService: any DeviceServiceable private let discoverAssetService: DiscoverAssetsService private let assetService: AssetsService @@ -17,7 +17,7 @@ actor WalletAssetSyncService: DiscoveryAssetsProcessing { private let assetsEnabler: any AssetsEnabler private let walletSessionService: any WalletSessionManageable - init( + public init( deviceService: any DeviceServiceable, discoverAssetService: DiscoverAssetsService, assetService: AssetsService, @@ -35,7 +35,7 @@ actor WalletAssetSyncService: DiscoveryAssetsProcessing { self.walletSessionService = walletSessionService } - func fetch(walletId: WalletId, assetIds: [AssetId]) async throws { + public func fetch(walletId: WalletId, assetIds: [AssetId]) async throws { async let updateAssets: () = try updateAssets(walletId: walletId, assetIds: assetIds) async let discoverAssets: () = try discoverAssets( for: walletId, @@ -44,11 +44,11 @@ actor WalletAssetSyncService: DiscoveryAssetsProcessing { _ = try await (updateAssets, discoverAssets) } - func updateAssets(walletId: WalletId, assetIds: [AssetId]) async throws { + public func updateAssets(walletId: WalletId, assetIds: [AssetId]) async throws { try await balanceUpdater.updateBalance(for: walletId, assetIds: assetIds) } - func addPrices(assetIds: [AssetId]) async throws { + public func addPrices(assetIds: [AssetId]) async throws { try await priceUpdater.addPrices(assetIds: assetIds) } diff --git a/Packages/FeatureServices/WalletsService/WalletSetupService.swift b/Packages/FeatureServices/WalletsService/WalletSetupService.swift new file mode 100644 index 000000000..febbefc5a --- /dev/null +++ b/Packages/FeatureServices/WalletsService/WalletSetupService.swift @@ -0,0 +1,30 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Foundation +import Primitives + +public struct WalletSetupService: Sendable { + private let balanceUpdater: any BalanceUpdater + + public init(balanceUpdater: any BalanceUpdater) { + self.balanceUpdater = balanceUpdater + } + + public func setup(wallet: Wallet) throws { + let chains = wallet.chains + + let (chainsEnabledByDefault, chainsDisabledByDefault) = chains.reduce(into: ([Chain](), [Chain]())) { result, chain in + if AssetConfiguration.enabledByDefault.contains(chain.assetId) || (wallet.accounts.count == 1 && chains.count == 1) { + result.0.append(chain) + } else { + result.1.append(chain) + } + } + + try balanceUpdater.addBalancesIfMissing(for: wallet.walletId, assetIds: chainsEnabledByDefault.ids, isEnabled: true) + try balanceUpdater.addBalancesIfMissing(for: wallet.walletId, assetIds: chainsDisabledByDefault.ids, isEnabled: false) + + let defaultAssets = chains.map { $0.defaultAssets.assetIds }.flatMap { $0 } + try balanceUpdater.addBalancesIfMissing(for: wallet.walletId, assetIds: defaultAssets, isEnabled: false) + } +} diff --git a/Packages/FeatureServices/WalletsService/WalletsService.swift b/Packages/FeatureServices/WalletsService/WalletsService.swift deleted file mode 100644 index 8dcb45b05..000000000 --- a/Packages/FeatureServices/WalletsService/WalletsService.swift +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c). Gem Wallet. All rights reserved. - -import Foundation -import Primitives -import PriceService -import Preferences -import BalanceService -import AssetsService -import DiscoverAssetsService -import WalletSessionService -import DeviceService - -public struct WalletsService: Sendable { - private let walletSessionService: any WalletSessionManageable - private let assetsEnabler: any AssetsEnabler - private let assetSyncService: WalletAssetSyncService - private let balanceUpdater: any BalanceUpdater - private let assetsVisibilityManager: any AssetVisibilityServiceable - - public init( - walletSessionService: WalletSessionService, - assetsService: AssetsService, - balanceService: BalanceService, - priceObserver: PriceObserverService, - deviceService: any DeviceServiceable, - discoverAssetsService: DiscoverAssetsService - ) { - let balanceUpdater = BalanceUpdateService( - balanceService: balanceService, - walletSessionService: walletSessionService - ) - let priceUpdater = priceObserver - let assetsEnabler = AssetsEnablerService( - assetsService: assetsService, - balanceUpdater: balanceUpdater, - priceUpdater: priceUpdater - ) - let assetSyncService = WalletAssetSyncService( - deviceService: deviceService, - discoverAssetService: discoverAssetsService, - assetService: assetsService, - priceUpdater: priceUpdater, - balanceUpdater: balanceUpdater, - assetsEnabler: assetsEnabler, - walletSessionService: walletSessionService, - ) - - self.walletSessionService = walletSessionService - self.assetsVisibilityManager = balanceService - self.assetsEnabler = assetsEnabler - self.balanceUpdater = balanceUpdater - self.assetSyncService = assetSyncService - } - - public func walletsCount() throws -> Int { - try walletSessionService.getWallets().count - } - - public func hasMulticoinWallet() -> Bool { - (try? walletSessionService.getWallets().contains { $0.type == .multicoin }) ?? false - } - - public func updateAssets(walletId: WalletId, assetIds: [AssetId]) async throws { - try await assetSyncService.updateAssets(walletId: walletId, assetIds: assetIds) - } - - public func fetch(walletId: WalletId, assetIds: [AssetId]) async throws { - try await assetSyncService.fetch(walletId: walletId, assetIds: assetIds) - } - - public func setup(wallet: Wallet) throws { - let chains = wallet.chains - - let (chainsEnabledByDefault, chainsDisabledByDefault) = chains.reduce(into: ([Chain](), [Chain]())) { result, chain in - if AssetConfiguration.enabledByDefault.contains(chain.assetId) || (wallet.accounts.count == 1 && chains.count == 1) { - result.0.append(chain) - } else { - result.1.append(chain) - } - } - - try addBalancesIfMissing(for: wallet.walletId, assetIds: chainsEnabledByDefault.ids, isEnabled: true) - try addBalancesIfMissing(for: wallet.walletId, assetIds: chainsDisabledByDefault.ids, isEnabled: false) - - let defaultAssets = chains.map { $0.defaultAssets.assetIds }.flatMap { $0 } - try addBalancesIfMissing(for: wallet.walletId, assetIds: defaultAssets, isEnabled: false) - } -} - -// MARK: - DiscoveryAssetsProcessing - -extension WalletsService: DiscoveryAssetsProcessing { - func discoverAssets(for walletId: WalletId, preferences: WalletPreferences) async throws { - try await assetSyncService.discoverAssets(for: walletId, preferences: preferences) - } -} - -// MARK: - AssetsEnabler - -extension WalletsService: AssetsEnabler { - public func enableAssets(walletId: WalletId, assetIds: [AssetId], enabled: Bool) async throws { - try await assetsEnabler.enableAssets(walletId: walletId, assetIds: assetIds, enabled: enabled) - } - - public func enableAssetId(walletId: WalletId, assetId: AssetId) async throws { try await assetsEnabler.enableAssetId(walletId: walletId, assetId: assetId) } -} - -// MARK: - PriceUpdater - -extension WalletsService: PriceUpdater { - public func addPrices(assetIds: [AssetId]) async throws { - try await assetSyncService.addPrices(assetIds: assetIds) - } -} - -// MARK: - BalanceUpdater - -extension WalletsService: BalanceUpdater { - func updateBalance(for walletId: WalletId, assetIds: [AssetId]) async throws { - try await assetSyncService.updateAssets(walletId: walletId, assetIds: assetIds) - } - - public func addBalancesIfMissing(for walletId: WalletId, assetIds: [AssetId], isEnabled: Bool?) throws { - try balanceUpdater.addBalancesIfMissing(for: walletId, assetIds: assetIds, isEnabled: isEnabled) - } -} - -// MARK: - AssetVisibilityServiceable - -extension WalletsService: AssetVisibilityServiceable { - public func setPinned(_ isPinned: Bool, walletId: WalletId, assetId: AssetId) throws { - try assetsVisibilityManager.setPinned(isPinned, walletId: walletId, assetId: assetId) - } - - public func hideAsset(walletId: WalletId, assetId: AssetId) throws { - try assetsVisibilityManager.hideAsset(walletId: walletId, assetId: assetId) - } -}