diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index 8633e9d88c..bbf7601d27 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -101,10 +101,6 @@ internal class DefaultStakingRepository( private val yieldBalanceConverter = YieldBalanceConverter() private val yieldBalanceListConverter = YieldBalanceListConverter(yieldBalanceConverter) - private val isYieldBalanceFetching = MutableStateFlow( - value = emptyMap(), - ) - private val tronStakeKitTransactionAdapter by lazy { moshi.adapter(TronStakeKitTransaction::class.java) } override fun getIntegrationKey(cryptoCurrencyId: CryptoCurrency.ID): String = with(cryptoCurrencyId) { @@ -384,79 +380,48 @@ internal class DefaultStakingRepository( ) = withContext(dispatchers.io) { if (!stakingFeatureToggle.isStakingEnabled) return@withContext - try { - cacheRegistry.invokeOnExpire( - key = getYieldBalancesKey(userWalletId), - skipCache = refresh, - block = { - isYieldBalanceFetching.update { - it + (userWalletId to true) - } + cacheRegistry.invokeOnExpire( + key = getYieldBalancesKey(userWalletId), + skipCache = refresh, + block = { + val yields = getEnabledYields().ifEmpty { + Timber.i("No enabled yields for $userWalletId") + stakingBalanceStore.store(userWalletId, emptySet()) - val yields = getEnabledYields().ifEmpty { - Timber.i("No enabled yields for $userWalletId") + return@invokeOnExpire + } + val availableCurrencies = cryptoCurrencies + .mapNotNull { currency -> + val addresses = walletManagersFacade.getAddresses(userWalletId, currency.network) + val integrationId = integrationIdMap[getIntegrationKey(currency.id)] + + if (integrationId != null && yields.any { it.id == integrationId }) { + addresses to integrationId + } else { + null + } + } + .flatMap { (addresses, integrationId) -> + addresses.map { address -> address to integrationId } + } + .map { getBalanceRequestData(it.first.value, it.second) } + .ifEmpty { + Timber.i("No yield balances available for $userWalletId") stakingBalanceStore.store(userWalletId, emptySet()) return@invokeOnExpire } - val availableCurrencies = cryptoCurrencies - .mapNotNull { currency -> - val addresses = walletManagersFacade.getAddresses(userWalletId, currency.network) - val integrationId = integrationIdMap[getIntegrationKey(currency.id)] - if (integrationId != null && yields.any { it.id == integrationId }) { - addresses to integrationId - } else { - null - } - } - .flatMap { (addresses, integrationId) -> - addresses.map { address -> address to integrationId } - } - .map { getBalanceRequestData(it.first.value, it.second) } - .ifEmpty { - Timber.i("No yield balances available for $userWalletId") - stakingBalanceStore.store(userWalletId, emptySet()) + val result = stakeKitApi + .getMultipleYieldBalances(availableCurrencies) + .getOrThrow() - return@invokeOnExpire - } - - val result = stakeKitApi - .getMultipleYieldBalances(availableCurrencies) - .getOrThrow() - - stakingBalanceStore.store(userWalletId, result) - }, - ) - } finally { - isYieldBalanceFetching.update { - it - userWalletId - } - } + stakingBalanceStore.store(userWalletId, result) + }, + ) } - override fun getMultiYieldBalanceFlow( - userWalletId: UserWalletId, - cryptoCurrencies: List, - ): Flow = channelFlow { - if (!stakingFeatureToggle.isStakingEnabled) { - send(YieldBalanceList.Empty) - } else { - launch(dispatchers.io) { - stakingBalanceStore.get(userWalletId) - .collectLatest { send(yieldBalanceListConverter.convert(it)) } - } - - withContext(dispatchers.io) { - fetchMultiYieldBalance( - userWalletId, - cryptoCurrencies, - ) - } - } - }.cancellable() - - override fun getMultiYieldBalance( + override fun getMultiYieldBalanceUpdates( userWalletId: UserWalletId, cryptoCurrencies: List, ): Flow = channelFlow { diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 4664e120ce..e5b5f561bd 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -1,6 +1,5 @@ package com.tangem.data.tokens.repository -import arrow.core.raise.catch import com.tangem.blockchain.common.Blockchain import com.tangem.blockchainsdk.compatibility.getL2CompatibilityTokenComparison import com.tangem.blockchainsdk.utils.toCoinId @@ -27,8 +26,6 @@ import com.tangem.datasource.local.preferences.utils.storeObject import com.tangem.datasource.local.token.ExpressAssetsStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.core.error.DataError -import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.core.lce.lceFlow import com.tangem.domain.demo.DemoConfig import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus @@ -67,10 +64,6 @@ internal class DefaultCurrenciesRepository( private val userTokensBackwardCompatibility = UserTokensBackwardCompatibility() private val customTokensMerger = CustomTokensMerger(tangemTechApi, dispatchers) - private val isMultiCurrencyWalletCurrenciesFetching = MutableStateFlow( - value = emptyMap(), - ) - override suspend fun saveTokens( userWalletId: UserWalletId, currencies: List, @@ -267,30 +260,6 @@ internal class DefaultCurrenciesRepository( } } - override fun getMultiCurrencyWalletCurrenciesUpdatesLce( - userWalletId: UserWalletId, - ): LceFlow> = lceFlow { - val userWallet = getUserWallet(userWalletId) - catch({ ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true) }) { - raise(it) - } - - launch(dispatchers.io) { - combine( - getMultiCurrencyWalletCurrencies(userWallet), - isMultiCurrencyWalletCurrenciesFetching.map { it.getOrElse(userWallet.walletId) { false } }, - ) { currencies, isFetching -> - send(currencies, isStillLoading = isFetching) - }.collect() - } - - withContext(dispatchers.io) { - catch({ fetchTokensIfCacheExpired(userWallet, refresh = false) }) { - raise(it) - } - } - } - override suspend fun getMultiCurrencyWalletCurrenciesSync( userWalletId: UserWalletId, refresh: Boolean, @@ -540,19 +509,7 @@ internal class DefaultCurrenciesRepository( cacheRegistry.invokeOnExpire( key = getTokensCacheKey(userWallet.walletId), skipCache = refresh, - block = { - isMultiCurrencyWalletCurrenciesFetching.update { - it + (userWallet.walletId to true) - } - - try { - fetchTokens(userWallet) - } finally { - isMultiCurrencyWalletCurrenciesFetching.update { - it - userWallet.walletId - } - } - }, + block = { fetchTokens(userWallet) }, ) } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultNetworksRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultNetworksRepository.kt index d61f12d1a3..26ab1470f2 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultNetworksRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultNetworksRepository.kt @@ -1,6 +1,5 @@ package com.tangem.data.tokens.repository -import arrow.core.raise.catch import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.address.AddressType import com.tangem.blockchainsdk.utils.fromNetworkId @@ -15,8 +14,6 @@ import com.tangem.datasource.local.preferences.PreferencesKeys import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.core.lce.lceFlow import com.tangem.domain.demo.DemoConfig import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyAddress @@ -28,7 +25,10 @@ import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber @Suppress("LongParameterList") @@ -46,10 +46,6 @@ internal class DefaultNetworksRepository( private val responseCurrenciesFactory by lazy { ResponseCryptoCurrenciesFactory() } private val networkStatusFactory by lazy { NetworkStatusFactory() } - private val isNetworkStatusesFetching = MutableStateFlow( - value = emptyMap(), - ) - override fun getNetworkStatusesUpdates( userWalletId: UserWalletId, networks: Set, @@ -63,24 +59,6 @@ internal class DefaultNetworksRepository( } } - override fun getNetworkStatusesUpdatesLce( - userWalletId: UserWalletId, - networks: Set, - ): LceFlow> = lceFlow { - combine( - networksStatusesStore.get(userWalletId), - isNetworkStatusesFetching.map { it.getOrElse(userWalletId) { false } }, - ) { statuses, isFetching -> - send(statuses, isStillLoading = isFetching || networks.size != statuses.size) - }.launchIn(scope = this + dispatchers.io) - - withContext(dispatchers.io) { - catch({ fetchNetworksStatusesIfCacheExpired(userWalletId, networks, refresh = false) }) { - raise(it) - } - } - } - override suspend fun fetchNetworkPendingTransactions(userWalletId: UserWalletId, networks: Set) { val currencies = getCurrencies(userWalletId, networks) withContext(dispatchers.io) { @@ -123,67 +101,13 @@ internal class DefaultNetworksRepository( } } - override suspend fun getNetworkAddress( - userWalletId: UserWalletId, - currency: CryptoCurrency, - ): CryptoCurrencyAddress = withContext(dispatchers.io) { - CryptoCurrencyAddress( - cryptoCurrency = currency, - address = walletManagersFacade.getAddresses(userWalletId, currency.network) - .firstOrNull { it.type == AddressType.Default } - ?.value.orEmpty(), - ) - } - - override fun getNetworkAddressFlow( - userWalletId: UserWalletId, - currency: CryptoCurrency, - ): Flow = channelFlow { - launch(dispatchers.io) { - send(getNetworkAddress(userWalletId, currency)) - } - } - - override suspend fun getNetworkAddresses(userWalletId: UserWalletId): List = - withContext(dispatchers.io) { - // Get list of currencies matching [network] - val currencies = getCurrencies(userWalletId) - - // There is no currencies matching given [networks] in [userWalletId] - if (currencies.toList().isEmpty()) return@withContext emptyList() - - currencies.toList().map { currency -> - CryptoCurrencyAddress( - cryptoCurrency = currency, - address = walletManagersFacade.getAddresses(userWalletId, currency.network) - .firstOrNull { it.type == AddressType.Default } - ?.value.orEmpty(), - ) - } - } - - override fun getNetworkAddressesFlow( - userWalletId: UserWalletId, - network: Network, - ): Flow> = channelFlow { - launch(dispatchers.io) { - send(getNetworkAddresses(userWalletId, network)) - } - } - - override fun getNetworkAddressesFlow(userWalletId: UserWalletId): Flow> = channelFlow { - launch(dispatchers.io) { - send(getNetworkAddresses(userWalletId)) - } - } - private suspend fun fetchNetworksStatusesIfCacheExpired( userWalletId: UserWalletId, networks: Set, refresh: Boolean, ) = coroutineScope { if (refresh) { - val statusesToRefresh = networks.map { NetworkStatus(it, NetworkStatus.Loading) } + val statusesToRefresh = networks.map { NetworkStatus(it, NetworkStatus.Refreshing) } networksStatusesStore.storeAll(userWalletId, statusesToRefresh) } @@ -230,8 +154,6 @@ internal class DefaultNetworksRepository( network: Network, currencies: Sequence, ) { - networksStatusesStore.store(userWalletId, NetworkStatus(network, NetworkStatus.Loading)) - val result = walletManagersFacade.update( userWalletId = userWalletId, network = network, diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt index 6e17391a27..568683be77 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt @@ -49,12 +49,7 @@ interface StakingRepository { refresh: Boolean = false, ) - fun getMultiYieldBalanceFlow( - userWalletId: UserWalletId, - cryptoCurrencies: List, - ): Flow - - fun getMultiYieldBalance( + fun getMultiYieldBalanceUpdates( userWalletId: UserWalletId, cryptoCurrencies: List, ): Flow diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt index 730dbc541b..cc96309f1f 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt @@ -186,7 +186,7 @@ internal class CurrenciesStatusesLceOperations( userWalletId: UserWalletId, cryptoCurrencies: List, ): EitherFlow { - return stakingRepository.getMultiYieldBalance(userWalletId, cryptoCurrencies) + return stakingRepository.getMultiYieldBalanceUpdates(userWalletId, cryptoCurrencies) .map> { it.right() } .catch { emit(TokenListError.DataError(it).left()) } .distinctUntilChanged() diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt index 8a19b705e9..bda0e8fdbd 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt @@ -1,7 +1,6 @@ package com.tangem.domain.tokens.repository import com.tangem.domain.core.error.DataError -import com.tangem.domain.core.lce.LceFlow import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.FeePaidCurrency @@ -130,17 +129,6 @@ interface CurrenciesRepository { */ fun getMultiCurrencyWalletCurrenciesUpdates(userWalletId: UserWalletId): Flow> - /** - * Retrieves updates of the list of cryptocurrencies within a multi-currency wallet. - * - * Loads remote cryptocurrencies if they have expired. - * - * @param userWalletId The unique identifier of the user wallet. - * @return A [LceFlow] emitting the set of cryptocurrencies associated with the user wallet. May emit an - * [DataError.UserWalletError.WrongUserWallet] if single-currency user wallet ID provided. - */ - fun getMultiCurrencyWalletCurrenciesUpdatesLce(userWalletId: UserWalletId): LceFlow> - /** * Retrieves the list of cryptocurrencies within a multi-currency wallet. * diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt index a2a99ddea2..2e568b83b4 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt @@ -1,7 +1,5 @@ package com.tangem.domain.tokens.repository -import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyAddress import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.model.NetworkStatus @@ -23,20 +21,6 @@ interface NetworksRepository { */ fun getNetworkStatusesUpdates(userWalletId: UserWalletId, networks: Set): Flow> - /** - * Retrieves updates of network statuses of specified blockchain networks for a specific user wallet. - * - * Loads remote network statuses if they have expired. - * - * @param userWalletId The unique identifier of the user wallet. - * @param networks A set of network which statuses are to be retrieved. - * @return A [LceFlow] emitting a set of [NetworkStatus] objects corresponding to the specified networks. - */ - fun getNetworkStatusesUpdatesLce( - userWalletId: UserWalletId, - networks: Set, - ): LceFlow> - /** * Fetches pending transactions for given network * @@ -63,33 +47,8 @@ interface NetworksRepository { fun isNeedToCreateAccountWithoutReserve(network: Network): Boolean - /** - * Returns list of addresses and crypto currency info of added currencies of [network] in selected wallet [userWalletId] - */ - fun getNetworkAddressesFlow(userWalletId: UserWalletId, network: Network): Flow> - /** * Returns list of addresses and crypto currency info of added currencies of [network] in selected wallet [userWalletId] */ suspend fun getNetworkAddresses(userWalletId: UserWalletId, network: Network): List - - /** - * Returns address of [cryptoCurrency] in selected wallet [userWalletId] - */ - suspend fun getNetworkAddress(userWalletId: UserWalletId, currency: CryptoCurrency): CryptoCurrencyAddress - - /** - * Returns address of [cryptoCurrency] in selected wallet [userWalletId] - */ - fun getNetworkAddressFlow(userWalletId: UserWalletId, currency: CryptoCurrency): Flow - - /** - * Returns list of addresses and crypto currency info in selected wallet [userWalletId] - */ - fun getNetworkAddressesFlow(userWalletId: UserWalletId): Flow> - - /** - * Returns list of addresses and crypto currency info in selected wallet [userWalletId] - */ - suspend fun getNetworkAddresses(userWalletId: UserWalletId): List } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt index cc16af1aba..f68979c6f4 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt @@ -3,8 +3,6 @@ package com.tangem.domain.tokens.repository import arrow.core.Either import arrow.core.getOrElse import com.tangem.domain.core.error.DataError -import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.core.utils.toLce import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.FeePaidCurrency @@ -57,7 +55,7 @@ internal class MockCurrenciesRepository( override suspend fun removeCurrencies(userWalletId: UserWalletId, currencies: List) = Unit - override fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): LceFlow> { + override fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): Flow> { return emptyFlow() } @@ -91,12 +89,6 @@ internal class MockCurrenciesRepository( return tokens.map { it.getOrElse { e -> throw e } } } - override fun getMultiCurrencyWalletCurrenciesUpdatesLce( - userWalletId: UserWalletId, - ): LceFlow> { - return tokens.map { it.toLce() } - } - override suspend fun getMultiCurrencyWalletCurrency( userWalletId: UserWalletId, id: CryptoCurrency.ID, diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt index 5b5019dfd6..2e56eb6aa0 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt @@ -3,15 +3,11 @@ package com.tangem.domain.tokens.repository import arrow.core.Either import arrow.core.getOrElse import com.tangem.domain.core.error.DataError -import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.core.utils.toLce -import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyAddress import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.model.NetworkStatus import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map @@ -26,13 +22,6 @@ internal class MockNetworksRepository( return statuses.map { it.getOrElse { e -> throw e } } } - override fun getNetworkStatusesUpdatesLce( - userWalletId: UserWalletId, - networks: Set, - ): LceFlow> { - return statuses.map { it.toLce() } - } - override suspend fun fetchNetworkPendingTransactions(userWalletId: UserWalletId, networks: Set) { // no-op } @@ -47,37 +36,10 @@ internal class MockNetworksRepository( override fun isNeedToCreateAccountWithoutReserve(network: Network) = false - override fun getNetworkAddressesFlow( - userWalletId: UserWalletId, - network: Network, - ): Flow> = channelFlow { - send(emptyList()) - } - - override fun getNetworkAddressesFlow(userWalletId: UserWalletId): Flow> = channelFlow { - send(emptyList()) - } - override suspend fun getNetworkAddresses( userWalletId: UserWalletId, network: Network, ): List { return emptyList() } - - override suspend fun getNetworkAddresses(userWalletId: UserWalletId): List { - return emptyList() - } - - override suspend fun getNetworkAddress( - userWalletId: UserWalletId, - currency: CryptoCurrency, - ): CryptoCurrencyAddress = CryptoCurrencyAddress(currency, "") - - override fun getNetworkAddressFlow( - userWalletId: UserWalletId, - currency: CryptoCurrency, - ): Flow = channelFlow { - send(CryptoCurrencyAddress(currency, "")) - } } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt index 9b702bacbb..0dc93edf8d 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt @@ -145,18 +145,7 @@ class MockStakingRepository : StakingRepository { /* no-op */ } - override fun getMultiYieldBalanceFlow( - userWalletId: UserWalletId, - cryptoCurrencies: List, - ): Flow = channelFlow { - send( - YieldBalanceList.Data( - balances = listOf(YieldBalance.Error), - ), - ) - } - - override fun getMultiYieldBalance( + override fun getMultiYieldBalanceUpdates( userWalletId: UserWalletId, cryptoCurrencies: List, ): Flow = flowOf()