Updated on 2026-08-14
This commit is contained in:
parent
c8b7934d93
commit
bdf2433cb7
7 changed files with 317 additions and 20 deletions
|
|
@ -363,4 +363,23 @@ internal object TransactionDomainModule {
|
|||
getMultiCryptoCurrencyStatusUseCase = getMultiCryptoCurrencyStatusUseCase,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideEstimateFeeForGaslessTxUseCase(
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
estimateFeeUseCase: EstimateFeeUseCase,
|
||||
): EstimateFeeForGaslessTxUseCase {
|
||||
return EstimateFeeForGaslessTxUseCase(
|
||||
gaslessTransactionRepository = gaslessTransactionRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
demoConfig = DemoConfig,
|
||||
currenciesRepository = currenciesRepository,
|
||||
getMultiCryptoCurrencyStatusUseCase = getMultiCryptoCurrencyStatusUseCase,
|
||||
estimateFeeUseCase = estimateFeeUseCase,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
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.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.error.GetFeeError.GaslessError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.domain.transaction.raiseIllegalStateError
|
||||
import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import java.math.BigDecimal
|
||||
|
||||
class EstimateFeeForGaslessTxUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val estimateFeeUseCase: EstimateFeeUseCase,
|
||||
) {
|
||||
|
||||
private val tokenFeeCalculator = TokenFeeCalculator(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
gaslessTransactionRepository = gaslessTransactionRepository,
|
||||
demoConfig = demoConfig,
|
||||
)
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWallet: UserWallet,
|
||||
amount: BigDecimal,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): Either<GetFeeError, TransactionFeeExtended> {
|
||||
return either {
|
||||
catch(
|
||||
block = {
|
||||
val network = cryptoCurrencyStatus.currency.network
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = network.id,
|
||||
derivationPath = network.derivationPath,
|
||||
)
|
||||
|
||||
if (!gaslessTransactionRepository.isNetworkSupported(network)) {
|
||||
estimateFeeUseCase.invoke(
|
||||
userWallet = userWallet,
|
||||
amount = amount,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
).fold(
|
||||
ifLeft = { raise(it) },
|
||||
ifRight = { fee ->
|
||||
return@either TransactionFeeExtended(
|
||||
transactionFee = fee,
|
||||
feeTokenId = nativeCurrency.id,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
val walletManager = prepareWalletManager(userWallet, network)
|
||||
|
||||
val initialFee = tokenFeeCalculator.estimateInitialFee(
|
||||
userWallet = userWallet,
|
||||
amount = amount,
|
||||
tokenCurrencyStatus = cryptoCurrencyStatus,
|
||||
).bind()
|
||||
|
||||
selectFeePaymentStrategy(
|
||||
userWallet = userWallet,
|
||||
walletManager = walletManager,
|
||||
nativeCurrency = nativeCurrency,
|
||||
network = network,
|
||||
initialFee = initialFee,
|
||||
)
|
||||
},
|
||||
catch = {
|
||||
raise(GetFeeError.DataError(it))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NullableToStringCall")
|
||||
private suspend fun Raise<GetFeeError>.prepareWalletManager(
|
||||
userWallet: UserWallet,
|
||||
network: Network,
|
||||
): EthereumWalletManager {
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = network,
|
||||
)
|
||||
val ethereumWalletManager = walletManager as? EthereumWalletManager
|
||||
?: raiseIllegalStateError("WalletManager type ${walletManager?.javaClass?.name} not supported")
|
||||
return ethereumWalletManager
|
||||
}
|
||||
|
||||
private suspend fun Raise<GetFeeError>.selectFeePaymentStrategy(
|
||||
userWallet: UserWallet,
|
||||
walletManager: EthereumWalletManager,
|
||||
nativeCurrency: CryptoCurrency,
|
||||
network: Network,
|
||||
initialFee: TransactionFee,
|
||||
): TransactionFeeExtended {
|
||||
val feeValue = initialFee.normal.amount.value ?: raise(GetFeeError.UnknownError)
|
||||
|
||||
val userCurrenciesStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull() ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val networkCurrenciesStatuses = userCurrenciesStatuses.filter {
|
||||
it.currency.network.id == network.id
|
||||
}
|
||||
|
||||
val nativeCurrencyStatus = networkCurrenciesStatuses.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${network.id}")
|
||||
|
||||
val nativeBalance = nativeCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
return if (nativeBalance >= feeValue) {
|
||||
TransactionFeeExtended(transactionFee = initialFee, feeTokenId = nativeCurrencyStatus.currency.id)
|
||||
} else {
|
||||
findTokensToPayFee(
|
||||
walletManager = walletManager,
|
||||
initialTxFee = initialFee,
|
||||
nativeCurrencyStatus = nativeCurrencyStatus,
|
||||
networkCurrenciesStatuses = networkCurrenciesStatuses,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NullableToStringCall")
|
||||
private suspend fun Raise<GetFeeError>.findTokensToPayFee(
|
||||
walletManager: EthereumWalletManager,
|
||||
initialTxFee: TransactionFee,
|
||||
nativeCurrencyStatus: CryptoCurrencyStatus,
|
||||
networkCurrenciesStatuses: List<CryptoCurrencyStatus>,
|
||||
): TransactionFeeExtended {
|
||||
val initialFee = initialTxFee.normal as? Fee.Ethereum
|
||||
?: raiseIllegalStateError(
|
||||
error = "only Fee.Ethereum supported, but was ${initialTxFee.normal::class.qualifiedName}",
|
||||
)
|
||||
|
||||
val supportedGaslessTokens = gaslessTransactionRepository.getSupportedTokens(
|
||||
network = nativeCurrencyStatus.currency.network,
|
||||
).mapNotNull { currency ->
|
||||
(currency as? CryptoCurrency.Token)?.contractAddress
|
||||
}.toSet()
|
||||
|
||||
val supportedGaslessTokensStatusesSortedByBalanceDesc = networkCurrenciesStatuses
|
||||
.filterNot { it.value.amount == BigDecimal.ZERO || it.currency !is CryptoCurrency.Token }
|
||||
.sortedByDescending { it.value.amount }
|
||||
.filter { status ->
|
||||
val token = status.currency as? CryptoCurrency.Token ?: return@filter false
|
||||
token.contractAddress.lowercase() in supportedGaslessTokens
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects token with highest balance to maximize chances of successful fee payment.
|
||||
* Returns null if no suitable tokens found.
|
||||
*/
|
||||
val tokenForPayFeeStatus = supportedGaslessTokensStatusesSortedByBalanceDesc.firstOrNull()
|
||||
?: raise(GaslessError.NoSupportedTokensFound)
|
||||
|
||||
return tokenFeeCalculator.calculateTokenFee(
|
||||
walletManager = walletManager,
|
||||
tokenForPayFeeStatus = tokenForPayFeeStatus,
|
||||
nativeCurrencyStatus = nativeCurrencyStatus,
|
||||
initialFee = initialFee,
|
||||
).bind()
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.tangem.blockchain.extensions.Result
|
|||
import com.tangem.domain.demo.DemoTransactionSender
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
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.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
|
|
@ -38,24 +39,15 @@ class EstimateFeeForTokenUseCase(
|
|||
|
||||
suspend operator fun invoke(
|
||||
userWallet: UserWallet,
|
||||
token: CryptoCurrency,
|
||||
tokenCurrencyStatus: CryptoCurrencyStatus,
|
||||
amount: BigDecimal,
|
||||
): Either<GetFeeError, TransactionFeeExtended> {
|
||||
return either {
|
||||
val token = tokenCurrencyStatus.currency
|
||||
if (!gaslessTransactionRepository.isNetworkSupported(token.network)) {
|
||||
raise(GetFeeError.GaslessError.NetworkIsNotSupported)
|
||||
}
|
||||
|
||||
val userCurrenciesStatusesByNetwork = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull()?.filter {
|
||||
it.currency.network.id == token.network.id
|
||||
} ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val tokenCurrencyStatus = userCurrenciesStatusesByNetwork.find {
|
||||
it.currency.id == token.id
|
||||
} ?: raiseIllegalStateError("token currency not found for network ${token.network.id}")
|
||||
|
||||
val amountData = amount.convertToSdkAmount(tokenCurrencyStatus)
|
||||
val result = if (userWallet is UserWallet.Cold &&
|
||||
demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)
|
||||
|
|
@ -89,6 +81,12 @@ class EstimateFeeForTokenUseCase(
|
|||
derivationPath = token.network.derivationPath,
|
||||
)
|
||||
|
||||
val userCurrenciesStatusesByNetwork = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull()?.filter {
|
||||
it.currency.network.id == token.network.id
|
||||
} ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val nativeCurrencyStatus = userCurrenciesStatusesByNetwork.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${token.network.id}")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.domain.transaction.error.GetFeeError.GaslessError
|
|||
import com.tangem.domain.transaction.error.mapToFeeError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.domain.transaction.raiseIllegalStateError
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
|
@ -56,6 +57,37 @@ internal class TokenFeeCalculator(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun estimateInitialFee(
|
||||
userWallet: UserWallet,
|
||||
amount: BigDecimal,
|
||||
tokenCurrencyStatus: CryptoCurrencyStatus,
|
||||
): Either<GetFeeError, TransactionFee> {
|
||||
return either {
|
||||
val network = tokenCurrencyStatus.currency.network
|
||||
val amountData = amount.convertToSdkAmount(tokenCurrencyStatus)
|
||||
val result = if (userWallet is UserWallet.Cold &&
|
||||
demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)
|
||||
) {
|
||||
demoTransactionSender(userWallet, network).estimateFee(
|
||||
amount = amountData,
|
||||
destination = "",
|
||||
)
|
||||
} else {
|
||||
walletManagersFacade.estimateFee(
|
||||
amount = amountData,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = network,
|
||||
)
|
||||
}
|
||||
|
||||
when (result) {
|
||||
is Result.Success -> result.data
|
||||
is Result.Failure -> raise(result.mapToFeeError())
|
||||
null -> raise(GetFeeError.UnknownError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun calculateTokenFee(
|
||||
walletManager: EthereumWalletManager,
|
||||
tokenForPayFeeStatus: CryptoCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
|
|||
params = FeeSelectorBlockParams(
|
||||
state = model.uiState.value.feeSelectorUM,
|
||||
onLoadFee = model::loadFee,
|
||||
onLoadFeeExtended = model::loadFeeExtended,
|
||||
feeCryptoCurrencyStatus = model.primaryFeePaidCurrencyStatus,
|
||||
cryptoCurrencyStatus = model.primaryCurrencyStatus,
|
||||
feeStateConfiguration = FeeStateConfiguration.ExcludeLow,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.swap.v2.impl.sendviaswap.confirm.model
|
|||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.left
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
|
||||
|
|
@ -26,7 +27,10 @@ import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
|
|||
import com.tangem.domain.swap.models.SwapDirection.Companion.withSwapDirection
|
||||
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.gasless.EstimateFeeForGaslessTxUseCase
|
||||
import com.tangem.domain.transaction.usecase.gasless.EstimateFeeForTokenUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
|
||||
|
|
@ -64,6 +68,7 @@ import jakarta.inject.Inject
|
|||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned
|
||||
import com.tangem.utils.transformer.update as transformerUpdate
|
||||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
|
|
@ -73,6 +78,8 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
private val router: Router,
|
||||
private val isSendTapHelpEnabledUseCase: IsSendTapHelpEnabledUseCase,
|
||||
private val estimateFeeUseCase: EstimateFeeUseCase,
|
||||
private val estimateFeeForTokenUseCase: EstimateFeeForTokenUseCase,
|
||||
private val estimateFeeForGaslessTxUseCase: EstimateFeeForGaslessTxUseCase,
|
||||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val sendNotificationsUpdateTrigger: SendNotificationsUpdateTrigger,
|
||||
|
|
@ -106,6 +113,8 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
get() = uiState.value.destinationUM as? DestinationUM.Content
|
||||
private val feeSelectorUM
|
||||
get() = uiState.value.feeSelectorUM as? FeeSelectorUM.Content
|
||||
private val feeUMV2
|
||||
get() = uiState.value.feeSelectorUM as? FeeSelectorUMRedesigned.Content
|
||||
|
||||
val secondaryCurrencyStatus: CryptoCurrencyStatus? = amountUM?.secondaryCryptoCurrencyStatus
|
||||
val secondaryCurrency: CryptoCurrency = requireNotNull(amountUM?.secondaryCryptoCurrencyStatus?.currency) {
|
||||
|
|
@ -143,7 +152,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
}
|
||||
|
||||
init {
|
||||
initAmountSubtractAvailability()
|
||||
updateAmountSubtractAvailability()
|
||||
configConfirmNavigation()
|
||||
initialState()
|
||||
subscribeOnNotificationUpdates()
|
||||
|
|
@ -152,6 +161,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
|
||||
override fun onFeeResult(feeSelectorUM: FeeSelectorUM) {
|
||||
uiState.update { it.copy(feeSelectorUM = feeSelectorUM) }
|
||||
updateAmountSubtractAvailability()
|
||||
updateConfirmNotifications()
|
||||
}
|
||||
|
||||
|
|
@ -243,11 +253,43 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun loadFeeExtended(maybeToken: CryptoCurrencyStatus?): Either<GetFeeError, TransactionFeeExtended> {
|
||||
val defaultError = GetFeeError.UnknownError.left()
|
||||
val provider = (confirmData.quote as? SwapQuoteUM.Content)?.provider ?: return defaultError
|
||||
val amountValue = confirmData.enteredAmount ?: return defaultError
|
||||
|
||||
return when (val providerType = provider.type) {
|
||||
ExpressProviderType.CEX -> {
|
||||
if (maybeToken != null) {
|
||||
estimateFeeForTokenUseCase(
|
||||
amount = amountValue,
|
||||
userWallet = params.userWallet,
|
||||
tokenCurrencyStatus = maybeToken,
|
||||
)
|
||||
} else {
|
||||
estimateFeeForGaslessTxUseCase(
|
||||
amount = amountValue,
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrencyStatus = primaryCurrencyStatus,
|
||||
)
|
||||
}
|
||||
}
|
||||
ExpressProviderType.DEX,
|
||||
ExpressProviderType.DEX_BRIDGE,
|
||||
ExpressProviderType.ONRAMP,
|
||||
-> GetFeeError.DataError(
|
||||
cause = IllegalStateException("Provider $providerType is not supported in Send With Swap"),
|
||||
).left()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSendClick() {
|
||||
val provider = confirmData.quote?.provider ?: return
|
||||
modelScope.launch {
|
||||
uiState.transformerUpdate(SendWithSwapConfirmSendingStateTransformer(true))
|
||||
val feeExtended = feeUMV2?.feeExtraInfo?.transactionFeeExtended
|
||||
swapTransactionSender.sendTransaction(
|
||||
feeExtended = feeExtended,
|
||||
confirmData = confirmData,
|
||||
isAmountSubtractAvailable = isAmountSubtractAvailable,
|
||||
onExpressError = { expressError ->
|
||||
|
|
@ -305,12 +347,15 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun initAmountSubtractAvailability() {
|
||||
private fun updateAmountSubtractAvailability() {
|
||||
modelScope.launch {
|
||||
val isGaslessEthTx =
|
||||
feeUMV2?.feeExtraInfo?.transactionFeeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency
|
||||
isAmountSubtractAvailable =
|
||||
isAmountSubtractAvailableUseCase(
|
||||
params.userWallet.walletId,
|
||||
primaryCurrencyStatus.currency,
|
||||
userWalletId = params.userWallet.walletId,
|
||||
currency = primaryCurrencyStatus.currency,
|
||||
isGaslessEthTx = isGaslessEthTx,
|
||||
).getOrElse { false }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ import com.tangem.domain.swap.models.SwapTxType
|
|||
import com.tangem.domain.swap.usecase.GetSwapDataUseCase
|
||||
import com.tangem.domain.swap.usecase.SwapTransactionSentUseCase
|
||||
import com.tangem.domain.transaction.error.SendTransactionError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.gasless.CreateAndSendGaslessTransactionUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils
|
||||
import com.tangem.features.swap.v2.impl.common.ConfirmData
|
||||
|
|
@ -35,6 +37,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
|
||||
private val swapTransactionSentUseCase: SwapTransactionSentUseCase,
|
||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||
private val createAndSendGaslessTransactionUseCase: CreateAndSendGaslessTransactionUseCase,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
) {
|
||||
|
||||
|
|
@ -45,6 +48,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
onExpressError: (ExpressError) -> Unit,
|
||||
onSendError: (SendTransactionError?) -> Unit,
|
||||
expressOperationType: ExpressOperationType,
|
||||
feeExtended: TransactionFeeExtended?,
|
||||
) {
|
||||
val provider = confirmData.quote?.provider ?: return
|
||||
|
||||
|
|
@ -56,6 +60,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
onSendSuccess = onSendSuccess,
|
||||
onSendError = onSendError,
|
||||
expressOperationType = expressOperationType,
|
||||
feeExtended = feeExtended,
|
||||
)
|
||||
ExpressProviderType.DEX,
|
||||
ExpressProviderType.DEX_BRIDGE,
|
||||
|
|
@ -74,6 +79,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
onExpressError: (ExpressError) -> Unit,
|
||||
onSendError: (SendTransactionError?) -> Unit,
|
||||
expressOperationType: ExpressOperationType,
|
||||
feeExtended: TransactionFeeExtended?,
|
||||
) {
|
||||
val fromStatus = confirmData.fromCryptoCurrencyStatus ?: return
|
||||
val toStatus = confirmData.toCryptoCurrencyStatus ?: return
|
||||
|
|
@ -114,6 +120,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
onSendSuccess = onSendSuccess,
|
||||
onExpressError = onExpressError,
|
||||
onSendError = onSendError,
|
||||
feeExtended = feeExtended,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +130,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
toStatus: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
fee: Fee,
|
||||
feeExtended: TransactionFeeExtended?,
|
||||
provider: ExpressProvider,
|
||||
swapData: SwapDataModel,
|
||||
onSendSuccess: (String, Long, SwapDataModel) -> Unit,
|
||||
|
|
@ -161,11 +169,22 @@ internal class SwapTransactionSender @AssistedInject constructor(
|
|||
txData.destinationAddress
|
||||
}
|
||||
|
||||
sendTransactionUseCase(
|
||||
txData = txData,
|
||||
userWallet = userWallet,
|
||||
network = fromStatus.currency.network,
|
||||
).fold(
|
||||
val isFeeInTokenCurrency = feeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency
|
||||
|
||||
val result = if (feeExtended != null && isFeeInTokenCurrency) {
|
||||
createAndSendGaslessTransactionUseCase(
|
||||
userWallet = userWallet,
|
||||
transactionData = txData,
|
||||
fee = feeExtended,
|
||||
)
|
||||
} else {
|
||||
sendTransactionUseCase(
|
||||
txData = txData,
|
||||
userWallet = userWallet,
|
||||
network = fromStatus.currency.network,
|
||||
)
|
||||
}
|
||||
result.fold(
|
||||
ifLeft = { onSendError(it) },
|
||||
ifRight = { txHash ->
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue