Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-27 18:53:11 +05:00
parent dcae84c5a6
commit 9950bde845
11 changed files with 53 additions and 24 deletions

View file

@ -206,4 +206,10 @@ internal object StakingDomainModule {
stakingErrorResolver = stakingErrorResolver,
)
}
@Provides
@Singleton
fun provideGetStakingIntegrationIdUseCase(stakingRepository: StakingRepository): GetStakingIntegrationIdUseCase {
return GetStakingIntegrationIdUseCase(stakingRepository)
}
}

View file

@ -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<Yield>, 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<Yield>? {
@ -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,

View file

@ -6,12 +6,15 @@ sealed class YieldBalanceList {
val balances: List<YieldBalance>,
) : 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
}
}

View file

@ -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)
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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<CryptoCurrency, TokenDetailsState> {
@ -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(),

View file

@ -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,
)

View file

@ -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,
)