Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-04 19:47:22 +05:00
parent 2cf60002a4
commit a7f5b54078
17 changed files with 319 additions and 336 deletions

View file

@ -9,37 +9,29 @@ import com.tangem.domain.staking.model.stakekit.Yield
import kotlinx.collections.immutable.ImmutableList
import java.math.BigDecimal
sealed class InnerYieldBalanceState {
internal sealed class InnerYieldBalanceState {
data class Data(
val rewardsCrypto: String,
val rewardsFiat: String,
val rewardBlockType: RewardBlockType,
val balance: ImmutableList<BalanceGroupedState>,
val balance: ImmutableList<BalanceState>,
) : InnerYieldBalanceState()
data object Empty : InnerYieldBalanceState()
}
// TODO staking get rid of unstable types
@Immutable
data class BalanceGroupedState(
val items: ImmutableList<BalanceState>,
val footer: TextReference?,
internal data class BalanceState(
val id: String,
val title: TextReference,
val type: BalanceType,
val subtitle: TextReference?,
val isClickable: Boolean,
)
@Immutable
data class BalanceState(
val validator: Yield.Validator?,
val title: TextReference,
val cryptoValue: String,
val cryptoDecimal: BigDecimal,
val cryptoAmount: TextReference,
val fiatAmount: TextReference,
val rawCurrencyId: String?,
val unbondingPeriod: TextReference,
val warmupPeriod: TextReference,
val validator: Yield.Validator?,
val pendingActions: ImmutableList<PendingAction>,
)

View file

@ -0,0 +1,125 @@
package com.tangem.features.staking.impl.presentation.state.converters
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.staking.model.stakekit.BalanceItem
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.BalanceType.Companion.isClickable
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toPersistentList
import org.joda.time.DateTime
import java.util.Calendar
internal class BalanceItemConverter(
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val yield: Yield,
) : Converter<BalanceItem, BalanceState?> {
override fun convert(value: BalanceItem): BalanceState? {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val appCurrency = appCurrencyProvider()
val cryptoCurrency = cryptoCurrencyStatus.currency
val validator = yield.validators.firstOrNull {
value.validatorAddress?.contains(it.address, ignoreCase = true) == true
}
val cryptoAmount = value.amount
val fiatAmount = cryptoCurrencyStatus.value.fiatRate?.times(cryptoAmount)
val title = value.type.getTitle(validator?.name)
return title?.let {
BalanceState(
id = value.id,
validator = validator,
title = title,
subtitle = getSubtitle(value),
type = value.type,
cryptoValue = cryptoAmount.parseBigDecimal(cryptoCurrency.decimals),
cryptoDecimal = cryptoAmount,
cryptoAmount = stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = cryptoAmount,
cryptoCurrency = cryptoCurrency,
),
),
fiatAmount = stringReference(
BigDecimalFormatter.formatFiatAmount(
fiatAmount = fiatAmount,
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
),
),
rawCurrencyId = value.rawCurrencyId,
pendingActions = value.pendingActions.toPersistentList(),
isClickable = value.type.isClickable(),
)
}
}
private fun BalanceType.getTitle(validatorName: String?) = when (this) {
BalanceType.STAKED -> validatorName?.let { stringReference(it) }
BalanceType.PREPARING -> resourceReference(R.string.staking_preparing)
BalanceType.UNSTAKED -> resourceReference(R.string.staking_unstaked)
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking)
BalanceType.LOCKED -> resourceReference(R.string.staking_locked)
BalanceType.AVAILABLE,
BalanceType.REWARDS,
BalanceType.UNLOCKING,
BalanceType.UNKNOWN,
-> null
}
private fun getSubtitle(balance: BalanceItem) = when (balance.type) {
BalanceType.UNSTAKING -> getUnbondingDate(balance.date)
BalanceType.UNSTAKED -> resourceReference(R.string.staking_tap_to_withdraw)
BalanceType.LOCKED -> resourceReference(R.string.staking_tap_to_unlock)
BalanceType.AVAILABLE,
BalanceType.STAKED,
BalanceType.PREPARING,
BalanceType.UNLOCKING,
BalanceType.REWARDS,
BalanceType.UNKNOWN,
-> null
}
private fun getUnbondingDate(date: DateTime?): TextReference {
val now = DateTime.now().millis
val nowCalendar = Calendar.getInstance()
nowCalendar.resetHours()
val endDate = Calendar.getInstance()
endDate.timeInMillis = date?.millis ?: now
endDate.resetHours()
val days = ((endDate.timeInMillis - nowCalendar.timeInMillis) / DAY_IN_MILLIS).toInt()
return if (days > 0) {
resourceReference(
R.string.common_left,
wrappedList(
pluralReference(R.plurals.common_days, days, wrappedList(days)),
),
)
} else {
resourceReference(R.string.common_today)
}
}
private fun Calendar.resetHours() {
this[Calendar.HOUR_OF_DAY] = 0
this[Calendar.MINUTE] = 0
this[Calendar.SECOND] = 0
this[Calendar.MILLISECOND] = 0
}
private companion object {
const val DAY_IN_MILLIS = 24 * 60 * 60 * 1000
}
}

