Updated on 2026-08-14
This commit is contained in:
parent
613bb9226f
commit
3f1102f232
20 changed files with 247 additions and 172 deletions
|
|
@ -21,7 +21,6 @@ import com.tangem.blockchain.externallinkprovider.TxExploreState
|
|||
import com.tangem.blockchain.network.ResultChecker
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
|
@ -39,7 +38,6 @@ import java.math.RoundingMode
|
|||
@Suppress("LargeClass")
|
||||
class TransactionManagerImpl(
|
||||
private val appStateHolder: AppStateHolder,
|
||||
private val analytics: AnalyticsEventHandler,
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) : TransactionManager {
|
||||
|
|
@ -144,10 +142,6 @@ class TransactionManagerImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getNativeTokenDecimals(networkId: String): Int {
|
||||
return Blockchain.fromNetworkId(networkId)?.decimals() ?: error("blockchain not found")
|
||||
}
|
||||
|
||||
override suspend fun updateWalletManager(networkId: String, derivationPath: String?) {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
getActualWalletManager(blockchain, derivationPath).update()
|
||||
|
|
@ -205,7 +199,6 @@ class TransactionManagerImpl(
|
|||
return ProxyNetworkInfo(
|
||||
name = blockchain.fullName,
|
||||
blockchainId = blockchain.id,
|
||||
blockchainCurrency = blockchain.currency,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,11 +164,6 @@ class UserWalletManagerImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getNetworkCurrency(networkId: String): String {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
return blockchain.currency
|
||||
}
|
||||
|
||||
@Throws(IllegalArgumentException::class)
|
||||
private suspend fun getActualWalletManager(blockchain: Blockchain, derivationPath: String?): WalletManager {
|
||||
val selectedUserWallet = requireNotNull(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.proxy.di
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
|
|
@ -43,13 +42,11 @@ internal object ProxyModule {
|
|||
@Singleton
|
||||
fun provideTransactionManager(
|
||||
appStateHolder: AppStateHolder,
|
||||
analytics: AnalyticsEventHandler,
|
||||
cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
): TransactionManager {
|
||||
return TransactionManagerImpl(
|
||||
appStateHolder = appStateHolder,
|
||||
analytics = analytics,
|
||||
cardSdkConfigRepository = cardSdkConfigRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem.domain.tokens.model
|
|||
import java.math.BigDecimal
|
||||
|
||||
sealed class FeePaidCurrency {
|
||||
object Coin : FeePaidCurrency()
|
||||
object SameCurrency : FeePaidCurrency()
|
||||
data object Coin : FeePaidCurrency()
|
||||
data object SameCurrency : FeePaidCurrency()
|
||||
data class Token(
|
||||
val tokenId: CryptoCurrency.ID,
|
||||
val name: String,
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ class GetFeePaidCryptoCurrencyStatusSyncUseCase(
|
|||
|
||||
return either {
|
||||
when (feePaidCurrency) {
|
||||
FeePaidCurrency.Coin -> getCryptoCurrency(operations, cryptoCurrency.id)
|
||||
FeePaidCurrency.Coin -> getCryptoCurrencyStatus(operations, cryptoCurrency.id)
|
||||
FeePaidCurrency.SameCurrency -> cryptoCurrencyStatus
|
||||
is FeePaidCurrency.Token -> getCryptoCurrency(operations, feePaidCurrency.tokenId)
|
||||
is FeePaidCurrency.Token -> getCryptoCurrencyStatus(operations, feePaidCurrency.tokenId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getCryptoCurrency(
|
||||
private suspend fun getCryptoCurrencyStatus(
|
||||
operations: CurrenciesStatusesOperations,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
): CryptoCurrencyStatus? {
|
||||
|
|
|
|||
|
|
@ -3,5 +3,4 @@ package com.tangem.feature.swap.domain.models.domain
|
|||
data class NetworkInfo(
|
||||
val name: String,
|
||||
val blockchainId: String,
|
||||
val blockchainCurrency: String,
|
||||
)
|
||||
|
|
@ -7,19 +7,18 @@ import com.tangem.feature.swap.domain.models.SwapAmount
|
|||
*
|
||||
* @property isAllowedToSpend shows is token allowed to spend
|
||||
* @property isBalanceEnough shows is balance of token enough
|
||||
* @property isFeeEnough shows is amount of main coin enough for fee
|
||||
*/
|
||||
// todo Refactor this state
|
||||
data class PreparedSwapConfigState(
|
||||
val isAllowedToSpend: Boolean,
|
||||
val isBalanceEnough: Boolean,
|
||||
val isFeeEnough: Boolean,
|
||||
val feeState: SwapFeeState,
|
||||
val hasOutgoingTransaction: Boolean,
|
||||
val includeFeeInAmount: IncludeFeeInAmount,
|
||||
)
|
||||
|
||||
sealed class IncludeFeeInAmount {
|
||||
data class Included(val amountSubtractFee: SwapAmount) : IncludeFeeInAmount()
|
||||
object Excluded : IncludeFeeInAmount()
|
||||
object BalanceNotEnough : IncludeFeeInAmount()
|
||||
data object Excluded : IncludeFeeInAmount()
|
||||
data object BalanceNotEnough : IncludeFeeInAmount()
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.feature.swap.domain.models.domain
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
||||
sealed class SwapFeeState {
|
||||
data object Enough : SwapFeeState()
|
||||
data class NotEnough(
|
||||
val feeCurrency: CryptoCurrency? = null,
|
||||
val currencyName: String? = null,
|
||||
val currencySymbol: String? = null,
|
||||
) : SwapFeeState()
|
||||
}
|
||||
|
|
@ -3,10 +3,7 @@ package com.tangem.feature.swap.domain.models.ui
|
|||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.swap.domain.models.DataError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.IncludeFeeInAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.PreparedSwapConfigState
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.domain.Warning
|
||||
import com.tangem.feature.swap.domain.models.domain.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed interface SwapState {
|
||||
|
|
@ -15,11 +12,10 @@ sealed interface SwapState {
|
|||
val fromTokenInfo: TokenSwapInfo,
|
||||
val toTokenInfo: TokenSwapInfo,
|
||||
val priceImpact: PriceImpact,
|
||||
val networkCurrency: String,
|
||||
val preparedSwapConfigState: PreparedSwapConfigState = PreparedSwapConfigState(
|
||||
isAllowedToSpend = false,
|
||||
isBalanceEnough = false,
|
||||
isFeeEnough = false,
|
||||
feeState = SwapFeeState.NotEnough(),
|
||||
hasOutgoingTransaction = false,
|
||||
includeFeeInAmount = IncludeFeeInAmount.Excluded,
|
||||
),
|
||||
|
|
@ -98,7 +94,7 @@ sealed class TxFeeState {
|
|||
val fee: TxFee,
|
||||
) : TxFeeState()
|
||||
|
||||
object Empty : TxFeeState()
|
||||
data object Empty : TxFeeState()
|
||||
}
|
||||
|
||||
data class TxFee(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ internal class DefaultBlockchainInteractor @Inject constructor(
|
|||
NetworkInfo(
|
||||
name = it.name,
|
||||
blockchainId = it.blockchainId,
|
||||
blockchainCurrency = it.blockchainCurrency,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
|||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.FeePaidCurrency
|
||||
import com.tangem.domain.tokens.model.Quote
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.tokens.utils.convertToAmount
|
||||
|
|
@ -61,6 +63,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
private val swapTransactionRepository: SwapTransactionRepository,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
private val appCurrencyRepository: AppCurrencyRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val initialToCurrencyResolver: InitialToCurrencyResolver,
|
||||
) : SwapInteractor {
|
||||
|
||||
|
|
@ -251,7 +254,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
if (amountDecimal == null || amountDecimal.signum() == 0) {
|
||||
return providers.associateWith { createEmptyAmountState() }
|
||||
}
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken.currency))
|
||||
val amount = SwapAmount(amountDecimal, fromToken.currency.decimals)
|
||||
val isBalanceWithoutFeeEnough = isBalanceEnough(fromToken, amount, null)
|
||||
val networkId = fromToken.currency.network.backendId
|
||||
when (provider.type) {
|
||||
|
|
@ -433,7 +436,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return when (swapProvider.type) {
|
||||
ExchangeProviderType.CEX -> {
|
||||
val amountDecimal = toBigDecimalOrNull(amountToSwap)
|
||||
val amount = SwapAmount(requireNotNull(amountDecimal), getTokenDecimals(currencyToSend.currency))
|
||||
val amount = SwapAmount(requireNotNull(amountDecimal), currencyToSend.currency.decimals)
|
||||
val amountToSwapWithFee = if (includeFeeInAmount is IncludeFeeInAmount.Included) {
|
||||
includeFeeInAmount.amountSubtractFee
|
||||
} else {
|
||||
|
|
@ -471,17 +474,28 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
if (amountDecimal == null || amountDecimal.signum() == 0) {
|
||||
return state
|
||||
}
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken.currency))
|
||||
val amount = SwapAmount(amountDecimal, fromToken.currency.decimals)
|
||||
val includeFeeInAmount = getIncludeFeeInAmount(
|
||||
networkId = fromToken.currency.network.backendId,
|
||||
txFee = state.txFee,
|
||||
amount = amount,
|
||||
fromToken = fromToken.currency,
|
||||
)
|
||||
val fee = when (val txFee = state.txFee) {
|
||||
TxFeeState.Empty -> BigDecimal.ZERO
|
||||
is TxFeeState.MultipleFeeState -> txFee.priorityFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> txFee.fee.feeValue
|
||||
}
|
||||
val feeState = getFeeState(
|
||||
fee = fee,
|
||||
spendAmount = amount,
|
||||
networkId = fromToken.currency.network.backendId,
|
||||
fromTokenStatus = fromToken,
|
||||
)
|
||||
return state.copy(
|
||||
permissionState = PermissionDataState.Empty,
|
||||
preparedSwapConfigState = state.preparedSwapConfigState.copy(
|
||||
isFeeEnough = includeFeeInAmount !is IncludeFeeInAmount.BalanceNotEnough,
|
||||
feeState = feeState,
|
||||
isBalanceEnough = includeFeeInAmount !is IncludeFeeInAmount.BalanceNotEnough,
|
||||
includeFeeInAmount = includeFeeInAmount,
|
||||
),
|
||||
|
|
@ -497,7 +511,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
fee: TxFee,
|
||||
): TxState {
|
||||
val amountDecimal = requireNotNull(toBigDecimalOrNull(amountToSwap)) { "wrong amount format" }
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(currencyToSend))
|
||||
val amount = SwapAmount(amountDecimal, currencyToSend.decimals)
|
||||
val derivationPath = currencyToSend.network.derivationPath.value
|
||||
val result = transactionManager.sendTransaction(
|
||||
txData = SwapTxData(
|
||||
|
|
@ -713,7 +727,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
@Deprecated("used in old swap mechanism")
|
||||
override fun getTokenBalance(token: CryptoCurrencyStatus): SwapAmount {
|
||||
return SwapAmount(token.value.amount ?: BigDecimal.ZERO, getTokenDecimals(token.currency))
|
||||
return SwapAmount(token.value.amount ?: BigDecimal.ZERO, token.currency.decimals)
|
||||
}
|
||||
|
||||
@Deprecated("used in old swap mechanism")
|
||||
|
|
@ -734,14 +748,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return repository.getNativeTokenForNetwork(networkId)
|
||||
}
|
||||
|
||||
private fun getTokenDecimals(token: CryptoCurrency): Int {
|
||||
return if (token is CryptoCurrency.Token) {
|
||||
token.decimals
|
||||
} else {
|
||||
transactionManager.getNativeTokenDecimals(token.network.backendId)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun isAllowedToSpend(
|
||||
networkId: String,
|
||||
fromToken: CryptoCurrency,
|
||||
|
|
@ -755,7 +761,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
userWalletId = userWallet.walletId,
|
||||
networkId = networkId,
|
||||
derivationPath = fromToken.network.derivationPath.value,
|
||||
tokenDecimalCount = getTokenDecimals(fromToken),
|
||||
tokenDecimalCount = fromToken.decimals,
|
||||
tokenAddress = getTokenAddress(fromToken),
|
||||
spenderAddress = spenderAddress,
|
||||
)
|
||||
|
|
@ -797,7 +803,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
val toToken = toTokenStatus.currency
|
||||
return coroutineScope {
|
||||
val txFee = if (provider.type == ExchangeProviderType.CEX) {
|
||||
getFeeForCex(amount, fromTokenStatus, networkId)
|
||||
getFeeForCex(amount, fromTokenStatus)
|
||||
} else {
|
||||
TxFeeState.Empty
|
||||
}
|
||||
|
|
@ -885,10 +891,21 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
)
|
||||
}
|
||||
ExchangeProviderType.CEX -> {
|
||||
val fee = when (txFee) {
|
||||
TxFeeState.Empty -> BigDecimal.ZERO
|
||||
is TxFeeState.MultipleFeeState -> txFee.priorityFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> txFee.fee.feeValue
|
||||
}
|
||||
val feeState = getFeeState(
|
||||
fee = fee,
|
||||
spendAmount = amount,
|
||||
networkId = networkId,
|
||||
fromTokenStatus = fromToken,
|
||||
)
|
||||
swapState.copy(
|
||||
permissionState = PermissionDataState.Empty,
|
||||
preparedSwapConfigState = PreparedSwapConfigState(
|
||||
isFeeEnough = includeFeeInAmount !is IncludeFeeInAmount.BalanceNotEnough,
|
||||
feeState = feeState,
|
||||
isAllowedToSpend = isAllowedToSpend,
|
||||
isBalanceEnough = isBalanceWithoutFeeEnough,
|
||||
hasOutgoingTransaction = hasOutgoingTransaction(fromToken),
|
||||
|
|
@ -911,26 +928,47 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
private suspend fun getIncludeFeeInAmount(
|
||||
networkId: String,
|
||||
txFee: TxFeeState,
|
||||
amount: SwapAmount,
|
||||
fromToken: CryptoCurrency,
|
||||
): IncludeFeeInAmount {
|
||||
val feeValue = when (txFee) {
|
||||
TxFeeState.Empty -> BigDecimal.ZERO
|
||||
is TxFeeState.MultipleFeeState -> txFee.priorityFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> txFee.fee.feeValue
|
||||
}
|
||||
val feePaidCurrency = getFeePaidCurrency(
|
||||
userWalletId = requireNotNull(getSelectedWallet()).walletId,
|
||||
currency = fromToken,
|
||||
)
|
||||
|
||||
return when (feePaidCurrency) {
|
||||
is FeePaidCurrency.Token -> {
|
||||
if (feePaidCurrency.balance > feeValue) {
|
||||
IncludeFeeInAmount.Excluded
|
||||
} else {
|
||||
IncludeFeeInAmount.BalanceNotEnough
|
||||
}
|
||||
}
|
||||
else -> getIncludeFeeAmountForCoinFee(networkId, amount, feeValue, fromToken)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getIncludeFeeAmountForCoinFee(
|
||||
networkId: String,
|
||||
amount: SwapAmount,
|
||||
feeValue: BigDecimal,
|
||||
fromToken: CryptoCurrency,
|
||||
): IncludeFeeInAmount {
|
||||
val tokenForFeeBalance =
|
||||
userWalletManager.getNativeTokenBalance(
|
||||
networkId,
|
||||
fromToken.network.derivationPath.value,
|
||||
) ?: ProxyAmount.empty()
|
||||
|
||||
val feeValue = when (txFee) {
|
||||
TxFeeState.Empty -> BigDecimal.ZERO
|
||||
is TxFeeState.MultipleFeeState -> txFee.priorityFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> txFee.fee.feeValue
|
||||
}
|
||||
|
||||
val amountWithFee = amount.value + feeValue
|
||||
|
||||
return when {
|
||||
fromToken is CryptoCurrency.Token -> {
|
||||
if (feeValue > tokenForFeeBalance.value || tokenForFeeBalance.value.signum() == 0) {
|
||||
|
|
@ -950,7 +988,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
IncludeFeeInAmount.Included(
|
||||
SwapAmount(
|
||||
tokenForFeeBalance.value - feeValue,
|
||||
transactionManager.getNativeTokenDecimals(networkId),
|
||||
getNativeToken(fromToken.network.backendId).decimals,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -960,11 +998,18 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getFormattedFiatFees(networkId: String, vararg fees: BigDecimal): List<String> {
|
||||
private suspend fun getFormattedFiatFees(fromToken: CryptoCurrency, vararg fees: BigDecimal): List<String> {
|
||||
val appCurrency = getSelectedAppCurrencyUseCase.unwrap()
|
||||
val nativeToken = repository.getNativeTokenForNetwork(networkId)
|
||||
val rates = getQuotes(nativeToken.id)
|
||||
return rates[nativeToken.id]?.fiatRate?.let { rate ->
|
||||
val feePaidCurrency = getFeePaidCurrency(
|
||||
userWalletId = requireNotNull(getSelectedWallet()).walletId,
|
||||
currency = fromToken,
|
||||
)
|
||||
val feeCurrencyId: CryptoCurrency.ID = when (feePaidCurrency) {
|
||||
is FeePaidCurrency.Token -> feePaidCurrency.tokenId
|
||||
else -> getNativeToken(networkId = fromToken.network.backendId).id
|
||||
}
|
||||
val rates = getQuotes(feeCurrencyId)
|
||||
return rates[feeCurrencyId]?.fiatRate?.let { rate ->
|
||||
fees.map { fee ->
|
||||
fee.toFiatString(rate, appCurrency.symbol, true)
|
||||
}
|
||||
|
|
@ -1006,16 +1051,16 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
derivationPath = fromToken.currency.network.derivationPath.value,
|
||||
)
|
||||
val txFeeState = when (feeData) {
|
||||
is ProxyFees.MultipleFees -> feeData.proxyFeesToFeeState(networkId)
|
||||
is ProxyFees.SingleFee -> feeData.proxyFeesToFeeState(networkId)
|
||||
is ProxyFees.MultipleFees -> feeData.proxyFeesToFeeState(fromToken.currency)
|
||||
is ProxyFees.SingleFee -> feeData.proxyFeesToFeeState(fromToken.currency)
|
||||
}
|
||||
val feeByPriority = selectFeeByType(feeType = selectedFee, txFeeState = txFeeState)
|
||||
val isBalanceIncludeFeeEnough = isBalanceEnough(fromToken, amount, feeByPriority)
|
||||
val isFeeEnough = checkFeeIsEnough(
|
||||
val feeState = getFeeState(
|
||||
fee = feeByPriority,
|
||||
spendAmount = amount,
|
||||
networkId = networkId,
|
||||
fromToken = fromToken.currency,
|
||||
fromTokenStatus = fromToken,
|
||||
)
|
||||
val swapState = updateBalances(
|
||||
networkId = networkId,
|
||||
|
|
@ -1032,7 +1077,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
preparedSwapConfigState = PreparedSwapConfigState(
|
||||
isAllowedToSpend = true,
|
||||
isBalanceEnough = isBalanceIncludeFeeEnough,
|
||||
isFeeEnough = isFeeEnough,
|
||||
feeState = feeState,
|
||||
hasOutgoingTransaction = hasOutgoingTransaction(fromToken),
|
||||
includeFeeInAmount = IncludeFeeInAmount.Excluded, // exclude for dex
|
||||
),
|
||||
|
|
@ -1089,17 +1134,12 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
toTokenAmount = toTokenAmount.value,
|
||||
toRate = rates[toToken.id]?.fiatRate?.toDouble() ?: 0.0,
|
||||
),
|
||||
networkCurrency = userWalletManager.getNetworkCurrency(networkId),
|
||||
swapDataModel = swapData,
|
||||
txFee = txFeeState,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getFeeForCex(
|
||||
amount: SwapAmount,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
networkId: String,
|
||||
): TxFeeState {
|
||||
private suspend fun getFeeForCex(amount: SwapAmount, fromToken: CryptoCurrencyStatus): TxFeeState {
|
||||
getSelectedWalletSyncUseCase().getOrNull()?.walletId?.let { userWalletId ->
|
||||
val txFeeResult = estimateFeeUseCase(
|
||||
amount = amount.value,
|
||||
|
|
@ -1111,7 +1151,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
TxFeeState.Empty
|
||||
},
|
||||
ifRight = { txFee ->
|
||||
txFee.toTxFeeState(networkId)
|
||||
txFee.toTxFeeState(fromToken.currency)
|
||||
},
|
||||
) ?: TxFeeState.Empty
|
||||
}
|
||||
|
|
@ -1170,8 +1210,8 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
val feeState = feeData?.let {
|
||||
when (feeData) {
|
||||
is ProxyFees.MultipleFees -> feeData.proxyFeesToFeeState(networkId)
|
||||
is ProxyFees.SingleFee -> feeData.proxyFeesToFeeState(networkId)
|
||||
is ProxyFees.MultipleFees -> feeData.proxyFeesToFeeState(fromToken)
|
||||
is ProxyFees.SingleFee -> feeData.proxyFeesToFeeState(fromToken)
|
||||
}
|
||||
} ?: TxFeeState.Empty
|
||||
val fee = when (feeState) {
|
||||
|
|
@ -1179,11 +1219,11 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
is TxFeeState.MultipleFeeState -> feeState.normalFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> feeState.fee.feeValue
|
||||
}
|
||||
val isFeeEnough = checkFeeIsEnough(
|
||||
val swapFeeState = getFeeState(
|
||||
fee = fee,
|
||||
spendAmount = SwapAmount.zeroSwapAmount(),
|
||||
networkId = networkId,
|
||||
fromToken = fromToken,
|
||||
fromTokenStatus = fromTokenStatus,
|
||||
)
|
||||
return quotesLoadedState.copy(
|
||||
permissionState = PermissionDataState.PermissionReadyForRequest(
|
||||
|
|
@ -1199,28 +1239,26 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
),
|
||||
),
|
||||
preparedSwapConfigState = quotesLoadedState.preparedSwapConfigState.copy(
|
||||
isFeeEnough = isFeeEnough,
|
||||
feeState = swapFeeState,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun ProxyFees.MultipleFees.proxyFeesToFeeState(networkId: String): TxFeeState {
|
||||
private suspend fun ProxyFees.MultipleFees.proxyFeesToFeeState(fromToken: CryptoCurrency): TxFeeState {
|
||||
val normalFeeValue = this.minFee.fee.value // in swap for normal use min fee
|
||||
val normalFeeGas = this.minFee.gasLimit.toInt()
|
||||
val priorityFeeValue = this.normalFee.fee.value // in swap for priority use normal fee
|
||||
val priorityFeeGas = this.normalFee.gasLimit.toInt()
|
||||
val feesFiat = getFormattedFiatFees(networkId, normalFeeValue, priorityFeeValue)
|
||||
val feesFiat = getFormattedFiatFees(fromToken, normalFeeValue, priorityFeeValue)
|
||||
val normalFiatFee = requireNotNull(feesFiat.getOrNull(0)) { "feesFiat item 0 couldn't be null" }
|
||||
val priorityFiatFee = requireNotNull(feesFiat.getOrNull(1)) { "feesFiat item 1 couldn't be null" }
|
||||
val networkCurrency = userWalletManager.getNetworkCurrency(networkId)
|
||||
val decimals = transactionManager.getNativeTokenDecimals(networkId)
|
||||
val normalCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = normalFeeValue,
|
||||
decimals = decimals,
|
||||
decimals = minFee.fee.decimals,
|
||||
)
|
||||
val priorityCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = priorityFeeValue,
|
||||
decimals = decimals,
|
||||
decimals = normalFee.fee.decimals,
|
||||
)
|
||||
return TxFeeState.MultipleFeeState(
|
||||
normalFee = TxFee(
|
||||
|
|
@ -1228,8 +1266,8 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = normalFeeGas,
|
||||
feeFiatFormatted = normalFiatFee,
|
||||
feeCryptoFormatted = normalCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = minFee.fee.decimals,
|
||||
cryptoSymbol = minFee.fee.currencySymbol,
|
||||
feeType = FeeType.NORMAL,
|
||||
),
|
||||
priorityFee = TxFee(
|
||||
|
|
@ -1237,23 +1275,21 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = priorityFeeGas,
|
||||
feeFiatFormatted = priorityFiatFee,
|
||||
feeCryptoFormatted = priorityCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = normalFee.fee.decimals,
|
||||
cryptoSymbol = normalFee.fee.currencySymbol,
|
||||
feeType = FeeType.PRIORITY,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun ProxyFees.SingleFee.proxyFeesToFeeState(networkId: String): TxFeeState {
|
||||
private suspend fun ProxyFees.SingleFee.proxyFeesToFeeState(fromToken: CryptoCurrency): TxFeeState {
|
||||
val normalFeeValue = this.singleFee.fee.value
|
||||
val normalFeeGas = this.singleFee.gasLimit.toInt()
|
||||
val networkCurrency = userWalletManager.getNetworkCurrency(networkId)
|
||||
val feesFiat = getFormattedFiatFees(networkId, normalFeeValue)
|
||||
val feesFiat = getFormattedFiatFees(fromToken, normalFeeValue)
|
||||
val normalFiatFee = requireNotNull(feesFiat.getOrNull(0)) { "feesFiat item 0 couldn't be null" }
|
||||
val decimals = transactionManager.getNativeTokenDecimals(networkId)
|
||||
val normalCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = normalFeeValue,
|
||||
decimals = decimals,
|
||||
decimals = singleFee.fee.decimals,
|
||||
)
|
||||
return TxFeeState.SingleFeeState(
|
||||
fee = TxFee(
|
||||
|
|
@ -1261,32 +1297,30 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = normalFeeGas,
|
||||
feeFiatFormatted = normalFiatFee,
|
||||
feeCryptoFormatted = normalCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = singleFee.fee.decimals,
|
||||
cryptoSymbol = singleFee.fee.currencySymbol,
|
||||
feeType = FeeType.NORMAL,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun TransactionFee.toTxFeeState(networkId: String): TxFeeState {
|
||||
val networkCurrency = userWalletManager.getNetworkCurrency(networkId)
|
||||
val decimals = transactionManager.getNativeTokenDecimals(networkId)
|
||||
private suspend fun TransactionFee.toTxFeeState(fromToken: CryptoCurrency): TxFeeState {
|
||||
return when (this) {
|
||||
is TransactionFee.Choosable -> {
|
||||
val normalFee = this.normal.increaseGasLimitBy(INCREASE_GAS_LIMIT_FOR_SEND)
|
||||
val priorityFee = this.priority.increaseGasLimitBy(INCREASE_GAS_LIMIT_FOR_SEND)
|
||||
val feeNormal = normalFee.amount.value ?: BigDecimal.ZERO
|
||||
val feePriority = priorityFee.amount.value ?: BigDecimal.ZERO
|
||||
val normalFiatValue = getFormattedFiatFees(networkId, feeNormal)[0]
|
||||
val priorityFiatValue = getFormattedFiatFees(networkId, feePriority)[0]
|
||||
val normalFiatValue = getFormattedFiatFees(fromToken, feeNormal)[0]
|
||||
val priorityFiatValue = getFormattedFiatFees(fromToken, feePriority)[0]
|
||||
|
||||
val normalCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = feeNormal,
|
||||
decimals = decimals,
|
||||
decimals = normalFee.amount.decimals,
|
||||
)
|
||||
val priorityCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = feePriority,
|
||||
decimals = decimals,
|
||||
decimals = priorityFee.amount.decimals,
|
||||
)
|
||||
TxFeeState.MultipleFeeState(
|
||||
normalFee = TxFee(
|
||||
|
|
@ -1294,8 +1328,8 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = normalFee.getGasLimit(),
|
||||
feeFiatFormatted = normalFiatValue,
|
||||
feeCryptoFormatted = normalCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = normalFee.amount.decimals,
|
||||
cryptoSymbol = normalFee.amount.currencySymbol,
|
||||
feeType = FeeType.NORMAL,
|
||||
),
|
||||
priorityFee = TxFee(
|
||||
|
|
@ -1303,18 +1337,18 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = priorityFee.getGasLimit(),
|
||||
feeFiatFormatted = priorityFiatValue,
|
||||
feeCryptoFormatted = priorityCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = priorityFee.amount.decimals,
|
||||
cryptoSymbol = priorityFee.amount.currencySymbol,
|
||||
feeType = FeeType.PRIORITY,
|
||||
),
|
||||
)
|
||||
}
|
||||
is TransactionFee.Single -> {
|
||||
val feeNormal = this.normal.amount.value ?: BigDecimal.ZERO
|
||||
val normalFiatValue = getFormattedFiatFees(networkId, feeNormal)[0]
|
||||
val normalFiatValue = getFormattedFiatFees(fromToken, feeNormal)[0]
|
||||
val normalCryptoFee = amountFormatter.formatBigDecimalAmountToUI(
|
||||
amount = feeNormal,
|
||||
decimals = transactionManager.getNativeTokenDecimals(networkId),
|
||||
decimals = this.normal.amount.decimals,
|
||||
)
|
||||
TxFeeState.SingleFeeState(
|
||||
fee = TxFee(
|
||||
|
|
@ -1322,8 +1356,8 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
gasLimit = this.normal.getGasLimit(),
|
||||
feeFiatFormatted = normalFiatValue,
|
||||
feeCryptoFormatted = normalCryptoFee,
|
||||
decimals = decimals,
|
||||
cryptoSymbol = networkCurrency,
|
||||
decimals = normal.amount.decimals,
|
||||
cryptoSymbol = normal.amount.currencySymbol,
|
||||
feeType = FeeType.NORMAL,
|
||||
),
|
||||
)
|
||||
|
|
@ -1375,15 +1409,35 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun isBalanceEnough(fromToken: CryptoCurrencyStatus, amount: SwapAmount, fee: BigDecimal?): Boolean {
|
||||
private suspend fun isBalanceEnough(
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
amount: SwapAmount,
|
||||
fee: BigDecimal?,
|
||||
): Boolean {
|
||||
val tokenBalance = getTokenBalance(fromToken).value
|
||||
return if (fromToken.currency is CryptoCurrency.Token) {
|
||||
tokenBalance >= amount.value
|
||||
} else {
|
||||
tokenBalance > amount.value.plus(fee ?: BigDecimal.ZERO)
|
||||
val feePaidCurrency = getFeePaidCurrency(
|
||||
userWalletId = requireNotNull(getSelectedWallet()).walletId,
|
||||
currency = fromToken.currency,
|
||||
)
|
||||
return when (feePaidCurrency) {
|
||||
is FeePaidCurrency.Token -> tokenBalance >= amount.value
|
||||
else -> {
|
||||
if (fromToken.currency is CryptoCurrency.Token) {
|
||||
tokenBalance >= amount.value
|
||||
} else {
|
||||
tokenBalance > amount.value.plus(fee ?: BigDecimal.ZERO)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getFeePaidCurrency(userWalletId: UserWalletId, currency: CryptoCurrency): FeePaidCurrency {
|
||||
return currenciesRepository.getFeePaidCurrency(
|
||||
userWalletId = userWalletId,
|
||||
currency = currency,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getWalletAddress(networkId: String, derivationPath: String?): String {
|
||||
return userWalletManager.getWalletAddress(networkId, derivationPath)
|
||||
}
|
||||
|
|
@ -1399,36 +1453,72 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun checkFeeIsEnough(
|
||||
private fun toBigDecimalOrNull(amountToSwap: String): BigDecimal? {
|
||||
return amountToSwap.replace(",", ".").toBigDecimalOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getFeeState(
|
||||
fee: BigDecimal?,
|
||||
spendAmount: SwapAmount,
|
||||
networkId: String,
|
||||
fromToken: CryptoCurrency,
|
||||
): Boolean {
|
||||
fromTokenStatus: CryptoCurrencyStatus,
|
||||
): SwapFeeState {
|
||||
val userWalletId = requireNotNull(getSelectedWallet()).walletId
|
||||
if (fee == null) {
|
||||
return false
|
||||
return SwapFeeState.NotEnough()
|
||||
}
|
||||
val nativeTokenBalance = userWalletManager.getNativeTokenBalance(
|
||||
networkId,
|
||||
fromToken.network.derivationPath.value,
|
||||
)
|
||||
val percentsToFeeIncrease = BigDecimal.ONE
|
||||
return when (fromToken) {
|
||||
is CryptoCurrency.Coin -> {
|
||||
nativeTokenBalance?.let { balance ->
|
||||
return balance.value.minus(spendAmount.value) > fee.multiply(percentsToFeeIncrease)
|
||||
} ?: false
|
||||
}
|
||||
is CryptoCurrency.Token -> {
|
||||
nativeTokenBalance?.let { balance ->
|
||||
return balance.value > fee.multiply(percentsToFeeIncrease)
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toBigDecimalOrNull(amountToSwap: String): BigDecimal? {
|
||||
return amountToSwap.replace(",", ".").toBigDecimalOrNull()
|
||||
val percentsToFeeIncrease = BigDecimal.ONE
|
||||
return when (val feePaidCurrency = getFeePaidCurrency(userWalletId, fromTokenStatus.currency)) {
|
||||
FeePaidCurrency.Coin -> {
|
||||
val nativeTokenBalance = userWalletManager.getNativeTokenBalance(
|
||||
networkId,
|
||||
fromTokenStatus.currency.network.derivationPath.value,
|
||||
)
|
||||
nativeTokenBalance?.let { balance ->
|
||||
if (balance.value.minus(spendAmount.value) > fee.multiply(percentsToFeeIncrease)) {
|
||||
SwapFeeState.Enough
|
||||
} else {
|
||||
val nativeToken = getNativeToken(fromTokenStatus.currency.network.backendId)
|
||||
SwapFeeState.NotEnough(
|
||||
feeCurrency = nativeToken,
|
||||
currencyName = nativeToken.network.name,
|
||||
currencySymbol = nativeToken.symbol,
|
||||
)
|
||||
}
|
||||
} ?: SwapFeeState.NotEnough()
|
||||
}
|
||||
FeePaidCurrency.SameCurrency -> {
|
||||
val balance = fromTokenStatus.value.amount ?: return SwapFeeState.NotEnough()
|
||||
if (balance.minus(spendAmount.value) > fee.multiply(percentsToFeeIncrease)) {
|
||||
SwapFeeState.Enough
|
||||
} else {
|
||||
SwapFeeState.NotEnough(
|
||||
feeCurrency = fromTokenStatus.currency,
|
||||
currencyName = fromTokenStatus.currency.network.name,
|
||||
currencySymbol = fromTokenStatus.currency.symbol,
|
||||
)
|
||||
}
|
||||
}
|
||||
is FeePaidCurrency.Token -> {
|
||||
if (feePaidCurrency.balance > fee.multiply(percentsToFeeIncrease)) {
|
||||
SwapFeeState.Enough
|
||||
} else {
|
||||
val token = currenciesRepository
|
||||
.getMultiCurrencyWalletCurrenciesSync(userWalletId)
|
||||
.find {
|
||||
it is CryptoCurrency.Token &&
|
||||
it.contractAddress.equals(feePaidCurrency.contractAddress, ignoreCase = true) &&
|
||||
it.network.derivationPath == fromTokenStatus.currency.network.derivationPath
|
||||
}
|
||||
SwapFeeState.NotEnough(
|
||||
feeCurrency = token,
|
||||
currencyName = feePaidCurrency.name,
|
||||
currencySymbol = feePaidCurrency.symbol,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculatePriceImpact(
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class SwapDomainModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
coroutineDispatcherProvider: CoroutineDispatcherProvider,
|
||||
initialToCurrencyResolver: InitialToCurrencyResolver,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
): SwapInteractor {
|
||||
return SwapInteractorImpl(
|
||||
transactionManager = transactionManager,
|
||||
|
|
@ -62,6 +63,7 @@ class SwapDomainModule {
|
|||
swapTransactionRepository = swapTransactionRepository,
|
||||
appCurrencyRepository = appCurrencyRepository,
|
||||
currencyChecksRepository = currencyChecksRepository,
|
||||
currenciesRepository = currenciesRepository,
|
||||
initialToCurrencyResolver = initialToCurrencyResolver,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import com.tangem.feature.swap.models.states.ProviderState
|
|||
data class SwapStateHolder(
|
||||
val sendCardData: SwapCardState,
|
||||
val receiveCardData: SwapCardState,
|
||||
val networkCurrency: String,
|
||||
val blockchainId: String, // not the same as networkId, its local id in app
|
||||
val warnings: List<SwapWarning> = emptyList(),
|
||||
val alert: SwapWarning.GenericWarning? = null,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.swap.models
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.feature.swap.domain.models.ui.TxFee
|
||||
|
||||
data class UiActions(
|
||||
|
|
@ -20,7 +21,7 @@ data class UiActions(
|
|||
val onSelectFeeType: (TxFee) -> Unit,
|
||||
val onProviderClick: (String) -> Unit,
|
||||
val onProviderSelect: (String) -> Unit,
|
||||
val onBuyClick: () -> Unit,
|
||||
val onBuyClick: (CryptoCurrency) -> Unit,
|
||||
val onPolicyClick: (String) -> Unit,
|
||||
val onTosClick: (String) -> Unit,
|
||||
val onReceiveCardWarningClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ internal class StateBuilder(
|
|||
isBalanceHidden = true,
|
||||
),
|
||||
fee = FeeItemState.Empty,
|
||||
networkCurrency = networkInfo.blockchainCurrency,
|
||||
swapButton = SwapButton(enabled = false, onClick = {}),
|
||||
onRefresh = {},
|
||||
onBackClicked = actions.onBackClicked,
|
||||
|
|
@ -250,7 +249,6 @@ internal class StateBuilder(
|
|||
balance = toCurrencyStatus.getFormattedAmount(isNeedSymbol = false),
|
||||
isBalanceHidden = isBalanceHiddenProvider(),
|
||||
),
|
||||
networkCurrency = quoteModel.networkCurrency,
|
||||
warnings = warnings,
|
||||
permissionState = convertPermissionState(
|
||||
lastPermissionState = uiStateHolder.permissionState,
|
||||
|
|
@ -317,7 +315,7 @@ internal class StateBuilder(
|
|||
val warnings = mutableListOf<SwapWarning>()
|
||||
addDomainWarnings(quoteModel, warnings)
|
||||
if (!quoteModel.preparedSwapConfigState.isAllowedToSpend &&
|
||||
quoteModel.preparedSwapConfigState.isFeeEnough &&
|
||||
quoteModel.preparedSwapConfigState.feeState is SwapFeeState.Enough &&
|
||||
quoteModel.permissionState is PermissionDataState.PermissionReadyForRequest
|
||||
) {
|
||||
warnings.add(
|
||||
|
|
@ -412,7 +410,8 @@ internal class StateBuilder(
|
|||
fromToken: CryptoCurrency,
|
||||
warnings: MutableList<SwapWarning>,
|
||||
) {
|
||||
if (!quoteModel.preparedSwapConfigState.isFeeEnough &&
|
||||
val feeEnoughState = quoteModel.preparedSwapConfigState.feeState
|
||||
if (feeEnoughState is SwapFeeState.NotEnough &&
|
||||
quoteModel.preparedSwapConfigState.isBalanceEnough &&
|
||||
quoteModel.permissionState !is PermissionDataState.PermissionLoading
|
||||
) {
|
||||
|
|
@ -420,7 +419,9 @@ internal class StateBuilder(
|
|||
SwapWarning.UnableToCoverFeeWarning(
|
||||
createUnableToCoverFeeNotificationConfig(
|
||||
fromToken = fromToken,
|
||||
onBuyClick = actions.onBuyClick,
|
||||
feeCurrency = feeEnoughState.feeCurrency,
|
||||
currencyName = feeEnoughState.currencyName ?: fromToken.network.name,
|
||||
currencySymbol = feeEnoughState.currencySymbol ?: fromToken.network.currencySymbol,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -438,7 +439,7 @@ internal class StateBuilder(
|
|||
IncludeFeeInAmount.Excluded ->
|
||||
preparedSwapConfigState.isAllowedToSpend &&
|
||||
preparedSwapConfigState.isBalanceEnough &&
|
||||
preparedSwapConfigState.isFeeEnough
|
||||
preparedSwapConfigState.feeState is SwapFeeState.Enough
|
||||
is IncludeFeeInAmount.Included -> true
|
||||
}
|
||||
}
|
||||
|
|
@ -1219,8 +1220,16 @@ internal class StateBuilder(
|
|||
|
||||
private fun createUnableToCoverFeeNotificationConfig(
|
||||
fromToken: CryptoCurrency,
|
||||
onBuyClick: () -> Unit,
|
||||
feeCurrency: CryptoCurrency?,
|
||||
currencyName: String,
|
||||
currencySymbol: String,
|
||||
): NotificationConfig {
|
||||
val buttonState = feeCurrency?.let {
|
||||
NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.common_buy_currency, wrappedList(currencySymbol)),
|
||||
onClick = { actions.onBuyClick(it) },
|
||||
)
|
||||
}
|
||||
return NotificationConfig(
|
||||
title = resourceReference(
|
||||
R.string.warning_express_not_enough_fee_for_token_tx_title,
|
||||
|
|
@ -1228,13 +1237,10 @@ internal class StateBuilder(
|
|||
),
|
||||
subtitle = resourceReference(
|
||||
R.string.warning_express_not_enough_fee_for_token_tx_description,
|
||||
wrappedList(fromToken.network.name, fromToken.network.currencySymbol),
|
||||
wrappedList(currencyName, currencySymbol),
|
||||
),
|
||||
iconResId = fromToken.networkIconResId,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.common_buy_currency, wrappedList(fromToken.network.currencySymbol)),
|
||||
onClick = onBuyClick,
|
||||
),
|
||||
buttonsState = buttonState,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -490,7 +490,6 @@ private val state = SwapStateHolder(
|
|||
),
|
||||
),
|
||||
),
|
||||
networkCurrency = "MATIC",
|
||||
swapButton = SwapButton(enabled = true, onClick = {}),
|
||||
onRefresh = {},
|
||||
onBackClicked = {},
|
||||
|
|
|
|||
|
|
@ -932,12 +932,11 @@ internal class SwapViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
},
|
||||
onBuyClick = {
|
||||
swapInteractor.getSelectedWallet()?.let {
|
||||
val fromToken = dataState.fromCryptoCurrency ?: return@let
|
||||
onBuyClick = { currency ->
|
||||
swapInteractor.getSelectedWallet()?.let { userWallet ->
|
||||
swapRouter.openTokenDetails(
|
||||
it.walletId,
|
||||
swapInteractor.getNativeToken(fromToken.currency.network.backendId),
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = currency,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -54,9 +54,6 @@ interface TransactionManager {
|
|||
derivationPath: String?,
|
||||
): ProxyFees
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
fun getNativeTokenDecimals(networkId: String): Int
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
suspend fun updateWalletManager(networkId: String, derivationPath: String?)
|
||||
|
||||
|
|
|
|||
|
|
@ -59,13 +59,6 @@ interface UserWalletManager {
|
|||
@Throws(IllegalStateException::class)
|
||||
suspend fun getNativeTokenBalance(networkId: String, derivationPath: String?): ProxyAmount?
|
||||
|
||||
/**
|
||||
* @param networkId
|
||||
* @return currency name
|
||||
*/
|
||||
@Throws(IllegalStateException::class)
|
||||
fun getNetworkCurrency(networkId: String): String
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
suspend fun getLastTransactionHash(networkId: String, derivationPath: String?): String?
|
||||
}
|
||||
|
|
@ -3,5 +3,4 @@ package com.tangem.lib.crypto.models
|
|||
data class ProxyNetworkInfo(
|
||||
val name: String,
|
||||
val blockchainId: String,
|
||||
val blockchainCurrency: String,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue