diff --git a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt index 87b23e1c2d..621ce6f4e9 100644 --- a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt @@ -111,6 +111,14 @@ class TransactionManagerImpl( gasPremium = normalFee.gasPremium, ) } + is Fee.Sui -> { + ProxyFee.Sui( + gasLimit = BigInteger.ZERO, + fee = convertToProxyAmount(amount = normalFee.amount), + gasPrice = normalFee.gasPrice, + gasBudget = normalFee.gasBudget, + ) + } else -> { ProxyFee.Common( gasLimit = BigInteger.ZERO, diff --git a/common/ui/src/main/java/com/tangem/common/ui/navigationButtons/NavigationButtonsBlock.kt b/common/ui/src/main/java/com/tangem/common/ui/navigationButtons/NavigationButtonsBlock.kt index 8cb08d87c0..ab24037ad8 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/navigationButtons/NavigationButtonsBlock.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/navigationButtons/NavigationButtonsBlock.kt @@ -79,6 +79,7 @@ fun NavigationPrimaryButton(primaryButton: NavigationButton?, modifier: Modifier onClick = button.onClick, showProgress = button.showProgress, colors = TangemButtonsDefaults.primaryButtonColors, + textStyle = TangemTheme.typography.subtitle1, icon = icon, modifier = Modifier.fillMaxWidth(), ) @@ -134,6 +135,7 @@ private fun ExtraButtons(extraButtons: ImmutableList?, txUrl: TangemButton( text = button.textReference.resolveReference(), icon = icon, + textStyle = TangemTheme.typography.subtitle1, onClick = rememberHapticFeedback(state = button, onAction = button.onClick), modifier = Modifier.weight(1f), enabled = button.isEnabled, diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index e8db31eab3..57db1a7c37 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -766,7 +766,7 @@ Застейкать еще Вы стейкаете %1$s и будете получать %2$s ежегодно Нажмите для разблокировки - Нажмите для разблокировки или голосования + Нажмите для разблокировки Нажмите для вывода Застейкать %s Вывести %s diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt index fb78b58f1e..4c44809cfa 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt @@ -490,7 +490,7 @@ object BigDecimalFormatter { ): String { if (threeDigitsMethod) { val scaledAmount = amount.setScale(scale, RoundingMode.HALF_UP) - val digitsCount = scaledAmount.longValueExact().toString().count() + val digitsCount = scaledAmount.toString().count() val digitsToFormat = 6 - when (digitsCount % 3) { 0 -> 0 1 -> 2 @@ -508,7 +508,7 @@ object BigDecimalFormatter { return formatter.format(amount.setScale(scale, RoundingMode.HALF_UP)) } else { val scaledAmount = amount.setScale(scale, RoundingMode.HALF_UP) - val digitsCount = scaledAmount.longValueExact().toString().count() + val digitsCount = scaledAmount.toString().count() val digitsToFormat = 5 - when (digitsCount % 3) { 0 -> 0 1 -> 2 diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt index ffdbb9e58d..4ac4e2bdd2 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt @@ -127,20 +127,24 @@ internal class ManagedCryptoCurrencyFactory { ): ManagedCryptoCurrency? { if (coinResponse.networks.isEmpty() || !coinResponse.active) return null - val updatedNetworks = coinResponse.networks.applyL2Compatibility(coinResponse.id) + val availableNetworks = coinResponse.networks + .applyL2Compatibility(coinResponse.id) + .mapNotNull { network -> + createSource( + networkId = network.networkId, + contractAddress = network.contractAddress, + decimals = network.decimalCount?.toInt(), + derivationStyleProvider = derivationStyleProvider, + ) + } + .ifEmpty { return null } + return ManagedCryptoCurrency.Token( id = ManagedCryptoCurrency.ID(coinResponse.id), name = coinResponse.name, symbol = coinResponse.symbol, iconUrl = getIconUrl(coinResponse.id, imageHost), - availableNetworks = updatedNetworks.mapNotNull { network -> - createSource( - networkId = network.networkId, - contractAddress = network.contractAddress, - decimals = network.decimalCount?.toInt() ?: return@mapNotNull null, - derivationStyleProvider = derivationStyleProvider, - ) - }, + availableNetworks = availableNetworks, addedIn = findAddedInNetworks(coinResponse.id, tokensResponse, derivationStyleProvider), ) } @@ -148,7 +152,7 @@ internal class ManagedCryptoCurrencyFactory { private fun createSource( networkId: String, contractAddress: String?, - decimals: Int, + decimals: Int?, derivationStyleProvider: DerivationStyleProvider?, extraDerivationPath: String? = null, ): SourceNetwork? { @@ -158,18 +162,18 @@ internal class ManagedCryptoCurrencyFactory { val network = getNetwork(blockchain, extraDerivationPath, derivationStyleProvider) ?: return null - return if (contractAddress.isNullOrBlank()) { - SourceNetwork.Main( + return when { + contractAddress.isNullOrBlank() -> SourceNetwork.Main( network = network, decimals = blockchain.decimals(), isL2Network = l2BlockchainsList.contains(blockchain), ) - } else { - SourceNetwork.Default( + network.canHandleTokens -> SourceNetwork.Default( network = network, - decimals = decimals, + decimals = decimals ?: return null, contractAddress = contractAddress, ) + else -> null } } diff --git a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldConverter.kt b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldConverter.kt index 7499cb4a34..8489a8772d 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldConverter.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldConverter.kt @@ -29,8 +29,9 @@ class YieldConverter( validators = value.validators .asSequence() .filter { it.status == ValidatorStatusDTO.ACTIVE } - .sortedByDescending { it.apr } .map { convertValidator(it) } + .sortedByDescending { it.isStrategicPartner } + .sortedByDescending { it.apr } .toImmutableList(), isAvailable = value.isAvailable, ) diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/InvalidatePendingTransactionsUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/InvalidatePendingTransactionsUseCase.kt index b7c4c597ef..3ed9de1336 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/InvalidatePendingTransactionsUseCase.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/InvalidatePendingTransactionsUseCase.kt @@ -8,6 +8,7 @@ import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.domain.staking.repositories.StakingErrorResolver import com.tangem.domain.staking.repositories.StakingPendingTransactionRepository import com.tangem.domain.wallets.models.UserWalletId +import org.joda.time.DateTime import java.util.UUID class InvalidatePendingTransactionsUseCase( @@ -40,12 +41,12 @@ class InvalidatePendingTransactionsUseCase( newBalancesId: Int, pendingData: List>, ): Pair, List> { - val balances = realData.associateBy { Triple(it.groupId, it.type, it.amount) }.toMutableMap() + val balances = realData.associateBy { Pair(it.groupId to it.type, it.amount to it.date) }.toMutableMap() val transactionsToRemove = mutableListOf() pendingData.forEach { (pendingTransaction, balanceItem) -> - val key = Triple(balanceItem.groupId, balanceItem.type, balanceItem.amount) + val key = Pair(balanceItem.groupId to balanceItem.type, balanceItem.amount to balanceItem.date) val oldBalancesId = pendingTransaction.balancesId when { @@ -57,7 +58,8 @@ class InvalidatePendingTransactionsUseCase( } else -> { val groupId = UUID.randomUUID().toString() - balances[Triple(groupId, BalanceType.STAKED, pendingTransaction.amount)] = BalanceItem( + val now = DateTime.now() + balances[Pair(groupId to BalanceType.STAKED, pendingTransaction.amount to now)] = BalanceItem( groupId = groupId, type = pendingTransaction.type, amount = pendingTransaction.amount, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt index 92c74bd946..bb73ad83b6 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt @@ -7,6 +7,7 @@ import com.tangem.domain.staking.model.stakekit.PendingAction import com.tangem.domain.staking.model.stakekit.RewardBlockType import com.tangem.domain.staking.model.stakekit.Yield import kotlinx.collections.immutable.ImmutableList +import org.joda.time.DateTime import java.math.BigDecimal internal sealed class InnerYieldBalanceState { @@ -35,4 +36,5 @@ internal data class BalanceState( val validator: Yield.Validator?, val pendingActions: ImmutableList, val isPending: Boolean, + val date: DateTime, ) \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt index 045baf45e0..e08e0a26d1 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt @@ -63,6 +63,7 @@ internal class BalanceItemConverter( pendingActions = value.pendingActions.toPersistentList(), isClickable = value.type.isClickable() && !value.isPending, isPending = value.isPending, + date = value.date ?: DateTime.now(), ) } } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt index 295f07c032..aca5b46db7 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt @@ -14,6 +14,7 @@ import com.tangem.features.staking.impl.presentation.state.StakingStates import com.tangem.utils.Provider import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.toPersistentList +import org.joda.time.DateTime import java.math.BigDecimal internal class RewardsValidatorStateConverter( @@ -91,6 +92,7 @@ internal class RewardsValidatorStateConverter( isClickable = true, type = balance.type, isPending = balance.isPending, + date = balance.date ?: DateTime.now(), ) } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt index d3890582f5..9273a2bea2 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt @@ -12,6 +12,7 @@ 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 +import org.joda.time.DateTime internal object InitialStakingStatePreview { val defaultState = StakingStates.InitialInfoState.Data( @@ -93,6 +94,7 @@ internal object InitialStakingStatePreview { type = BalanceType.STAKED, subtitle = null, isPending = false, + date = DateTime.now(), ), ), ), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt index 66ec803e8a..6c4009304a 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt @@ -33,6 +33,8 @@ internal object StakingClickIntentsStub : StakingClickIntents { override fun onInfoClick(infoType: InfoType) {} + override fun onEnterClick() {} + override fun onAmountValueChange(value: String) {} override fun onAmountPasteTriggerDismiss() {} diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt index ea4406d986..52251d7408 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt @@ -140,10 +140,7 @@ internal class SetButtonsStateTransformer( private fun StakingUiState.onPrimaryClick() { when (currentStep) { - StakingStep.InitialInfo -> { - clickIntents.onAmountValueChange("") // reset amount state - clickIntents.onNextClick(StakingActionCommonType.ENTER) - } + StakingStep.InitialInfo -> clickIntents.onEnterClick() StakingStep.Validators -> { if (confirmationState is StakingStates.ConfirmationState.Data) { clickIntents.onNextClick( @@ -154,9 +151,7 @@ internal class SetButtonsStateTransformer( clickIntents.onNextClick() } } - StakingStep.Amount -> { - clickIntents.onNextClick() - } + StakingStep.Amount -> clickIntents.onNextClick() StakingStep.Confirmation -> onConfirmationClick() StakingStep.RewardsValidators -> Unit } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt index a3b203d9eb..ee866db72c 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt @@ -3,7 +3,6 @@ package com.tangem.features.staking.impl.presentation.state.transformers import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState import com.tangem.features.staking.impl.presentation.state.StakingStates import com.tangem.features.staking.impl.presentation.state.StakingUiState -import com.tangem.features.staking.impl.presentation.state.ValidatorState import com.tangem.utils.transformer.Transformer internal object SetConfirmationStateResetAssentTransformer : Transformer { @@ -14,7 +13,7 @@ internal object SetConfirmationStateResetAssentTransformer : Transformer?) override fun onAmountNext() = onNextClick(actionTypeToOverwrite = null) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index 2c0c1833ed..244b8b108d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -388,6 +388,27 @@ internal class StakingViewModel @Inject constructor( ) } + override fun onEnterClick() { + onAmountValueChange("") // reset amount state + + // TODO refactor in [REDACTED_JIRA] + val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data + val filteredValidator = yield.validators.filter { it.preferred } + stateController.update { + value.copy( + confirmationState = confirmationState?.copy( + validatorState = ValidatorState.Content( + isClickable = true, + chosenValidator = filteredValidator[0], + availableValidators = filteredValidator, + ), + ) as StakingStates.ConfirmationState, + ) + } + + onNextClick(StakingActionCommonType.ENTER) + } + override fun onAmountValueChange(value: String) { stateController.update(AmountChangeStateTransformer(cryptoCurrencyStatus, value, yield)) } diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt index 854e53526b..115737ec2b 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt @@ -113,8 +113,21 @@ data class TxFee( val decimals: Int, val cryptoSymbol: String, val feeType: FeeType, - val gasPremium: Long?, -) + val params: Params?, +) { + + sealed class Params { + + data class Filecoin( + val gasPremium: Long, + ) : Params() + + data class Sui( + val gasBudget: Long, + val gasPrice: Long, + ) : Params() + } +} enum class FeeType { NORMAL, PRIORITY 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 b892338148..97ad3eb467 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 @@ -867,6 +867,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( } } + @Suppress("LongMethod") private fun getFeeForTransaction(fee: TxFee, blockchain: Blockchain): Fee { val feeAmountValue = fee.feeValue val feeAmount = Amount( @@ -876,50 +877,192 @@ internal class SwapInteractorImpl @AssistedInject constructor( type = AmountType.Coin, ) - return when { - blockchain.isEvm() -> { - val feeAmountWithDecimals = feeAmountValue.movePointRight(fee.decimals) - Fee.Ethereum.Legacy( - amount = feeAmount, - gasLimit = fee.gasLimit.toBigInteger(), - gasPrice = (feeAmountWithDecimals / fee.gasLimit.toBigDecimal()).toBigInteger(), - ) - } - blockchain == Blockchain.VeChain -> Fee.VeChain( + return if (blockchain.isEvm()) { + val feeAmountWithDecimals = feeAmountValue.movePointRight(fee.decimals) + + Fee.Ethereum.Legacy( amount = feeAmount, - gasPriceCoef = Fee.VeChain.getGasPriceCoef(fee.gasLimit.toLong(), fee.feeValue), - gasLimit = fee.gasLimit.toLong(), + gasLimit = fee.gasLimit.toBigInteger(), + gasPrice = (feeAmountWithDecimals / fee.gasLimit.toBigDecimal()).toBigInteger(), ) - blockchain == Blockchain.Aptos -> { - val gasUnitPrice = fee.feeValue.divide( - fee.gasLimit.toBigDecimal(), - Blockchain.Aptos.decimals(), - RoundingMode.HALF_UP, - ) - Fee.Aptos( - amount = feeAmount, - gasUnitPrice = gasUnitPrice - .movePointRight(Blockchain.Aptos.decimals()) - .toLong(), - gasLimit = fee.gasLimit.toLong(), - ) + } else { + when (blockchain) { + // region Blockchains with their own fees + Blockchain.VeChain, + Blockchain.VeChainTestnet, + -> { + Fee.VeChain( + amount = feeAmount, + gasPriceCoef = Fee.VeChain.getGasPriceCoef(fee.gasLimit.toLong(), fee.feeValue), + gasLimit = fee.gasLimit.toLong(), + ) + } + Blockchain.Aptos, + Blockchain.AptosTestnet, + -> { + val gasUnitPrice = fee.feeValue.divide( + fee.gasLimit.toBigDecimal(), + Blockchain.Aptos.decimals(), + RoundingMode.HALF_UP, + ) + + Fee.Aptos( + amount = feeAmount, + gasUnitPrice = gasUnitPrice + .movePointRight(Blockchain.Aptos.decimals()) + .toLong(), + gasLimit = fee.gasLimit.toLong(), + ) + } + Blockchain.Filecoin, + -> { + val gasUnitPrice = fee.feeValue.divide( + BigDecimal(fee.gasLimit), + Blockchain.Filecoin.decimals(), + RoundingMode.HALF_UP, + ) + val feeParams = requireNotNull(fee.params as? TxFee.Params.Filecoin) + + Fee.Filecoin( + amount = feeAmount, + gasUnitPrice = gasUnitPrice + .movePointRight(Blockchain.Filecoin.decimals()) + .toLong(), + gasLimit = fee.gasLimit.toLong(), + gasPremium = feeParams.gasPremium, + ) + } + Blockchain.Sui, + Blockchain.SuiTestnet, + -> { + val feeParams = requireNotNull(fee.params as? TxFee.Params.Sui) + + Fee.Sui( + amount = feeAmount, + gasPrice = feeParams.gasPrice, + gasBudget = feeParams.gasBudget, + ) + } + // 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, + -> Fee.Common(feeAmount) + // endregion } - blockchain == Blockchain.Filecoin -> { - val gasUnitPrice = fee.feeValue.divide( - BigDecimal(fee.gasLimit), - Blockchain.Filecoin.decimals(), - RoundingMode.HALF_UP, - ) - Fee.Filecoin( - amount = feeAmount, - gasUnitPrice = gasUnitPrice - .movePointRight(Blockchain.Filecoin.decimals()) - .toLong(), - gasLimit = fee.gasLimit.toLong(), - gasPremium = requireNotNull(fee.gasPremium), - ) - } - else -> Fee.Common(feeAmount) } } @@ -1615,7 +1758,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = minFee.fee.decimals, cryptoSymbol = minFee.fee.currencySymbol, feeType = FeeType.NORMAL, - gasPremium = (minFee as? ProxyFee.Filecoin)?.gasPremium, + params = getSwapFeeParams(minFee), ), priorityFee = TxFee( feeValue = priorityFeeValue, @@ -1628,7 +1771,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = normalFee.fee.decimals, cryptoSymbol = normalFee.fee.currencySymbol, feeType = FeeType.PRIORITY, - gasPremium = (normalFee as? ProxyFee.Filecoin)?.gasPremium, + params = getSwapFeeParams(normalFee), ), ) } @@ -1671,7 +1814,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = singleFee.fee.decimals, cryptoSymbol = singleFee.fee.currencySymbol, feeType = FeeType.NORMAL, - gasPremium = (singleFee as? ProxyFee.Filecoin)?.gasPremium, + params = getSwapFeeParams(singleFee), ), ) } @@ -1727,7 +1870,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = normalFee.amount.decimals, cryptoSymbol = normalFee.amount.currencySymbol, feeType = FeeType.NORMAL, - gasPremium = (normalFee as? Fee.Filecoin)?.gasPremium, + params = getSwapFeeParams(normalFee), ), priorityFee = TxFee( feeValue = feePriority, @@ -1740,7 +1883,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = priorityFee.amount.decimals, cryptoSymbol = priorityFee.amount.currencySymbol, feeType = FeeType.PRIORITY, - gasPremium = (priorityFee as? Fee.Filecoin)?.gasPremium, + params = getSwapFeeParams(priorityFee), ), ) } @@ -1772,13 +1915,46 @@ internal class SwapInteractorImpl @AssistedInject constructor( decimals = normal.amount.decimals, cryptoSymbol = normal.amount.currencySymbol, feeType = FeeType.NORMAL, - gasPremium = (normal as? Fee.Filecoin)?.gasPremium, + params = getSwapFeeParams(normal), ), ) } } } + private fun getSwapFeeParams(fee: Fee): TxFee.Params? = when (fee) { + is Fee.Filecoin -> TxFee.Params.Filecoin( + gasPremium = fee.gasPremium, + ) + is Fee.Sui -> TxFee.Params.Sui( + gasPrice = fee.gasPrice, + gasBudget = fee.gasBudget, + ) + is Fee.Aptos, + is Fee.Bitcoin, + is Fee.CardanoToken, + is Fee.Common, + is Fee.Ethereum.EIP1559, + is Fee.Ethereum.Legacy, + is Fee.Kaspa, + is Fee.Tron, + is Fee.VeChain, + -> null + } + + private fun getSwapFeeParams(proxyFee: ProxyFee): TxFee.Params? = when (proxyFee) { + is ProxyFee.Filecoin -> TxFee.Params.Filecoin( + gasPremium = proxyFee.gasPremium, + ) + is ProxyFee.Sui -> TxFee.Params.Sui( + gasPrice = proxyFee.gasPrice, + gasBudget = proxyFee.gasBudget, + ) + is ProxyFee.CardanoToken, + is ProxyFee.Common, + -> null + } + private fun createNativeAmountForDex(txValueAmount: String, network: Network): Amount { val nativeDecimals = Blockchain.fromNetworkId(network.backendId)?.decimals() ?: error("Blockchain not found") diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index f647d69b87..6e38987881 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -89,7 +89,7 @@ markdownComposeView = "0.5.4" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_5.16-807" +tangemBlockchainSdk = "release-app_5.16-813" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "release-app_5.16-388" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ProxyFee.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ProxyFee.kt index 77b655eb1f..6cb324fcef 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ProxyFee.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ProxyFee.kt @@ -24,4 +24,11 @@ sealed interface ProxyFee { override val fee: ProxyAmount, val gasPremium: Long, ) : ProxyFee + + data class Sui( + override val gasLimit: BigInteger, + override val fee: ProxyAmount, + val gasPrice: Long, + val gasBudget: Long, + ) : ProxyFee } \ No newline at end of file