Updated on 2026-08-14
This commit is contained in:
parent
a0d7cd3066
commit
3ca8a415cd
5 changed files with 43 additions and 31 deletions
|
|
@ -21,6 +21,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.yieldSupplyKey
|
||||
import com.tangem.domain.models.staking.YieldBalance
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
|
|
@ -41,7 +42,7 @@ import java.math.BigDecimal
|
|||
class TokenItemStateConverter(
|
||||
private val appCurrency: AppCurrency,
|
||||
private val yieldModuleApyMap: Map<String, String> = emptyMap(),
|
||||
private val stakingApyMap: Map<String, BigDecimal> = emptyMap(),
|
||||
private val stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
private val iconStateProvider: (CryptoCurrencyStatus) -> CurrencyIconState = {
|
||||
CryptoCurrencyToIconStateConverter().convert(it)
|
||||
},
|
||||
|
|
@ -156,7 +157,7 @@ class TokenItemStateConverter(
|
|||
private fun createTitleState(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): TokenItemState.TitleState {
|
||||
return when (val value = currencyStatus.value) {
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
|
|
@ -190,7 +191,7 @@ class TokenItemStateConverter(
|
|||
private fun resolveEarnApy(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): Pair<TextReference?, Boolean> {
|
||||
val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token
|
||||
if (token != null && yieldModuleApyMap.isNotEmpty()) {
|
||||
|
|
@ -210,20 +211,41 @@ class TokenItemStateConverter(
|
|||
}
|
||||
|
||||
if (stakingApyMap.isNotEmpty()) {
|
||||
val stakingKey = cryptoCurrencyStatus.currency.stakingKey()
|
||||
val stakingApy = stakingApyMap[stakingKey]?.format { percent(withPercentSign = false) }
|
||||
if (stakingApy != null) {
|
||||
val hasStakedBalance = cryptoCurrencyStatus.value.yieldBalance is YieldBalance.Data
|
||||
val (stakingRate, hasStaked) = findStakingRate(
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
stakingApyMap = stakingApyMap,
|
||||
)
|
||||
if (stakingRate != null) {
|
||||
return resourceReference(
|
||||
R.string.yield_module_earn_badge,
|
||||
wrappedList(stakingApy),
|
||||
) to hasStakedBalance
|
||||
wrappedList(stakingRate.format { percent(withPercentSign = false) }),
|
||||
) to hasStaked
|
||||
}
|
||||
}
|
||||
|
||||
return null to false
|
||||
}
|
||||
|
||||
private fun findStakingRate(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): Pair<BigDecimal?, Boolean> {
|
||||
val stakingKey = currencyStatus.currency.stakingKey()
|
||||
val validators = stakingApyMap[stakingKey] ?: return null to false
|
||||
val yieldBalance = currencyStatus.value.yieldBalance
|
||||
val hasStakedBalance = yieldBalance is YieldBalance.Data
|
||||
val rate = if (hasStakedBalance) {
|
||||
val validatorsByAddress = validators.associateBy { it.address }
|
||||
yieldBalance.balance.items
|
||||
.mapNotNull { it.validatorAddress }
|
||||
.firstNotNullOfOrNull { address -> validatorsByAddress[address]?.rewardInfo?.rate }
|
||||
?: validators.mapNotNull { it.rewardInfo?.rate }.maxOrNull()
|
||||
} else {
|
||||
validators.mapNotNull { it.rewardInfo?.rate }.maxOrNull()
|
||||
}
|
||||
return rate to hasStakedBalance
|
||||
}
|
||||
|
||||
private fun createSubtitleState(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
appCurrency: AppCurrency,
|
||||
|
|
|
|||
|
|
@ -4,34 +4,24 @@ import com.tangem.domain.staking.model.stakekit.Yield
|
|||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Emits a map of APY values per currency for staking.
|
||||
* Emits a map of Validators values per currency for staking.
|
||||
*
|
||||
* Return map:
|
||||
* - key: currency staking key (network.backendId + "_" + symbol)
|
||||
* - value: APY as string
|
||||
* - value: validators
|
||||
*/
|
||||
class StakingApyFlowUseCase(private val stakingRepository: StakingRepository) {
|
||||
|
||||
operator fun invoke(): Flow<Map<String, BigDecimal>> {
|
||||
operator fun invoke(): Flow<Map<String, List<Yield.Validator>>> {
|
||||
return stakingRepository.getEnabledYields()
|
||||
.map { yields ->
|
||||
yields.associate { yield ->
|
||||
val key = "${yield.token.coinGeckoId}_${yield.token.symbol}"
|
||||
val apy = calculateApy(yield)
|
||||
val apy = yield.validators
|
||||
key to apy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateApy(yield: Yield): BigDecimal {
|
||||
val rates = yield.validators.mapNotNull { it.rewardInfo?.rate }
|
||||
return if (rates.isNotEmpty()) {
|
||||
rates.maxOf { it }
|
||||
} else {
|
||||
yield.apy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
|||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
|
|
@ -10,7 +11,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.transformers.converte
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TokenListStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.enableButtons
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class SetTokenListTransformer(
|
||||
private val params: TokenConverterParams,
|
||||
|
|
@ -18,7 +18,7 @@ internal class SetTokenListTransformer(
|
|||
private val appCurrency: AppCurrency,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val yieldSupplyApyMap: Map<String, String> = emptyMap(),
|
||||
private val stakingApyMap: Map<String, BigDecimal> = emptyMap(),
|
||||
private val stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
) : WalletStateTransformer(userWallet.walletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
import com.tangem.domain.models.tokenlist.TokenList.GroupedByNetwork.NetworkGroup
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
|
||||
|
|
@ -27,7 +28,6 @@ import kotlinx.collections.immutable.PersistentList
|
|||
import kotlinx.collections.immutable.mutate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState.OrganizeTokensButtonConfig as WalletOrganizeTokensButtonConfig
|
||||
|
||||
internal class TokenListStateConverter(
|
||||
|
|
@ -36,7 +36,7 @@ internal class TokenListStateConverter(
|
|||
private val selectedWallet: UserWallet,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val yieldModuleApyMap: Map<String, String>,
|
||||
private val stakingApyMap: Map<String, BigDecimal>,
|
||||
private val stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
) : Converter<WalletTokensListState, WalletTokensListState> {
|
||||
|
||||
private val onTokenClick: (accountId: AccountId?, currencyStatus: CryptoCurrencyStatus) -> Unit =
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.domain.models.account.AccountStatus
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
|
|
@ -33,7 +34,6 @@ import kotlinx.coroutines.flow.*
|
|||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal abstract class BasicTokenListSubscriber : WalletSubscriber() {
|
||||
|
|
@ -103,7 +103,7 @@ internal abstract class BasicTokenListSubscriber : WalletSubscriber() {
|
|||
appCurrency: AppCurrency,
|
||||
portfolioId: PortfolioId,
|
||||
yieldSupplyApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
) {
|
||||
val tokenList = maybeTokenList.getOrElse(
|
||||
ifLoading = { maybeContent ->
|
||||
|
|
@ -242,7 +242,7 @@ internal abstract class BasicTokenListSubscriber : WalletSubscriber() {
|
|||
params: TokenConverterParams,
|
||||
appCurrency: AppCurrency,
|
||||
yieldSupplyApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
) {
|
||||
stateHolder.update(
|
||||
SetTokenListTransformer(
|
||||
|
|
@ -268,6 +268,6 @@ internal abstract class BasicTokenListSubscriber : WalletSubscriber() {
|
|||
private fun yieldSupplyApyFlow(): Flow<Map<String, String>> = yieldSupplyApyFlowUseCase()
|
||||
.distinctUntilChanged()
|
||||
|
||||
private fun stakingApyFlow(): Flow<Map<String, BigDecimal>> = stakingApyFlowUseCase()
|
||||
private fun stakingApyFlow(): Flow<Map<String, List<Yield.Validator>>> = stakingApyFlowUseCase()
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue