Updated on 2026-08-14

This commit is contained in:
Tangem 2023-05-25 18:35:19 +03:00
parent 9421105c9f
commit e50716f834
3 changed files with 37 additions and 8 deletions

View file

@ -154,7 +154,7 @@ internal class SwapInteractorImpl @Inject constructor(
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken))
val fromTokenAddress = getTokenAddress(fromToken)
val toTokenAddress = getTokenAddress(toToken)
val isAllowedToSpend = checkAllowance(networkId, fromTokenAddress)
val isAllowedToSpend = isAllowedToSpend(networkId, fromTokenAddress, amount)
if (isAllowedToSpend && allowPermissionsHandler.isAddressAllowanceInProgress(fromTokenAddress)) {
allowPermissionsHandler.removeAddressFromProgress(fromTokenAddress)
transactionManager.updateWalletManager(networkId, derivationPath)
@ -295,13 +295,14 @@ internal class SwapInteractorImpl @Inject constructor(
}
}
private suspend fun checkAllowance(networkId: String, fromTokenAddress: String): Boolean {
private suspend fun isAllowedToSpend(networkId: String, fromTokenAddress: String, amount: SwapAmount): Boolean {
val allowance = repository.checkTokensSpendAllowance(
networkId = networkId,
tokenAddress = fromTokenAddress,
walletAddress = userWalletManager.getWalletAddress(networkId, derivationPath),
)
return allowance.error == DataError.NoError && allowance.dataModel != ZERO_BALANCE
val allowanceAmount = allowance.dataModel?.toBigDecimalOrNull() ?: BigDecimal.ZERO
return allowance.error == DataError.NoError && allowanceAmount >= amount.value.movePointRight(amount.decimals)
}
private fun createEmptyAmountState(networkId: String, fromToken: Currency, toToken: Currency): SwapState {

View file

@ -103,10 +103,20 @@ internal class StateBuilder(val actions: UiActions) {
)
}
/**
* Create quotes loaded state
*
* @param uiStateHolder whole screen state
* @param quoteModel data model
* @param fromToken token data to swap
* @param onFeeSetup callback for reset fee after auto update
* @return updated whole screen state
*/
fun createQuotesLoadedState(
uiStateHolder: SwapStateHolder,
quoteModel: SwapState.QuotesLoadedState,
fromToken: Currency,
onFeeSetup: (TxFee) -> Unit,
): SwapStateHolder {
val warnings = mutableListOf<SwapWarning>()
if (!quoteModel.preparedSwapConfigState.isAllowedToSpend &&
@ -122,7 +132,7 @@ internal class StateBuilder(val actions: UiActions) {
if (quoteModel.priceImpact > PRICE_IMPACT_THRESHOLD) {
warnings.add(SwapWarning.HighPriceImpact((quoteModel.priceImpact * HUNDRED_PERCENTS).toInt()))
}
val feeState = createFeeState(quoteModel, uiStateHolder)
val feeState = createFeeState(quoteModel, uiStateHolder, onFeeSetup)
return uiStateHolder.copy(
sendCardData = SwapCardData(
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.SendCard),
@ -282,22 +292,31 @@ internal class StateBuilder(val actions: UiActions) {
}
}
private fun createFeeState(quoteModel: SwapState.QuotesLoadedState, uiStateHolder: SwapStateHolder): FeeState {
private fun createFeeState(
quoteModel: SwapState.QuotesLoadedState,
uiStateHolder: SwapStateHolder,
onFeeSetup: (TxFee) -> Unit,
): FeeState {
val previousFeeState = when (val stateFee = uiStateHolder.fee) {
is FeeState.Loaded -> stateFee.state
is FeeState.NotEnoughFundsWarning -> stateFee.state
else -> null
}
val selectFeeState = createSelectFeeState(
fee = quoteModel.swapDataModel?.fee,
previousState = previousFeeState,
onFeeSetup = onFeeSetup,
)
return if (quoteModel.preparedSwapConfigState.isFeeEnough) {
FeeState.Loaded(
tangemFee = quoteModel.tangemFee,
state = createSelectFeeState(quoteModel.swapDataModel?.fee, previousFeeState),
state = selectFeeState,
onSelectItem = actions.onSelectItemFee,
)
} else {
FeeState.NotEnoughFundsWarning(
tangemFee = quoteModel.tangemFee,
state = createSelectFeeState(quoteModel.swapDataModel?.fee, previousFeeState),
state = selectFeeState,
onSelectItem = actions.onSelectItemFee,
)
}
@ -422,9 +441,11 @@ internal class StateBuilder(val actions: UiActions) {
private fun createSelectFeeState(
fee: TxFeeState?,
previousState: SelectableItemsState<TxFee>?,
onFeeSetup: (TxFee) -> Unit,
): SelectableItemsState<TxFee>? {
if (fee == null) return null
if (previousState == null) {
onFeeSetup.invoke(fee.normalFee) // if there is no previous state, setup normal fee by default
val selectedItemId = 0
// by default preselect normal
val preselectedItem = Item(
@ -469,8 +490,10 @@ internal class StateBuilder(val actions: UiActions) {
),
)
val selectedEndText = if (normalFeeItem.isSelected) {
onFeeSetup.invoke(fee.normalFee)
normalFeeItem.endText
} else {
onFeeSetup.invoke(fee.priorityFee)
priorityFeeItem.endText
}
return previousState.copy(

View file

@ -184,7 +184,11 @@ internal class SwapViewModel @Inject constructor(
uiStateHolder = uiState,
quoteModel = swapState,
fromToken = fromToken,
)
) { updatedFee ->
dataState = dataState.copy(
selectedFee = updatedFee,
)
}
}
is SwapState.EmptyAmountState -> {
uiState = stateBuilder.createQuotesEmptyAmountState(
@ -213,6 +217,7 @@ internal class SwapViewModel @Inject constructor(
} else {
dataState.copy(
swapDataModel = swapDataModel,
selectedFee = swapDataModel?.fee?.normalFee,
)
}
}