Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-17 14:05:58 +03:00
commit 3cbc2dadfb
822 changed files with 12838 additions and 5366 deletions

View file

@ -535,6 +535,7 @@ internal class TokenDetailsModel @Inject constructor(
token = cryptoCurrency.symbol,
blockchain = cryptoCurrency.network.name,
status = unavailabilityReason.toReasonAnalyticsText(),
derivationIndex = getAccountIndexOrNull(),
),
)
@ -560,6 +561,7 @@ internal class TokenDetailsModel @Inject constructor(
token = cryptoCurrency.symbol,
blockchain = cryptoCurrency.network.name,
status = null,
derivationIndex = getAccountIndexOrNull(),
),
)
router.openTokenDetails(userWalletId = userWalletId, currency = cryptoCurrency)
@ -581,6 +583,7 @@ internal class TokenDetailsModel @Inject constructor(
token = cryptoCurrency.symbol,
blockchain = cryptoCurrency.network.name,
status = unavailabilityReason.toReasonAnalyticsText(),
derivationIndex = getAccountIndexOrNull(),
),
)
@ -701,6 +704,7 @@ internal class TokenDetailsModel @Inject constructor(
token = cryptoCurrency.symbol,
blockchain = cryptoCurrency.network.name,
status = unavailabilityReason.toReasonAnalyticsText(),
derivationIndex = getAccountIndexOrNull(),
),
)
@ -769,6 +773,12 @@ internal class TokenDetailsModel @Inject constructor(
showErrorIfDemoModeOrElse(action = ::openExplorer)
}
private fun getAccountIndexOrNull(): Int? {
val account = account
val isNotMainAccount = account != null && !account.isMainAccount
return if (isNotMainAccount) account.derivationIndex.value else null
}
private fun openExplorer() {
val currencyStatus = cryptoCurrencyStatus ?: return
@ -881,7 +891,7 @@ internal class TokenDetailsModel @Inject constructor(
PromoAnalyticsEvent.PromotionBannerClicked(
source = AnalyticsParam.ScreensSources.Token,
program = PromoAnalyticsEvent.Program.Empty, // Use it on new promo action
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Closed,
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Closed(),
),
)
}
@ -894,7 +904,7 @@ internal class TokenDetailsModel @Inject constructor(
PromoAnalyticsEvent.PromotionBannerClicked(
source = AnalyticsParam.ScreensSources.Token,
program = PromoAnalyticsEvent.Program.Empty, // Use it on new promo action
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Clicked,
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Clicked(),
),
)
}

View file

@ -5,7 +5,7 @@ import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.YieldBalance
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance
@ -29,8 +29,8 @@ internal class TokenDetailsBalanceSelectStateConverter(
return this
}
val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data
val stakingCryptoAmount = yieldBalance?.getTotalWithRewardsStakingBalance(
val stakingBalance = cryptoCurrencyStatus.value.stakingBalance as? StakingBalance.Data
val stakingCryptoAmount = stakingBalance?.getTotalWithRewardsStakingBalance(
cryptoCurrencyStatus.currency.network.rawId,
)
val stakingFiatAmount = stakingCryptoAmount?.let { cryptoCurrencyStatus.value.fiatRate?.multiply(it) }

View file

@ -9,7 +9,7 @@ import com.tangem.core.ui.format.bigdecimal.*
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.YieldBalance
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
@ -73,7 +73,7 @@ internal class TokenDetailsLoadedBalanceConverter(
status: CryptoCurrencyStatus,
): TokenDetailsBalanceBlockState {
val stakingCryptoAmount =
(status.value.yieldBalance as? YieldBalance.Data)?.getTotalWithRewardsStakingBalance(
(status.value.stakingBalance as? StakingBalance.Data)?.getTotalWithRewardsStakingBalance(
status.currency.network.rawId,
)
val stakingFiatAmount = stakingCryptoAmount?.let { status.value.fiatRate?.multiply(it) }

View file

@ -83,9 +83,9 @@ internal class TokenDetailsOnrampTransactionStateConverter(
fallbackResId = R.drawable.ic_currency_24,
),
iconState = getIconState(value.status),
onGoToProviderClick = {
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider)
clickIntents.onGoToProviderClick(it)
onGoToProviderClick = { url ->
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider())
clickIntents.onGoToProviderClick(url)
},
onClick = { clickIntents.onExpressTransactionClick(value.txId) },
onDisposeExpressStatus = clickIntents::onConfirmDisposeExpressStatus,
@ -117,7 +117,7 @@ internal class TokenDetailsOnrampTransactionStateConverter(
private fun onProviderClick(externalTxUrl: String?) = if (externalTxUrl != null) {
{
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider)
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider())
clickIntents.onGoToProviderClick(externalTxUrl)
}
} else {
@ -269,7 +269,7 @@ internal class TokenDetailsOnrampTransactionStateConverter(
icon = R.drawable.ic_arrow_top_right_24,
text = resourceReference(R.string.common_go_to_provider),
onClick = {
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider)
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider())
clickIntents.onGoToProviderClick(externalTxUrl)
},
)