View file

@ -1,19 +1,18 @@
package com.tangem.features.staking.impl.presentation.state.converters
import com.tangem.core.ui.extensions.pluralReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.staking.model.stakekit.*
import com.tangem.domain.staking.model.stakekit.BalanceItem
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.StakingStates
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
import java.math.BigDecimal
@ -49,23 +48,21 @@ internal class RewardsValidatorStateConverter(
val fiatValue = cryptoCurrencyStatus.value.fiatRate?.times(cryptoValue)
validator?.toBalanceState(
balance = balance,
cryptoCurrencyStatus = cryptoCurrencyStatus,
cryptoValue = cryptoValue,
fiatValue = fiatValue,
pendingActions = balance.pendingActions.toPersistentList(),
)
}
private fun Yield.Validator.toBalanceState(
balance: BalanceItem,
cryptoCurrencyStatus: CryptoCurrencyStatus,
cryptoValue: BigDecimal,
fiatValue: BigDecimal?,
pendingActions: ImmutableList<PendingAction>,
): BalanceState {
val appCurrency = appCurrencyProvider()
val cryptoCurrency = cryptoCurrencyStatus.currency
val unbondingPeriod = yield.metadata.cooldownPeriod.days
val warmupPeriod = yield.metadata.warmupPeriod.days
val cryptoAmount = stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = cryptoValue,
@ -81,24 +78,18 @@ internal class RewardsValidatorStateConverter(
)
return BalanceState(
id = balance.id,
validator = this,
title = stringReference(this.name),
subtitle = null,
cryptoValue = cryptoValue.parseBigDecimal(cryptoCurrency.decimals),
cryptoDecimal = cryptoValue,
cryptoAmount = cryptoAmount,
fiatAmount = fiatAmount,
rawCurrencyId = cryptoCurrency.id.rawCurrencyId,
unbondingPeriod = pluralReference(
id = R.plurals.common_days,
count = unbondingPeriod,
formatArgs = wrappedList(unbondingPeriod),
),
warmupPeriod = pluralReference(
id = R.plurals.common_days,
count = unbondingPeriod,
formatArgs = wrappedList(warmupPeriod),
),
pendingActions = pendingActions,
pendingActions = balance.pendingActions.toPersistentList(),
isClickable = true,
type = balance.type,
)
}
}

View file

