Updated on 2026-08-14
This commit is contained in:
parent
f807fe288f
commit
c9fca04205
4 changed files with 68 additions and 29 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.common.ui.tokens
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
|
|
@ -21,6 +22,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.isStakingSupported
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
|
|
@ -211,15 +213,22 @@ class TokenItemStateConverter(
|
|||
}
|
||||
|
||||
if (stakingApyMap.isNotEmpty()) {
|
||||
val (stakingRate, hasStaked) = findStakingRate(
|
||||
val stakingInfo = findStakingRate(
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
stakingApyMap = stakingApyMap,
|
||||
)
|
||||
if (stakingRate != null) {
|
||||
val rewardTypeRes = when (stakingInfo.rewardType) {
|
||||
Yield.RewardType.APR -> R.string.staking_apr_earn_badge
|
||||
Yield.RewardType.UNKNOWN,
|
||||
Yield.RewardType.APY,
|
||||
null,
|
||||
-> R.string.yield_module_earn_badge
|
||||
}
|
||||
if (stakingInfo.rate != null) {
|
||||
return resourceReference(
|
||||
R.string.yield_module_earn_badge,
|
||||
wrappedList(stakingRate.format { percent(withPercentSign = false) }),
|
||||
) to hasStaked
|
||||
rewardTypeRes,
|
||||
wrappedList(stakingInfo.rate.format { percent(withPercentSign = false) }),
|
||||
) to stakingInfo.isActive
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,21 +238,46 @@ class TokenItemStateConverter(
|
|||
private fun findStakingRate(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): Pair<BigDecimal?, Boolean> {
|
||||
): StakingLocalInfo {
|
||||
val stakingKey = currencyStatus.currency.stakingKey()
|
||||
val validators = stakingApyMap[stakingKey] ?: return null to false
|
||||
val validators = stakingApyMap[stakingKey]
|
||||
?: return StakingLocalInfo(rate = null, isActive = false, rewardType = null)
|
||||
|
||||
val yieldBalance = currencyStatus.value.yieldBalance
|
||||
val hasStakedBalance = yieldBalance is YieldBalance.Data
|
||||
val rate = if (hasStakedBalance) {
|
||||
|
||||
val rateInfo: Pair<BigDecimal, Yield.RewardType?>? = 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()
|
||||
.firstNotNullOfOrNull { address ->
|
||||
val validator = validatorsByAddress[address]
|
||||
validator?.rewardInfo?.rate?.let { rate ->
|
||||
rate to validator.rewardInfo?.type
|
||||
}
|
||||
}
|
||||
?: validators
|
||||
.filter { it.preferred }
|
||||
.mapNotNull { validator ->
|
||||
validator.rewardInfo?.rate?.let { rate -> rate to validator.rewardInfo?.type }
|
||||
}
|
||||
.maxByOrNull { it.first }
|
||||
} else {
|
||||
validators.mapNotNull { it.rewardInfo?.rate }.maxOrNull()
|
||||
validators
|
||||
.filter { it.preferred }
|
||||
.mapNotNull { validator ->
|
||||
validator.rewardInfo?.rate?.let { rate ->
|
||||
rate to validator.rewardInfo?.type
|
||||
}
|
||||
}
|
||||
.maxByOrNull { it.first }
|
||||
}
|
||||
return rate to hasStakedBalance
|
||||
|
||||
return StakingLocalInfo(
|
||||
rate = rateInfo?.first,
|
||||
isActive = hasStakedBalance,
|
||||
rewardType = rateInfo?.second,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSubtitleState(
|
||||
|
|
@ -353,7 +387,21 @@ class TokenItemStateConverter(
|
|||
fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = sources.total == StatusSource.CACHE
|
||||
|
||||
private fun CryptoCurrency.stakingKey(): String {
|
||||
return "${network.backendId}_$symbol"
|
||||
if (this is CryptoCurrency.Coin && !network.isStakingSupported) return ""
|
||||
|
||||
if (network.isStakingSupported && this !is CryptoCurrency.Coin) {
|
||||
val isPolygonTokenOnEthereum = this is CryptoCurrency.Token &&
|
||||
this.network.id.rawId.value == Blockchain.Ethereum.id &&
|
||||
this.symbol == Blockchain.Polygon.currency
|
||||
if (!isPolygonTokenOnEthereum) return ""
|
||||
}
|
||||
return "${id.rawCurrencyId}_$symbol"
|
||||
}
|
||||
}
|
||||
|
||||
private data class StakingLocalInfo(
|
||||
val rate: BigDecimal?,
|
||||
val isActive: Boolean,
|
||||
val rewardType: Yield.RewardType?,
|
||||
)
|
||||
}
|
||||
|
|
@ -1155,6 +1155,7 @@
|
|||
<string name="staking_amount_requirement_error">The amount to stake must be at least %s</string>
|
||||
<string name="staking_amount_tron_integer_error">Staking amount will be rounded to %1$s TRX due to network rules.</string>
|
||||
<string name="staking_amount_tron_integer_error_unstaking">Unstaking amount will be rounded to %1$s TRX due to network rules.</string>
|
||||
<string name="staking_apr_earn_badge">APR %1$s%%</string>
|
||||
<string name="staking_claim_unstaked">Claim unstaked</string>
|
||||
<string name="staking_details_account_fee">Stake account fee</string>
|
||||
<string name="staking_details_account_fee_info">A staking account is a special account where staked SOL tokens are stored. It is created when you delegate your tokens to a validator to participate in transaction validation and receive rewards. A small fee is charged for creating the staking account, which is returned after the staking is completed.</string>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.domain.staking.model
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toMigratedCoinId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
||||
/**
|
||||
* Represents a staking integration identifier.
|
||||
|
|
@ -143,6 +145,9 @@ sealed interface StakingIntegrationID {
|
|||
}
|
||||
}
|
||||
|
||||
val Network.isStakingSupported: Boolean
|
||||
get() = this.toBlockchain().isStakingSupported
|
||||
|
||||
/**
|
||||
* Extension property to check if staking is supported for a blockchain.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package com.tangem.domain.staking.usecase
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.staking.model.StakingIntegrationID
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -21,22 +18,10 @@ class StakingApyFlowUseCase(private val stakingRepository: StakingRepository) {
|
|||
return stakingRepository.getEnabledYields()
|
||||
.map { yields ->
|
||||
yields.associate { yield ->
|
||||
val key = composeKey(yield)
|
||||
val key = "${yield.token.coinGeckoId}_${yield.token.symbol}"
|
||||
val apy = yield.validators
|
||||
key to apy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// so that cause for api.stakek.it coinGeckoId on BNB Smart chain different how we receive our backendId
|
||||
// coinGeckoId - binance
|
||||
// our backendId BNB Smart Chain - binance-smart-chain
|
||||
// our backendId BNB Beacon Chain - binance
|
||||
private fun composeKey(yield: Yield): String {
|
||||
return if (yield.token.symbol == StakingIntegrationID.Coin.BSC.blockchain.currency) {
|
||||
"${Blockchain.BSC.toNetworkId()}_${yield.token.symbol}"
|
||||
} else {
|
||||
"${yield.token.coinGeckoId}_${yield.token.symbol}"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue