diff --git a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt index e15eea4635..c3520a41cf 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt @@ -4,6 +4,7 @@ import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.managetokens.* import com.tangem.domain.managetokens.repository.CustomTokensRepository import com.tangem.domain.managetokens.repository.ManageTokensRepository +import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.walletmanager.WalletManagersFacade @@ -65,6 +66,7 @@ internal object ManageTokensDomainModule { currenciesRepository: CurrenciesRepository, networksRepository: NetworksRepository, derivationsRepository: DerivationsRepository, + stakingRepository: StakingRepository, ): SaveManagedTokensUseCase { return SaveManagedTokensUseCase( customTokensRepository = customTokensRepository, @@ -72,6 +74,7 @@ internal object ManageTokensDomainModule { currenciesRepository = currenciesRepository, networksRepository = networksRepository, derivationsRepository = derivationsRepository, + stakingRepository = stakingRepository, ) } diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt index aaadb1d435..18aaa9d968 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt @@ -72,21 +72,35 @@ internal class DefaultStakingBalanceStore( override suspend fun store(userWalletId: UserWalletId, items: Set) { coroutineScope { launch { - updateRuntimeStore(userWalletId = userWalletId) { - YieldBalanceConverter(isCached = false).convertSet(input = items) + val newBalances = YieldBalanceConverter(isCached = false).convertSet(input = items) + + runtimeStore.update(default = emptyMap()) { saved -> + saved.toMutableMap().apply { + this[userWalletId] = saved[userWalletId] + ?.addOrReplace(newBalances) { old, new -> + old.integrationId == new.integrationId && old.address == new.address + } + ?: newBalances + } } } launch { storeInPersistenceStore(userWalletId = userWalletId, items = items) } } } - override suspend fun refresh(userWalletId: UserWalletId) { + override suspend fun refresh(userWalletId: UserWalletId, addressWithIntegrationIdMap: Map) { updateRuntimeStore(userWalletId = userWalletId) { saved -> - saved.mapTo(hashSetOf()) { - when (it) { - is YieldBalance.Data -> it.copy(source = StatusSource.CACHE) - is YieldBalance.Empty -> it.copy(source = StatusSource.CACHE) - is YieldBalance.Error -> it + saved.mapTo(hashSetOf()) { balance -> + val refreshIntegrationId = addressWithIntegrationIdMap[balance.address] + + if (balance.integrationId == refreshIntegrationId) { + when (balance) { + is YieldBalance.Data -> balance.copy(source = StatusSource.CACHE) + is YieldBalance.Empty -> balance.copy(source = StatusSource.CACHE) + is YieldBalance.Error -> balance + } + } else { + balance } } } @@ -114,11 +128,13 @@ internal class DefaultStakingBalanceStore( ) { val newBalance = YieldBalanceConverter(isCached = false).convert(value = item) - val balances = getSyncOrNull(userWalletId) - ?.addOrReplace(newBalance) { it.integrationId == integrationId && it.address == address } - ?: setOf(newBalance) - - updateRuntimeStore(userWalletId = userWalletId) { balances } + runtimeStore.update(default = emptyMap()) { saved -> + saved.toMutableMap().apply { + this[userWalletId] = saved[userWalletId] + ?.addOrReplace(newBalance) { it.integrationId == integrationId && it.address == address } + ?: setOf(newBalance) + } + } } private suspend fun updateRuntimeStore( @@ -135,7 +151,11 @@ internal class DefaultStakingBalanceStore( private suspend fun storeInPersistenceStore(userWalletId: UserWalletId, items: Set) { persistenceStore.updateData { current -> current.toMutableMap().apply { - this[userWalletId.stringValue] = items + this[userWalletId.stringValue] = current[userWalletId.stringValue] + ?.addOrReplace(items = items) { old, new -> + old.integrationId == new.integrationId && old.addresses.address == new.addresses.address + } + ?: items } } } @@ -159,6 +179,8 @@ internal class DefaultStakingBalanceStore( cachedBalances: Set, runtimeBalances: Set, ): Set { + if (runtimeBalances.isEmpty()) return cachedBalances + return runtimeBalances .map { runtime -> runtime.takeIf { runtime !is YieldBalance.Error } diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/StakingBalanceStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/StakingBalanceStore.kt index c09987f7f4..7722a21c10 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/StakingBalanceStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/StakingBalanceStore.kt @@ -27,5 +27,5 @@ interface StakingBalanceStore { /** Store [item] by [userWalletId], [integrationId] and [address] */ suspend fun store(userWalletId: UserWalletId, integrationId: String, address: String, item: YieldBalanceWrapperDTO) - suspend fun refresh(userWalletId: UserWalletId) + suspend fun refresh(userWalletId: UserWalletId, addressWithIntegrationIdMap: Map) } \ No newline at end of file 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 8956f6f26a..32ecdae0d4 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 @@ -403,13 +403,31 @@ internal class DefaultStakingRepository( ?: YieldBalance.Error(integrationId, address) } + @Suppress("LongMethod") override suspend fun fetchMultiYieldBalance( userWalletId: UserWalletId, cryptoCurrencies: List, refresh: Boolean, ) = withContext(dispatchers.io) { if (refresh) { - stakingBalanceStore.refresh(userWalletId = userWalletId) + stakingBalanceStore.refresh( + userWalletId = userWalletId, + addressWithIntegrationIdMap = cryptoCurrencies + .mapNotNull { currency -> + val addresses = walletManagersFacade.getAddresses(userWalletId, currency.network) + val integrationId = integrationIdMap[getIntegrationKey(currency.id)] + + if (integrationId != null) { + addresses to integrationId + } else { + null + } + } + .flatMap { (addresses, integrationId) -> + addresses.map { address -> integrationId to address.value } + } + .toMap(), + ) } cacheRegistry.invokeOnExpire( diff --git a/domain/manage-tokens/build.gradle.kts b/domain/manage-tokens/build.gradle.kts index 5ed6875afa..958503009f 100644 --- a/domain/manage-tokens/build.gradle.kts +++ b/domain/manage-tokens/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { api(projects.domain.core) implementation(projects.domain.wallets.models) implementation(projects.domain.tokens.models) + implementation(projects.domain.staking) implementation(projects.domain.tokens) implementation(projects.domain.card) implementation(projects.domain.legacy) diff --git a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt index 817a68b712..4143444b7b 100644 --- a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt +++ b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt @@ -5,6 +5,7 @@ import arrow.core.flatten import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.repository.CustomTokensRepository +import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -18,6 +19,7 @@ class SaveManagedTokensUseCase( private val currenciesRepository: CurrenciesRepository, private val networksRepository: NetworksRepository, private val derivationsRepository: DerivationsRepository, + private val stakingRepository: StakingRepository, ) { suspend operator fun invoke( @@ -50,6 +52,8 @@ class SaveManagedTokensUseCase( existingCurrencies = existingCurrencies, currenciesToAdd = addingCurrencies, ) + + refreshUpdatedYieldBalances(userWalletId, existingCurrencies) } private suspend fun removeCurrenciesFromWalletManager( @@ -90,6 +94,17 @@ class SaveManagedTokensUseCase( ) } + private suspend fun refreshUpdatedYieldBalances( + userWalletId: UserWalletId, + existingCurrencies: List, + ) { + stakingRepository.fetchMultiYieldBalance( + userWalletId = userWalletId, + cryptoCurrencies = existingCurrencies, + refresh = true, + ) + } + /** * Determines if the [existingCurrencies] list contains a coin that corresponds * to the given [network].