Updated on 2026-08-14

This commit is contained in:
Tangem 2024-10-04 16:54:47 +04:00
commit addacc6b07
4 changed files with 253 additions and 49 deletions

View file

@ -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,

View file

@ -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

View file

@ -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")

View file

@ -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
}