Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-06 13:54:38 +05:00
parent 9d73e02d69
commit f9226ab6bf
19 changed files with 106 additions and 63 deletions

View file

@ -13,6 +13,10 @@ android {
dependencies {
implementation(projects.core.utils)
api(projects.domain.models)
api(projects.domain.appCurrency.models)
api(projects.domain.staking.models)
api(projects.libs.crypto)
// region Firebase libraries
implementation(platform(deps.firebase.bom))

View file

@ -0,0 +1,33 @@
package com.tangem.common
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.utils.extensions.orZero
import java.math.BigDecimal
/**
* Calculates the total fiat amount by adding the main fiat amount and the fiat value of the staked balance.
*/
fun CryptoCurrencyStatus.getTotalFiatAmount(): BigDecimal? {
val fiatAmount = value.fiatAmount
val fiatStakedBalance = value.fiatRate?.times(getStakedBalance().orZero()) ?: return fiatAmount
val totalAmount = fiatAmount?.plus(fiatStakedBalance) ?: return fiatStakedBalance
return totalAmount
}
/**
* Calculates the total cryptocurrency amount by adding the main crypto amount and the staked balance.
*/
fun CryptoCurrencyStatus.getTotalCryptoAmount(): BigDecimal? {
val cryptoAmount = value.amount
val cryptoStakedBalance = getStakedBalance() ?: return cryptoAmount
val totalAmount = cryptoAmount?.plus(cryptoStakedBalance) ?: return cryptoStakedBalance
return totalAmount
}
private fun CryptoCurrencyStatus.getStakedBalance() = (value.stakingBalance as? StakingBalance.Data)
?.getTotalWithRewardsStakingBalance(blockchainId = currency.network.rawId)

View file

@ -1,4 +1,4 @@
package com.tangem.domain.staking.utils
package com.tangem.common
import com.tangem.domain.models.staking.BalanceType
import com.tangem.domain.models.staking.StakingBalance

View file

@ -9,6 +9,7 @@ android {
}
dependencies {
api(projects.common)
/** Compose */
implementation(deps.compose.material3)

View file

@ -1,5 +1,7 @@
package com.tangem.common.ui.tokens
import com.tangem.common.getTotalCryptoAmount
import com.tangem.common.getTotalFiatAmount
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
@ -25,11 +27,8 @@ import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingOption
import com.tangem.domain.staking.model.common.RewardInfo
import com.tangem.domain.staking.model.common.RewardType
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.StringsSigns.DASH_SIGN
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.orZero
import kotlinx.collections.immutable.toImmutableList
import java.math.BigDecimal
@ -156,29 +155,6 @@ class TokenItemStateConverter(
}
companion object {
fun CryptoCurrencyStatus.getFormattedFiatAmount(appCurrency: AppCurrency): String {
val fiatAmount = value.fiatAmount ?: return DASH_SIGN
val fiatYieldBalance = value.fiatRate?.times(getStakedBalance()).orZero()
val totalAmount = fiatAmount.plus(fiatYieldBalance)
return totalAmount.format {
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
}
}
fun CryptoCurrencyStatus.getFormattedCryptoAmount(): String {
val cryptoAmount = value.amount ?: return DASH_SIGN
val totalAmount = cryptoAmount.plus(getStakedBalance())
return totalAmount.format { crypto(currency) }
}
private fun CryptoCurrencyStatus.getStakedBalance() = (value.stakingBalance as? StakingBalance.Data)
?.getTotalWithRewardsStakingBalance(blockchainId = currency.network.rawId).orZero()
private fun createTitleState(
currencyStatus: CryptoCurrencyStatus,
yieldModuleApyMap: Map<String, BigDecimal>,
@ -348,7 +324,9 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.Subtitle2State.TextContent(
text = status.getFormattedCryptoAmount(),
text = status.getTotalCryptoAmount().format {
crypto(status.currency)
},
isFlickering = status.value.isFlickering(),
)
}
@ -371,7 +349,12 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.FiatAmountState.Content(
text = status.getFormattedFiatAmount(appCurrency = appCurrency),
text = status.getTotalFiatAmount().format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
isFlickering = status.value.isFlickering(),
icons = buildList {
if (status.value.yieldSupplyStatus?.isActive == true &&

View file

@ -44,6 +44,7 @@ dependencies {
implementation(projects.core.datasource)
implementation(projects.core.utils)
implementation(projects.libs.blockchainSdk)
implementation(projects.common)
// endregion
// region Project - Features API

View file

@ -3,13 +3,13 @@ package com.tangem.data.tokens.repository
import com.tangem.blockchain.blockchains.ethereum.eip1559.isGaslessTxSupported
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
import com.tangem.blockchain.common.*
import com.tangem.common.getTotalStakingBalance
import com.tangem.data.tokens.converters.UtxoConverter
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.utils.getTotalStakingBalance
import com.tangem.domain.tokens.model.CurrencyAmount
import com.tangem.domain.tokens.model.blockchains.UtxoAmountLimit
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning

View file

@ -46,6 +46,7 @@ dependencies {
implementation(projects.core.configToggles)
implementation(projects.core.utils)
implementation(projects.libs.crypto)
implementation(projects.common)
/** Android - Other */
implementation(deps.androidx.paging.runtime)

View file

@ -2,16 +2,14 @@ package com.tangem.domain.tokens.operations
import arrow.core.NonEmptyList
import arrow.core.toNonEmptyListOrNull
import com.tangem.common.getTotalFiatAmount
import com.tangem.domain.models.TokensGroupType
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.tokenlist.TokenList.GroupedByNetwork.NetworkGroup
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.utils.extensions.orZero
import java.math.BigDecimal
/**
* This factory creates a [TokenList] based on the provided list of [CryptoCurrencyStatus], [TokensGroupType],
@ -103,7 +101,7 @@ object TokenListFactory {
if (hasLoading) return this
sortedByDescending { group ->
group.currencies.sumOf { it.calculateBalance() }
group.currencies.sumOf { it.getTotalFiatAmount().orZero() }
}
}
}
@ -117,16 +115,8 @@ object TokenListFactory {
if (hasLoading) return this
sortedByDescending { it.calculateBalance() }
sortedByDescending { it.getTotalFiatAmount().orZero() }
}
}
}
private fun CryptoCurrencyStatus.calculateBalance(): BigDecimal {
val stakingBalance = value.stakingBalance as? StakingBalance.Data
val totalStakingBalance = stakingBalance?.getTotalWithRewardsStakingBalance(currency.network.rawId).orZero()
val totalFiatStakingBalance = totalStakingBalance.multiply(value.fiatRate.orZero())
return value.fiatAmount?.plus(totalFiatStakingBalance).orZero()
}
}

View file

@ -2,13 +2,13 @@ package com.tangem.domain.tokens.operations
import arrow.core.NonEmptyList
import arrow.core.toNonEmptyListOrNull
import com.tangem.common.getTotalWithRewardsStakingBalance
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.getResultStatusSource
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.extensions.orZero
import java.math.BigDecimal

View file

@ -1,13 +1,16 @@
package com.tangem.features.onramp.tokenlist.entity.utils
import com.tangem.common.getTotalCryptoAmount
import com.tangem.common.getTotalFiatAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.isFlickering
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.format.bigdecimal.crypto
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
@ -112,7 +115,9 @@ internal object OnrampTokenItemStateConverterFactory {
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.Subtitle2State.TextContent(
text = status.getFormattedCryptoAmount(),
text = status.getTotalCryptoAmount().format {
crypto(cryptoCurrency = status.currency)
},
isFlickering = status.value.isFlickering(),
)
}
@ -136,7 +141,12 @@ internal object OnrampTokenItemStateConverterFactory {
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.FiatAmountState.TextContent(
text = status.getFormattedFiatAmount(appCurrency = appCurrency),
text = status.getTotalFiatAmount().format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
isAvailable = isAvailable,
isFlickering = status.value.isFlickering(),
)

View file

@ -1,14 +1,17 @@
package com.tangem.feature.referral.model
import com.tangem.common.getTotalCryptoAmount
import com.tangem.common.getTotalFiatAmount
import com.tangem.common.ui.account.CryptoPortfolioIconConverter
import com.tangem.common.ui.account.PortfolioSelectUM
import com.tangem.common.ui.account.toUM
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.isFlickering
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.format.bigdecimal.crypto
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.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
@ -35,10 +38,17 @@ internal class AccountAwardConverter(
iconState = CryptoCurrencyToIconStateConverter().convert(currency),
titleState = TokenItemState.TitleState.Content(stringReference(currency.name)),
fiatAmountState = TokenItemState.FiatAmountState.Content(
text = accountAwardToken.getFormattedFiatAmount(appCurrency = appCurrency),
text = accountAwardToken.getTotalFiatAmount().format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
),
subtitle2State = TokenItemState.Subtitle2State.TextContent(
text = accountAwardToken.getFormattedCryptoAmount(),
text = accountAwardToken.getTotalCryptoAmount().format {
crypto(cryptoCurrency = currency)
},
isFlickering = accountAwardToken.value.isFlickering(),
),
subtitleState = TokenItemState.SubtitleState.TextContent(stringReference(currency.symbol)),

View file

@ -5,6 +5,7 @@ import arrow.core.getOrElse
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.getValidatorsCount
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer.ReduceByData
@ -53,7 +54,6 @@ import com.tangem.domain.staking.model.stakekit.action.StakingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
import com.tangem.domain.staking.repositories.P2PEthPoolRepository
import com.tangem.domain.staking.utils.getValidatorsCount
import com.tangem.domain.tokens.*
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.usecase.*

View file

@ -1,15 +1,18 @@
package com.tangem.feature.swap.converters
import com.tangem.common.getTotalCryptoAmount
import com.tangem.common.getTotalFiatAmount
import com.tangem.common.ui.account.AccountCryptoPortfolioItemStateConverter
import com.tangem.common.ui.tokens.TokenItemStateConverter
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.isFlickering
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.format.bigdecimal.crypto
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.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrencyStatus
@ -108,7 +111,9 @@ internal class AccountTokenItemConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.Subtitle2State.TextContent(
text = status.getFormattedCryptoAmount(),
text = status.getTotalCryptoAmount().format {
crypto(cryptoCurrency = status.currency)
},
isFlickering = status.value.isFlickering(),
)
}
@ -132,7 +137,12 @@ internal class AccountTokenItemConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.FiatAmountState.TextContent(
text = status.getFormattedFiatAmount(appCurrency = appCurrency),
text = status.getTotalFiatAmount().format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
isAvailable = isAvailable,
isFlickering = status.value.isFlickering(),
)

View file

@ -1,12 +1,12 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import com.tangem.common.getTotalWithRewardsStakingBalance
import com.tangem.core.ui.format.bigdecimal.crypto
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.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
import com.tangem.utils.Provider

View file

@ -1,6 +1,7 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import arrow.core.Either
import com.tangem.common.getTotalWithRewardsStakingBalance
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
import com.tangem.core.ui.components.marketprice.PriceChangeState
import com.tangem.core.ui.components.marketprice.PriceChangeType
@ -10,7 +11,6 @@ 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.StakingBalance
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.BalanceType

View file

@ -1,5 +1,7 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import com.tangem.common.getRewardStakingBalance
import com.tangem.common.getTotalStakingBalance
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
@ -13,8 +15,6 @@ import com.tangem.domain.models.staking.RewardBlockType
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
import com.tangem.domain.staking.utils.getTotalStakingBalance
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.IconState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.StakingBlockUM

View file

@ -1,5 +1,6 @@
package com.tangem.feature.wallet.presentation.organizetokens.utils.converter.items
import com.tangem.common.getTotalWithRewardsStakingBalance
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.stringReference
@ -9,7 +10,6 @@ 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.StakingBalance
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getGroupHeaderId
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getTokenItemId

View file

@ -10,7 +10,7 @@ import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.common.getTotalWithRewardsStakingBalance
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getGroupHeaderId
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getTokenItemId