@ -1,29 +1,26 @@
package com.tangem.features.staking.impl.presentation.state.converters
import com.tangem.common.extensions.isZero
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.staking.model.stakekit.*
import com.tangem.domain.staking.model.stakekit.BalanceType.Companion.isClickable
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
import com.tangem.lib.crypto.BlockchainUtils.isSolana
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toPersistentList
import org.joda.time.DateTime
import java.util.Calendar
internal class YieldBalancesConverter(
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val yield: Yield,
) : Converter<Unit, InnerYieldBalanceState> {
private val balanceItemConverter by lazy(LazyThreadSafetyMode.NONE) {
BalanceItemConverter(cryptoCurrencyStatusProvider, appCurrencyProvider, yield)
}
override fun convert(value: Unit): InnerYieldBalanceState {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val appCurrency = appCurrencyProvider()
@ -34,7 +31,6 @@ internal class YieldBalancesConverter(
return if (yieldBalance is YieldBalance.Data) {
val cryptoRewardsValue = yieldBalance.getRewardStakingBalance()
val fiatRewardsValue = cryptoCurrencyStatus.value.fiatRate?.times(cryptoRewardsValue)
val groupedBalances = getGroupedBalance(yieldBalance.balance)
InnerYieldBalanceState.Data(
rewardsCrypto = BigDecimalFormatter.formatCryptoAmount(
@ -47,121 +43,18 @@ internal class YieldBalancesConverter(
fiatCurrencySymbol = appCurrency.symbol,
),
rewardBlockType = getRewardBlockType(),
balance = groupedBalances,
balance = yieldBalance.balance.items.mapBalances(),
)
} else {
InnerYieldBalanceState.Empty
}
}
private fun getGroupedBalance(balance: YieldBalanceItem) = balance.items
.sortedBy { it.type }
.groupBy { it.type.toGroup() }
.mapNotNull { item ->
val (title, footer) = getGroupTitle(item.key)
val isClickable = item.key.isClickable()
title?.let {
BalanceGroupedState(
items = item.value.mapBalances(item.key).toPersistentList(),
footer = footer,
title = it,
type = item.key,
isClickable = isClickable,
)
}
}
.filterNot { it.items.isEmpty() }
private fun List<BalanceItem>.mapBalances() = sortedBy { it.type.order }
.filterNot { it.amount.isZero() || it.type == BalanceType.REWARDS }
.mapNotNull(balanceItemConverter::convert)
.toPersistentList()
private fun List<BalanceItem>.mapBalances(balanceType: BalanceType): List<BalanceState> {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val appCurrency = appCurrencyProvider()
val cryptoCurrency = cryptoCurrencyStatus.currency
var incrementingIndex = 1
return this
.filterNot { it.amount.isZero() }
.mapNotNull { balance ->
val validator = yield.validators.firstOrNull {
balance.validatorAddress?.contains(it.address, ignoreCase = true) == true
}
val cryptoAmount = balance.amount
val fiatAmount = cryptoCurrencyStatus.value.fiatRate?.times(cryptoAmount)
val unbonding = getUnbondingDate(balance.date)
val warmupPeriod = yield.metadata.warmupPeriod.days
val title = when {
validator != null -> stringReference(validator.name)
balanceType == BalanceType.UNSTAKING -> {
resourceReference(R.string.staking_unstaking_item_name, wrappedList(incrementingIndex++))
}
else -> null
}
title?.let {
BalanceState(
validator = validator,
title = title,
cryptoValue = cryptoAmount.parseBigDecimal(cryptoCurrency.decimals),
cryptoDecimal = cryptoAmount,
cryptoAmount = stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = cryptoAmount,
cryptoCurrency = cryptoCurrency,
),
),
fiatAmount = stringReference(
BigDecimalFormatter.formatFiatAmount(
fiatAmount = fiatAmount,
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
),
),
rawCurrencyId = balance.rawCurrencyId,
unbondingPeriod = unbonding,
warmupPeriod = pluralReference(R.plurals.common_days, warmupPeriod, wrappedList(warmupPeriod)),
pendingActions = balance.pendingActions.toPersistentList(),
)
}
}
}
private fun BalanceType.toGroup() = when (this) {
BalanceType.REWARDS,
BalanceType.UNKNOWN,
-> BalanceType.UNKNOWN
else -> this
}
private fun getGroupTitle(type: BalanceType) = when (type) {
BalanceType.STAKED -> resourceReference(R.string.staking_active) to
resourceReference(R.string.staking_active_footer)
BalanceType.UNSTAKED -> resourceReference(R.string.staking_unstaked) to
resourceReference(R.string.staking_unstaked_footer)
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking) to null
BalanceType.LOCKED -> resourceReference(R.string.staking_locked) to null
BalanceType.AVAILABLE -> null to null
BalanceType.PREPARING -> resourceReference(R.string.staking_preparing) to null
BalanceType.REWARDS -> null to null
BalanceType.UNLOCKING -> null to null
BalanceType.UNKNOWN -> null to null
}
private fun getUnbondingDate(date: DateTime?): TextReference {
val now = DateTime.now().millis
val nowCalendar = Calendar.getInstance()
nowCalendar.resetHours()
val endDate = Calendar.getInstance()
endDate.timeInMillis = date?.millis ?: now
endDate.resetHours()
val days = ((endDate.timeInMillis - nowCalendar.timeInMillis) / DAY_IN_MILLIS).toInt()
return if (days > 0) {
pluralReference(R.plurals.common_in_days, days, wrappedList(days))
} else {
resourceReference(R.string.common_today)
}
}
private fun getRewardBlockType(): RewardBlockType {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data
@ -178,15 +71,4 @@ internal class YieldBalancesConverter(
else -> RewardBlockType.NoRewards
}
}
private fun Calendar.resetHours() {
this[Calendar.HOUR_OF_DAY] = 0
this[Calendar.MINUTE] = 0
this[Calendar.SECOND] = 0
this[Calendar.MILLISECOND] = 0
}
private companion object {
const val DAY_IN_MILLIS = 24 * 60 * 60 * 1000
}
}