View file

@ -10,7 +10,7 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.RewardBlockType
import com.tangem.domain.models.staking.YieldBalance
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingEntryInfo
import com.tangem.domain.staking.utils.getRewardStakingBalance
@ -54,18 +54,29 @@ internal class TokenDetailsStakingInfoConverter(
}
}
@Suppress("CyclomaticComplexMethod")
private fun getStakingInfoBlock(status: CryptoCurrencyStatus, state: TokenDetailsState): StakingBlockUM? {
val yieldBalance = status.value.yieldBalance as? YieldBalance.Data
val stakingBalance = status.value.stakingBalance as? StakingBalance.Data
val stakingCryptoAmount = yieldBalance?.getTotalStakingBalance(status.currency.network.rawId)
val pendingBalances = yieldBalance?.balance?.items ?: emptyList()
val stakingCryptoAmount = stakingBalance?.getTotalStakingBalance(status.currency.network.rawId)
val hasPendingBalances = when (stakingBalance) {
is StakingBalance.Data.StakeKit -> stakingBalance.balance.items.isNotEmpty()
is StakingBalance.Data.P2P -> !stakingBalance.unstakingAmount.isNullOrZero()
null -> false
}
val pendingAmount = when (stakingBalance) {
is StakingBalance.Data.StakeKit -> stakingBalance.balance.items.sumOf { it.amount }
is StakingBalance.Data.P2P -> stakingBalance.unstakingAmount
null -> BigDecimal.ZERO
}
val iconState = state.tokenInfoBlockState.iconState
Timber.i(
"""
getStakingInfoBlock:
yieldBalance: $yieldBalance
stakingBalance: ${stakingBalance ?: "null"}
stakingCryptoAmount: $stakingCryptoAmount
stakingEntryInfo: $stakingEntryInfo
""".trimIndent(),
@ -73,16 +84,24 @@ internal class TokenDetailsStakingInfoConverter(
return when {
stakingCryptoAmount.isNullOrZero() && stakingEntryInfo != null -> {
if (pendingBalances.isEmpty()) {
if (!hasPendingBalances) {
getStakeAvailableState(stakingEntryInfo, iconState, isStakingButtonEnabled(status))
} else {
getStakedBlockWithFiatAmount(status, pendingBalances.sumOf { it.amount }, null)
getStakedBlockWithFiatAmount(status, pendingAmount, null)
}
}
stakingCryptoAmount.isNullOrZero() && stakingEntryInfo == null -> {
null
}
else -> getStakedBlockWithFiatAmount(status, stakingCryptoAmount, yieldBalance?.getRewardStakingBalance())
else -> getStakedBlockWithFiatAmount(
status = status,
stakingAmount = stakingCryptoAmount,
rewardAmount = when (stakingBalance) {
is StakingBalance.Data.StakeKit -> stakingBalance.getRewardStakingBalance()
is StakingBalance.Data.P2P -> stakingBalance.totalRewards
else -> BigDecimal.ZERO
},
)
}
}