From 92ad2b40a08725385904089d51a16902611b5c12 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 12 Nov 2024 11:33:28 +0200 Subject: [PATCH 1/3] Updated on 2026-08-14 --- .../tangem/data/staking/converters/YieldBalanceConverter.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt index 5edd7f05e7..c0807165b7 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt @@ -31,10 +31,12 @@ internal class YieldBalanceConverter : Converter Date: Tue, 12 Nov 2024 13:57:07 +0300 Subject: [PATCH 2/3] Updated on 2026-08-14 --- .../transaction/usecase/EstimateFeeUseCase.kt | 41 ++- .../feature/swap/domain/SwapInteractorImpl.kt | 302 ++++++++++-------- gradle/dependencies.toml | 1 - 3 files changed, 181 insertions(+), 163 deletions(-) diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt index 134cb9f3f5..8edb20c7a6 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt @@ -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> { - 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 { + 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() } } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 77aa2d704c..1d5e225d91 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -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? { + ): Either { return estimateFeeUseCase( amount = amount, userWallet = userWallet, cryptoCurrency = cryptoCurrency, - ).firstOrNull() + ).mapFeeToForceSingleFeeIfNeeded(cryptoCurrency) + } + + private fun Either.mapFeeToForceSingleFeeIfNeeded( + cryptoCurrency: CryptoCurrency, + ): Either { + 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 diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index cb7a4dbffc..045a84b417 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -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" From c404846b0da9178b6c75eb0e20a8061ce085f1f1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 12 Nov 2024 13:30:25 +0500 Subject: [PATCH 3/3] Updated on 2026-08-14 --- .../staking/model/stakekit/action/StakingActionType.kt | 5 +++-- .../notifications/StakingInfoNotificationsFactory.kt | 4 +++- .../presentation/state/utils/StakingPendingActionUtils.kt | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionType.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionType.kt index 3d449ae82a..01e02cea2f 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionType.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionType.kt @@ -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" diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt index 11b61e92b9..1a527dd242 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt @@ -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) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt index 558aa4252e..9287657626 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt @@ -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)