View file

@ -6,9 +6,9 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.RewardBlockType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.Yield.Validator.ValidatorStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.*
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
import com.tangem.features.staking.impl.presentation.state.StakingStates
import kotlinx.collections.immutable.persistentListOf
@ -63,36 +63,30 @@ internal object InitialStakingStatePreview {
rewardsCrypto = "100 SOL",
rewardBlockType = RewardBlockType.RewardUnavailable,
balance = persistentListOf(
BalanceGroupedState(
title = stringReference("Staked"),
footer = null,
type = BalanceType.STAKED,
isClickable = true,
items = persistentListOf(
BalanceState(
title = stringReference("Binance"),
cryptoValue = "100",
cryptoAmount = stringReference("100 SOL"),
cryptoDecimal = "100".toBigDecimal(),
fiatAmount = stringReference("100 $"),
rawCurrencyId = null,
validator = Yield.Validator(
address = "address",
status = ValidatorStatus.ACTIVE,
name = "Binance",
image = null,
website = null,
apr = "5".toBigDecimal(),
commission = null,
stakedBalance = null,
votingPower = null,
preferred = false,
),
unbondingPeriod = stringReference("3 days"),
pendingActions = persistentListOf(),
warmupPeriod = stringReference("3 days"),
),
BalanceState(
id = "id",
title = stringReference("Binance"),
cryptoValue = "100",
cryptoAmount = stringReference("100 SOL"),
cryptoDecimal = "100".toBigDecimal(),
fiatAmount = stringReference("100 $"),
rawCurrencyId = null,
validator = Yield.Validator(
address = "address",
status = Yield.Validator.ValidatorStatus.ACTIVE,
name = "Binance",
image = null,
website = null,
apr = "5".toBigDecimal(),
commission = null,
stakedBalance = null,
votingPower = null,
preferred = false,
),
pendingActions = persistentListOf(),
isClickable = true,
type = BalanceType.STAKED,
subtitle = null,
),
),
),

View file

@ -32,7 +32,6 @@ import androidx.compose.ui.unit.Density
import com.tangem.common.ui.navigationButtons.NavigationButtonsState
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
import com.tangem.core.ui.components.SpacerH12
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.inputrow.InputRowDefault
import com.tangem.core.ui.components.inputrow.InputRowImageInfo
import com.tangem.core.ui.components.list.roundedListWithDividersItems
@ -44,7 +43,6 @@ import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.RewardBlockType
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
import com.tangem.features.staking.impl.presentation.state.StakingStates
@ -198,53 +196,43 @@ private fun StakingRewardBlock(
}
@Composable
private fun ActiveStakingBlock(groups: ImmutableList<BalanceGroupedState>, onClick: (BalanceState) -> Unit) {
private fun ActiveStakingBlock(balances: ImmutableList<BalanceState>, onClick: (BalanceState) -> Unit) {
Column(
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
modifier = Modifier
.fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action),
) {
groups.forEach { group ->
key(group.title) {
FooterContainer(
footer = group.footer?.resolveReference(),
modifier = Modifier,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action),
) {
Text(
text = group.title.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.padding(
top = TangemTheme.dimens.spacing12,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
),
)
group.items.forEachIndexed { index, balance ->
key(balance.title.resolveReference() + index) {
InputRowImageInfo(
subtitle = balance.title,
caption = getCaption(group.type, balance),
isGrayscaleImage = !group.isClickable,
infoTitle = balance.fiatAmount,
infoSubtitle = balance.cryptoAmount,
imageUrl = balance.validator?.image,
iconEndRes = R.drawable.ic_chevron_right_24.takeIf { group.isClickable },
modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
enabled = group.isClickable,
onClick = { onClick(balance) },
),
)
}
}
}
}
Text(
text = stringResource(id = R.string.staking_your_stakes),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.padding(
top = TangemTheme.dimens.spacing12,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing4,
),
)
balances.forEach { balance ->
key(balance.id) {
val (icon, iconTint) = balance.type.getIcon()
InputRowImageInfo(
subtitle = balance.title,
caption = balance.subtitle ?: balance.getAprText(),
isGrayscaleImage = !balance.isClickable,
infoTitle = balance.fiatAmount,
infoSubtitle = balance.cryptoAmount,
imageUrl = balance.getImage(),
iconRes = icon,
iconTint = iconTint,
modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
enabled = balance.isClickable,
onClick = { onClick(balance) },
),
)
}
}
}
@ -266,51 +254,35 @@ private fun StakeButtonBlock(buttonState: NavigationButtonsState) {
}
@Composable
private fun getCaption(balanceType: BalanceType, balance: BalanceState): TextReference {
return when (balanceType) {
BalanceType.UNSTAKING -> {
combinedReference(
resourceReference(R.string.staking_unbonding),
annotatedReference {
appendSpace()
appendColored(
text = balance.unbondingPeriod.resolveReference(),
color = TangemTheme.colors.text.accent,
)
},
)
}
BalanceType.UNSTAKED -> {
resourceReference(R.string.staking_ready_to_withdraw)
}
BalanceType.PREPARING -> {
combinedReference(
resourceReference(R.string.staking_details_warmup_period),
annotatedReference {
appendSpace()
appendColored(
text = balance.warmupPeriod.resolveReference(),
color = TangemTheme.colors.text.accent,
)
},
)
}
else -> {
combinedReference(
resourceReference(R.string.staking_details_apr),
annotatedReference {
appendSpace()
appendColored(
text = BigDecimalFormatter.formatPercent(
percent = balance.validator?.apr.orZero(),
useAbsoluteValue = true,
),
color = TangemTheme.colors.text.accent,
)
},
)
}
}
private fun BalanceState.getAprText() = combinedReference(
resourceReference(R.string.staking_details_apr),
annotatedReference {
appendSpace()
appendColored(
text = BigDecimalFormatter.formatPercent(
percent = validator?.apr.orZero(),
useAbsoluteValue = true,
),
color = TangemTheme.colors.text.accent,
)
},
)
@Composable
private fun BalanceType.getIcon() = when (this) {
BalanceType.UNSTAKING -> R.drawable.ic_connection_18 to TangemTheme.colors.icon.accent
BalanceType.UNSTAKED -> R.drawable.ic_connection_18 to TangemTheme.colors.icon.informative
BalanceType.LOCKED -> R.drawable.ic_lock_24 to TangemTheme.colors.icon.informative
else -> null to TangemTheme.colors.icon.informative
}
@Composable
private fun BalanceState.getImage() = when (type) {
BalanceType.UNSTAKING,
BalanceType.UNSTAKED,
BalanceType.LOCKED,
-> null
else -> validator?.image
}
private val textGradientColors = listOf(