From 9950bde8455ec5dc8516cd65391314be6d0ff0d8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 27 Sep 2024 18:53:11 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/di/domain/StakingDomainModule.kt | 6 ++++++ .../data/staking/DefaultStakingRepository.kt | 14 ++++++++------ .../staking/model/stakekit/YieldBalanceList.kt | 11 +++++++---- .../staking/GetStakingIntegrationIdUseCase.kt | 12 ++++++++++++ .../staking/repositories/StakingRepository.kt | 2 +- .../operations/CurrenciesStatusesLceOperations.kt | 8 +++----- .../operations/CurrenciesStatusesOperations.kt | 8 +++----- .../tokens/repository/MockStakingRepository.kt | 4 ++-- .../factory/TokenDetailsSkeletonStateConverter.kt | 6 +++++- .../state/factory/TokenDetailsStateFactory.kt | 3 +++ .../viewmodels/TokenDetailsViewModel.kt | 3 +++ 11 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 domain/staking/src/main/java/com/tangem/domain/staking/GetStakingIntegrationIdUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt index 0807a628f1..bc9b31d6fe 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt @@ -206,4 +206,10 @@ internal object StakingDomainModule { stakingErrorResolver = stakingErrorResolver, ) } + + @Provides + @Singleton + fun provideGetStakingIntegrationIdUseCase(stakingRepository: StakingRepository): GetStakingIntegrationIdUseCase { + return GetStakingIntegrationIdUseCase(stakingRepository) + } } \ 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 5251158860..c21f12dc95 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 @@ -111,8 +111,8 @@ internal class DefaultStakingRepository( rawNetworkId.plus(rawCurrencyId) } - override fun isStakingSupportedInMobileApp(integrationKey: String): Boolean { - return integrationIdMap.containsKey(integrationKey) + override fun getSupportedIntegrationId(cryptoCurrencyId: CryptoCurrency.ID): String? { + return integrationIdMap.getOrDefault(getIntegrationKey(cryptoCurrencyId), null) } override suspend fun fetchEnabledYields(refresh: Boolean) { @@ -166,7 +166,7 @@ internal class DefaultStakingRepository( val rawCurrencyId = cryptoCurrency.id.rawCurrencyId ?: return StakingAvailability.Unavailable return withContext(dispatchers.io) { - val isSupportedInMobileApp = isStakingSupportedInMobileApp(getIntegrationKey(cryptoCurrency.id)) + val isSupportedInMobileApp = getSupportedIntegrationId(cryptoCurrency.id).isNullOrEmpty().not() val yields = getEnabledYields() ?: return@withContext if (isSupportedInMobileApp) { StakingAvailability.TemporaryUnavailable @@ -575,7 +575,9 @@ internal class DefaultStakingRepository( } private fun findPrefetchedYield(yields: List, currencyId: String, symbol: String): Yield? { - return yields.find { it.token.coinGeckoId == currencyId && it.token.symbol == symbol } + return yields.find { yield -> + yield.tokens.any { it.coinGeckoId == currencyId && it.symbol == symbol } + } } private suspend fun getEnabledYields(): List? { @@ -633,8 +635,8 @@ internal class DefaultStakingRepository( Blockchain.Solana.run { id + toCoinId() } to SOLANA_INTEGRATION_ID, Blockchain.Cosmos.run { id + toCoinId() } to COSMOS_INTEGRATION_ID, Blockchain.Tron.run { id + toCoinId() } to TRON_INTEGRATION_ID, - // Blockchain.Ethereum.id + Blockchain.Polygon.toCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID, - // Blockchain.BSC.run { id + toCoinId() } to BINANCE_INTEGRATION_ID, + Blockchain.Ethereum.id + Blockchain.Polygon.toCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID, + Blockchain.BSC.run { id + toCoinId() } to BINANCE_INTEGRATION_ID, // Blockchain.Polkadot.run { id + toCoinId() } to POLKADOT_INTEGRATION_ID, // Blockchain.Avalanche.run { id + toCoinId() } to AVALANCHE_INTEGRATION_ID, // Blockchain.Cronos.run { id + toCoinId() } to CRONOS_INTEGRATION_ID, diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalanceList.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalanceList.kt index 02f20f6e1c..7b8e993734 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalanceList.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalanceList.kt @@ -6,12 +6,15 @@ sealed class YieldBalanceList { val balances: List, ) : YieldBalanceList() { - fun getBalance(address: String?, rawCurrencyId: String?): YieldBalance { + fun getBalance(address: String?, integrationId: String?): YieldBalance { return balances.firstOrNull { yieldBalance -> val data = yieldBalance as? YieldBalance.Data - data?.balance?.items?.any { - address == data.address && rawCurrencyId == it.rawCurrencyId - } == true + val balance = data?.balance + + val isCorrectAddress = balance?.items?.any { address == data.address } == true + val isCorrectIntegration = balance?.integrationId == integrationId + + isCorrectIntegration && isCorrectAddress } ?: YieldBalance.Error } } diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingIntegrationIdUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingIntegrationIdUseCase.kt new file mode 100644 index 0000000000..719a2ef4c3 --- /dev/null +++ b/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingIntegrationIdUseCase.kt @@ -0,0 +1,12 @@ +package com.tangem.domain.staking + +import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.model.CryptoCurrency + +class GetStakingIntegrationIdUseCase( + private val stakingRepository: StakingRepository, +) { + + operator fun invoke(cryptoCurrencyId: CryptoCurrency.ID) = + stakingRepository.getSupportedIntegrationId(cryptoCurrencyId) +} \ No newline at end of file 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 3484bc6151..e82d0fb40a 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 @@ -23,7 +23,7 @@ interface StakingRepository { fun getIntegrationKey(cryptoCurrencyId: CryptoCurrency.ID): String - fun isStakingSupportedInMobileApp(integrationKey: String): Boolean + fun getSupportedIntegrationId(cryptoCurrencyId: CryptoCurrency.ID): String? suspend fun fetchEnabledYields(refresh: Boolean) 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 3729f8ff2c..419842f017 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 @@ -147,13 +147,11 @@ internal class CurrenciesStatusesLceOperations( val quote = quotes?.firstOrNull { it.rawCurrencyId == currency.id.rawCurrencyId } val networkStatus = networksStatuses?.firstOrNull { it.network == currency.network } val address = extractAddress(networkStatus) - val isStakingSupported = stakingRepository.isStakingSupportedInMobileApp( - stakingRepository.getIntegrationKey(currency.id), - ) - val yieldBalance = if (isStakingSupported) { + val supportedIntegration = stakingRepository.getSupportedIntegrationId(currency.id) + val yieldBalance = if (supportedIntegration.isNullOrBlank().not()) { (yieldBalances as? YieldBalanceList.Data)?.getBalance( address = address, - rawCurrencyId = currency.id.rawCurrencyId, + integrationId = supportedIntegration, ) } else { null diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt index a7e0233a4b..34ac4153c2 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt @@ -271,13 +271,11 @@ internal class CurrenciesStatusesOperations( val networkStatus = networksStatuses?.firstOrNull { it.network == currency.network } val address = extractAddress(networkStatus) - val isStakingSupported = stakingRepository.isStakingSupportedInMobileApp( - stakingRepository.getIntegrationKey(currency.id), - ) - val yieldBalance = if (isStakingSupported) { + val supportedIntegration = stakingRepository.getSupportedIntegrationId(currency.id) + val yieldBalance = if (supportedIntegration.isNullOrEmpty().not()) { (yieldBalances as? YieldBalanceList.Data)?.getBalance( address = address, - rawCurrencyId = currency.id.rawCurrencyId, + integrationId = supportedIntegration, ) } else { null 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 36242e041b..647a1a411d 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 @@ -24,9 +24,9 @@ import java.math.BigDecimal class MockStakingRepository : StakingRepository { - override fun getIntegrationKey(cryptoCurrencyId: CryptoCurrency.ID): String = "" + override fun getSupportedIntegrationId(cryptoCurrencyId: CryptoCurrency.ID): String? = null - override fun isStakingSupportedInMobileApp(integrationKey: String): Boolean = true + override fun getIntegrationKey(cryptoCurrencyId: CryptoCurrency.ID): String = "" override suspend fun fetchEnabledYields(refresh: Boolean) { /* no-op */ diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt index 04de376869..98850f08f2 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt @@ -10,6 +10,7 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.card.NetworkHasDerivationUseCase +import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network import com.tangem.domain.wallets.models.UserWalletId @@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.MutableStateFlow internal class TokenDetailsSkeletonStateConverter( private val clickIntents: TokenDetailsClickIntents, private val networkHasDerivationUseCase: NetworkHasDerivationUseCase, + private val getStakingIntegrationIdUseCase: GetStakingIntegrationIdUseCase, private val getUserWalletUseCase: GetUserWalletUseCase, private val userWalletId: UserWalletId, ) : Converter { @@ -36,6 +38,8 @@ internal class TokenDetailsSkeletonStateConverter( override fun convert(value: CryptoCurrency): TokenDetailsState { val iconState = iconStateConverter.convert(value) + val isSupportedInMobileApp = getStakingIntegrationIdUseCase(value.id).isNullOrBlank().not() + return TokenDetailsState( topAppBarConfig = TokenDetailsTopAppBarConfig( onBackClick = clickIntents::onBackClick, @@ -59,7 +63,7 @@ internal class TokenDetailsSkeletonStateConverter( selectedBalanceType = BalanceType.ALL, ), marketPriceBlockState = MarketPriceBlockState.Loading(value.symbol), - stakingBlocksState = StakingBlockUM.Loading(iconState), + stakingBlocksState = StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp }, notifications = persistentListOf(), pendingTxs = persistentListOf(), swapTxs = persistentListOf(), diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt index 133ebb4f93..c3bc29d4a4 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt @@ -17,6 +17,7 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.card.NetworkHasDerivationUseCase import com.tangem.domain.common.CardTypesResolver +import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo import com.tangem.domain.tokens.error.CurrencyStatusError @@ -56,6 +57,7 @@ internal class TokenDetailsStateFactory( private val getUserWalletUseCase: GetUserWalletUseCase, private val userWalletId: UserWalletId, stakingFeatureToggles: StakingFeatureToggles, + getStakingIntegrationIdUseCase: GetStakingIntegrationIdUseCase, symbol: String, decimals: Int, ) { @@ -64,6 +66,7 @@ internal class TokenDetailsStateFactory( TokenDetailsSkeletonStateConverter( clickIntents = clickIntents, networkHasDerivationUseCase = networkHasDerivationUseCase, + getStakingIntegrationIdUseCase = getStakingIntegrationIdUseCase, getUserWalletUseCase = getUserWalletUseCase, userWalletId = userWalletId, ) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index ab322bc724..d85c3693a2 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -34,6 +34,7 @@ import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.settings.ShouldShowSwapPromoTokenUseCase import com.tangem.domain.staking.GetStakingAvailabilityUseCase import com.tangem.domain.staking.GetStakingEntryInfoUseCase +import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.staking.GetYieldUseCase import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo @@ -123,6 +124,7 @@ internal class TokenDetailsViewModel @Inject constructor( private val vibratorHapticManager: VibratorHapticManager, private val clipboardManager: ClipboardManager, getUserWalletUseCase: GetUserWalletUseCase, + getStakingIntegrationIdUseCase: GetStakingIntegrationIdUseCase, deepLinksRegistry: DeepLinksRegistry, savedStateHandle: SavedStateHandle, private val appRouter: AppRouter, @@ -163,6 +165,7 @@ internal class TokenDetailsViewModel @Inject constructor( getUserWalletUseCase = getUserWalletUseCase, userWalletId = userWalletId, stakingFeatureToggles = stakingFeatureToggles, + getStakingIntegrationIdUseCase = getStakingIntegrationIdUseCase, symbol = cryptoCurrency.symbol, decimals = cryptoCurrency.decimals, )