Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-12 15:03:24 +03:00
commit f0026d8880
7 changed files with 194 additions and 170 deletions

View file

@ -31,10 +31,12 @@ internal class YieldBalanceConverter : Converter<YieldBalanceWrapperDTO, YieldBa
validatorAddress = item.validatorAddress ?: item.validatorAddresses?.get(0),
date = item.date?.toDateTime(),
pendingActions = pendingActionConverter
.convertList(item.pendingActions),
.convertList(item.pendingActions)
.sortedBy { it.passthrough },
isPending = false,
)
},
}
.sortedWith(compareBy({ it.type }, { it.amount })),
integrationId = value.integrationId,
),
)

View file

@ -25,9 +25,10 @@ enum class StakingActionType {
UNSTAKE -> "Unstake"
CLAIM_REWARDS -> "Claim Rewards"
RESTAKE_REWARDS -> "Restake Rewards"
WITHDRAW -> "Withdraw"
CLAIM_UNSTAKED,
WITHDRAW,
-> "Withdraw"
RESTAKE -> "Restake"
CLAIM_UNSTAKED -> "Claim Unstaked"
UNLOCK_LOCKED -> "Unlock Locked"
STAKE_LOCKED -> "Stake Locked"
VOTE -> "Vote"

View file

@ -15,8 +15,6 @@ import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.error.mapToFeeError
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWallet
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.math.BigDecimal
/**
@ -30,28 +28,25 @@ class EstimateFeeUseCase(
amount: BigDecimal,
userWallet: UserWallet,
cryptoCurrency: CryptoCurrency,
): Flow<Either<GetFeeError, TransactionFee>> {
return flow {
val amountData = convertCryptoCurrencyToAmount(cryptoCurrency, amount)
val result = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) {
demoTransactionSender(userWallet, cryptoCurrency).estimateFee(
amount = amountData,
destination = "",
)
} else {
walletManagersFacade.estimateFee(
amount = amountData,
userWalletId = userWallet.walletId,
network = cryptoCurrency.network,
)
}
): Either<GetFeeError, TransactionFee> {
val amountData = convertCryptoCurrencyToAmount(cryptoCurrency, amount)
val result = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) {
demoTransactionSender(userWallet, cryptoCurrency).estimateFee(
amount = amountData,
destination = "",
)
} else {
walletManagersFacade.estimateFee(
amount = amountData,
userWalletId = userWallet.walletId,
network = cryptoCurrency.network,
)
}
val maybeFee = when (result) {
is Result.Success -> result.data.right()
is Result.Failure -> result.mapToFeeError().left()
null -> GetFeeError.UnknownError.left()
}
emit(maybeFee)
return when (result) {
is Result.Success -> result.data.right()
is Result.Failure -> result.mapToFeeError().left()
null -> GetFeeError.UnknownError.left()
}
}

View file

@ -86,7 +86,9 @@ internal class StakingInfoNotificationsFactory(
resourceReference(R.string.staking_restake) to
resourceReference(R.string.staking_notification_restake_rewards_text)
}
StakingActionType.WITHDRAW -> {
StakingActionType.CLAIM_UNSTAKED,
StakingActionType.WITHDRAW,
-> {
resourceReference(R.string.staking_withdraw) to
resourceReference(R.string.staking_notification_withdraw_text)
}

View file

@ -16,9 +16,10 @@ import kotlinx.collections.immutable.toPersistentList
internal fun StakingActionType?.getPendingActionTitle(): TextReference = when (this) {
StakingActionType.CLAIM_REWARDS -> resourceReference(R.string.common_claim_rewards)
StakingActionType.RESTAKE_REWARDS -> resourceReference(R.string.staking_restake_rewards)
StakingActionType.WITHDRAW -> resourceReference(R.string.staking_withdraw)
StakingActionType.CLAIM_UNSTAKED,
StakingActionType.WITHDRAW,
-> resourceReference(R.string.staking_withdraw)
StakingActionType.RESTAKE -> resourceReference(R.string.staking_restake)
StakingActionType.CLAIM_UNSTAKED -> resourceReference(R.string.staking_claim_unstaked)
StakingActionType.UNLOCK_LOCKED -> resourceReference(R.string.staking_unlocked_locked)
StakingActionType.STAKE_LOCKED -> resourceReference(R.string.staking_stake_locked)
StakingActionType.VOTE -> resourceReference(R.string.staking_vote)

View file

@ -5,6 +5,7 @@ import arrow.core.getOrElse
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchainsdk.utils.fromNetworkId
@ -45,7 +46,6 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.firstOrNull
import timber.log.Timber
import java.math.BigDecimal
import java.math.BigInteger
@ -865,8 +865,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
} else {
when (blockchain) {
// region Blockchains with their own fees
Blockchain.VeChain,
Blockchain.VeChainTestnet,
VeChain,
VeChainTestnet,
-> {
Fee.VeChain(
amount = feeAmount,
@ -874,28 +874,28 @@ internal class SwapInteractorImpl @AssistedInject constructor(
gasLimit = fee.gasLimit.toLong(),
)
}
Blockchain.Aptos,
Blockchain.AptosTestnet,
Aptos,
AptosTestnet,
-> {
val gasUnitPrice = fee.feeValue.divide(
fee.gasLimit.toBigDecimal(),
Blockchain.Aptos.decimals(),
Aptos.decimals(),
RoundingMode.HALF_UP,
)
Fee.Aptos(
amount = feeAmount,
gasUnitPrice = gasUnitPrice
.movePointRight(Blockchain.Aptos.decimals())
.movePointRight(Aptos.decimals())
.toLong(),
gasLimit = fee.gasLimit.toLong(),
)
}
Blockchain.Filecoin,
Filecoin,
-> {
val gasUnitPrice = fee.feeValue.divide(
BigDecimal(fee.gasLimit),
Blockchain.Filecoin.decimals(),
Filecoin.decimals(),
RoundingMode.HALF_UP,
)
val feeParams = requireNotNull(fee.params as? TxFee.Params.Filecoin)
@ -903,14 +903,14 @@ internal class SwapInteractorImpl @AssistedInject constructor(
Fee.Filecoin(
amount = feeAmount,
gasUnitPrice = gasUnitPrice
.movePointRight(Blockchain.Filecoin.decimals())
.movePointRight(Filecoin.decimals())
.toLong(),
gasLimit = fee.gasLimit.toLong(),
gasPremium = feeParams.gasPremium,
)
}
Blockchain.Sui,
Blockchain.SuiTestnet,
Sui,
SuiTestnet,
-> {
val feeParams = requireNotNull(fee.params as? TxFee.Params.Sui)
@ -922,131 +922,131 @@ internal class SwapInteractorImpl @AssistedInject constructor(
}
// endregion
// region Blockchains with common fees or EVM-like fees
Blockchain.Unknown,
Blockchain.Arbitrum,
Blockchain.ArbitrumTestnet,
Blockchain.Avalanche,
Blockchain.AvalancheTestnet,
Blockchain.Binance,
Blockchain.BinanceTestnet,
Blockchain.BSC,
Blockchain.BSCTestnet,
Blockchain.Bitcoin,
Blockchain.BitcoinTestnet,
Blockchain.BitcoinCash,
Blockchain.BitcoinCashTestnet,
Blockchain.Cardano,
Blockchain.Cosmos,
Blockchain.CosmosTestnet,
Blockchain.Dogecoin,
Blockchain.Ducatus,
Blockchain.Ethereum,
Blockchain.EthereumTestnet,
Blockchain.EthereumClassic,
Blockchain.EthereumClassicTestnet,
Blockchain.Fantom,
Blockchain.FantomTestnet,
Blockchain.Litecoin,
Blockchain.Near,
Blockchain.NearTestnet,
Blockchain.Polkadot,
Blockchain.PolkadotTestnet,
Blockchain.Kava,
Blockchain.KavaTestnet,
Blockchain.Kusama,
Blockchain.Polygon,
Blockchain.PolygonTestnet,
Blockchain.RSK,
Blockchain.Sei,
Blockchain.SeiTestnet,
Blockchain.Stellar,
Blockchain.StellarTestnet,
Blockchain.Solana,
Blockchain.SolanaTestnet,
Blockchain.Tezos,
Blockchain.Tron,
Blockchain.TronTestnet,
Blockchain.XRP,
Blockchain.Gnosis,
Blockchain.Dash,
Blockchain.Optimism,
Blockchain.OptimismTestnet,
Blockchain.Dischain,
Blockchain.EthereumPow,
Blockchain.EthereumPowTestnet,
Blockchain.Kaspa,
Blockchain.Telos,
Blockchain.TelosTestnet,
Blockchain.TON,
Blockchain.TONTestnet,
Blockchain.Ravencoin,
Blockchain.RavencoinTestnet,
Blockchain.TerraV1,
Blockchain.TerraV2,
Blockchain.Cronos,
Blockchain.AlephZero,
Blockchain.AlephZeroTestnet,
Blockchain.OctaSpace,
Blockchain.OctaSpaceTestnet,
Blockchain.Chia,
Blockchain.ChiaTestnet,
Blockchain.Decimal,
Blockchain.DecimalTestnet,
Blockchain.XDC,
Blockchain.XDCTestnet,
Blockchain.Playa3ull,
Blockchain.Shibarium,
Blockchain.ShibariumTestnet,
Blockchain.Algorand,
Blockchain.AlgorandTestnet,
Blockchain.Hedera,
Blockchain.HederaTestnet,
Blockchain.Aurora,
Blockchain.AuroraTestnet,
Blockchain.Areon,
Blockchain.AreonTestnet,
Blockchain.PulseChain,
Blockchain.PulseChainTestnet,
Blockchain.ZkSyncEra,
Blockchain.ZkSyncEraTestnet,
Blockchain.Nexa,
Blockchain.NexaTestnet,
Blockchain.Moonbeam,
Blockchain.MoonbeamTestnet,
Blockchain.Manta,
Blockchain.MantaTestnet,
Blockchain.PolygonZkEVM,
Blockchain.PolygonZkEVMTestnet,
Blockchain.Radiant,
Blockchain.Base,
Blockchain.BaseTestnet,
Blockchain.Moonriver,
Blockchain.MoonriverTestnet,
Blockchain.Mantle,
Blockchain.MantleTestnet,
Blockchain.Flare,
Blockchain.FlareTestnet,
Blockchain.Taraxa,
Blockchain.TaraxaTestnet,
Blockchain.Koinos,
Blockchain.KoinosTestnet,
Blockchain.Joystream,
Blockchain.Bittensor,
Blockchain.Blast,
Blockchain.BlastTestnet,
Blockchain.Cyber,
Blockchain.CyberTestnet,
Blockchain.InternetComputer,
Blockchain.EnergyWebChain,
Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX,
Blockchain.EnergyWebXTestnet,
Blockchain.Casper,
Blockchain.CasperTestnet,
Blockchain.Core,
Blockchain.CoreTestnet,
Blockchain.Xodex,
Blockchain.Canxium,
Unknown,
Arbitrum,
ArbitrumTestnet,
Avalanche,
AvalancheTestnet,
Binance,
BinanceTestnet,
BSC,
BSCTestnet,
Bitcoin,
BitcoinTestnet,
BitcoinCash,
BitcoinCashTestnet,
Cardano,
Cosmos,
CosmosTestnet,
Dogecoin,
Ducatus,
Ethereum,
EthereumTestnet,
EthereumClassic,
EthereumClassicTestnet,
Fantom,
FantomTestnet,
Litecoin,
Near,
NearTestnet,
Polkadot,
PolkadotTestnet,
Kava,
KavaTestnet,
Kusama,
Polygon,
PolygonTestnet,
RSK,
Sei,
SeiTestnet,
Stellar,
StellarTestnet,
Solana,
SolanaTestnet,
Tezos,
Tron,
TronTestnet,
XRP,
Gnosis,
Dash,
Optimism,
OptimismTestnet,
Dischain,
EthereumPow,
EthereumPowTestnet,
Kaspa,
Telos,
TelosTestnet,
TON,
TONTestnet,
Ravencoin,
RavencoinTestnet,
TerraV1,
TerraV2,
Cronos,
AlephZero,
AlephZeroTestnet,
OctaSpace,
OctaSpaceTestnet,
Chia,
ChiaTestnet,
Decimal,
DecimalTestnet,
XDC,
XDCTestnet,
Playa3ull,
Shibarium,
ShibariumTestnet,
Algorand,
AlgorandTestnet,
Hedera,
HederaTestnet,
Aurora,
AuroraTestnet,
Areon,
AreonTestnet,
PulseChain,
PulseChainTestnet,
ZkSyncEra,
ZkSyncEraTestnet,
Nexa,
NexaTestnet,
Moonbeam,
MoonbeamTestnet,
Manta,
MantaTestnet,
PolygonZkEVM,
PolygonZkEVMTestnet,
Radiant,
Base,
BaseTestnet,
Moonriver,
MoonriverTestnet,
Mantle,
MantleTestnet,
Flare,
FlareTestnet,
Taraxa,
TaraxaTestnet,
Koinos,
KoinosTestnet,
Joystream,
Bittensor,
Blast,
BlastTestnet,
Cyber,
CyberTestnet,
InternetComputer,
EnergyWebChain,
EnergyWebChainTestnet,
EnergyWebX,
EnergyWebXTestnet,
Casper,
CasperTestnet,
Core,
CoreTestnet,
Xodex,
Canxium,
-> Fee.Common(feeAmount)
// endregion
}
@ -1592,12 +1592,25 @@ internal class SwapInteractorImpl @AssistedInject constructor(
amount: BigDecimal,
userWallet: UserWallet,
cryptoCurrency: CryptoCurrency,
): Either<GetFeeError, TransactionFee>? {
): Either<GetFeeError, TransactionFee> {
return estimateFeeUseCase(
amount = amount,
userWallet = userWallet,
cryptoCurrency = cryptoCurrency,
).firstOrNull()
).mapFeeToForceSingleFeeIfNeeded(cryptoCurrency)
}
private fun Either<GetFeeError, TransactionFee>.mapFeeToForceSingleFeeIfNeeded(
cryptoCurrency: CryptoCurrency,
): Either<GetFeeError, TransactionFee> {
return this.map {
val blockchain = Blockchain.fromNetworkId(cryptoCurrency.network.backendId)
if (it is TransactionFee.Choosable && forceSingleFeeBlockchains.contains(blockchain)) {
TransactionFee.Single(normal = it.normal)
} else {
it
}
}
}
@Suppress("LongParameterList", "LongMethod")
@ -2211,6 +2224,17 @@ internal class SwapInteractorImpl @AssistedInject constructor(
private val minDemoFee = "0.0001".toBigDecimal()
private val normalDemoFee = "0.0002".toBigDecimal()
private val priorityDemoFee = "0.0003".toBigDecimal()
private val forceSingleFeeBlockchains = listOf(
Bitcoin, BitcoinTestnet,
BitcoinCash, BitcoinCashTestnet,
Litecoin,
Dogecoin,
Dash,
Kaspa,
Ravencoin, RavencoinTestnet,
Ducatus,
)
}
@AssistedFactory

View file

@ -78,7 +78,6 @@ mlKit-barcodeScanning = "17.2.0"
androidXCamera = "1.3.0"
listenableFuture = "1.0"
swipeRefreshLayout = "1.1.0"
spr-client = "3.6.2"
web3j = "4.10.1"
leakcanary = "2.13"
decompose = "2.2.2"