Updated on 2026-08-14
This commit is contained in:
parent
e8c5c35e56
commit
8cb94b6b7c
5 changed files with 72 additions and 27 deletions
|
|
@ -4,7 +4,10 @@ import java.math.BigDecimal
|
|||
|
||||
sealed class Warning {
|
||||
|
||||
data class ExistentialDepositWarning(val existentialDeposit: BigDecimal) : Warning()
|
||||
data class ExistentialDepositWarning(
|
||||
val existentialDeposit: BigDecimal,
|
||||
val minAvailableAmount: BigDecimal,
|
||||
) : Warning()
|
||||
|
||||
data class MinAmountWarning(val dustValue: BigDecimal) : Warning()
|
||||
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
val fromToken = fromTokenStatus.currency
|
||||
val userWalletId = getSelectedWallet()?.walletId ?: return emptyList()
|
||||
val warnings = mutableListOf<Warning>()
|
||||
manageExistentialDepositWarning(warnings, userWalletId, amount, fromToken)
|
||||
manageExistentialDepositWarning(warnings, userWalletId, amount, fromToken, feeState)
|
||||
manageDustWarning(warnings, feeState, userWalletId, fromTokenStatus, amount)
|
||||
manageReduceAmountWarning(warnings, fromTokenStatus, amount)
|
||||
manageTransactionValidationWarnings(
|
||||
|
|
@ -404,6 +404,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
userWalletId: UserWalletId,
|
||||
amount: SwapAmount,
|
||||
fromToken: CryptoCurrency,
|
||||
txFee: TxFeeState,
|
||||
) {
|
||||
val existentialDeposit = currencyChecksRepository.getExistentialDeposit(userWalletId, fromToken.network)
|
||||
if (existentialDeposit != null) {
|
||||
|
|
@ -411,8 +412,14 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
fromToken.network.backendId,
|
||||
fromToken.network.derivationPath.value,
|
||||
) ?: ProxyAmount.empty()
|
||||
val fee = when (txFee) {
|
||||
TxFeeState.Empty -> BigDecimal.ZERO
|
||||
is TxFeeState.MultipleFeeState -> txFee.priorityFee.feeValue
|
||||
is TxFeeState.SingleFeeState -> txFee.fee.feeValue
|
||||
}
|
||||
val minAvailableAmount = nativeBalance.value - existentialDeposit - fee
|
||||
if (nativeBalance.value.minus(amount.value) < existentialDeposit) {
|
||||
warnings.add(Warning.ExistentialDepositWarning(existentialDeposit))
|
||||
warnings.add(Warning.ExistentialDepositWarning(existentialDeposit, minAvailableAmount))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ data class UiActions(
|
|||
val onBackClicked: () -> Unit,
|
||||
val onMaxAmountSelected: () -> Unit,
|
||||
val onReduceAmount: (SwapAmount) -> Unit,
|
||||
val onLeaveExistentialDeposit: (SwapAmount) -> Unit,
|
||||
val openPermissionBottomSheet: () -> Unit,
|
||||
val onChangeApproveType: (ApproveType) -> Unit,
|
||||
// region new actions
|
||||
|
|
|
|||
|
|
@ -358,21 +358,7 @@ internal class StateBuilder(
|
|||
quoteModel.warnings.forEach {
|
||||
when (it) {
|
||||
is Warning.ExistentialDepositWarning -> {
|
||||
warnings.add(
|
||||
SwapWarning.GeneralInformational(
|
||||
NotificationConfig(
|
||||
title = resourceReference(R.string.warning_existential_deposit_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.warning_existential_deposit_message,
|
||||
wrappedList(
|
||||
quoteModel.fromTokenInfo.cryptoCurrencyStatus.currency.name,
|
||||
it.existentialDeposit.toPlainString(),
|
||||
),
|
||||
),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
),
|
||||
),
|
||||
)
|
||||
warnings.add(createLeaveExistentialDepositWarning(quoteModel, it))
|
||||
}
|
||||
is Warning.MinAmountWarning -> {
|
||||
warnings.add(
|
||||
|
|
@ -443,6 +429,41 @@ internal class StateBuilder(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createLeaveExistentialDepositWarning(
|
||||
quoteModel: SwapState.QuotesLoadedState,
|
||||
domainWarning: Warning.ExistentialDepositWarning,
|
||||
): SwapWarning {
|
||||
val fromCurrency = quoteModel.fromTokenInfo.cryptoCurrencyStatus.currency
|
||||
val deposit = BigDecimalFormatter.formatCryptoAmountUncapped(
|
||||
cryptoAmount = domainWarning.existentialDeposit,
|
||||
cryptoCurrency = fromCurrency,
|
||||
)
|
||||
return SwapWarning.GeneralError(
|
||||
NotificationConfig(
|
||||
title = resourceReference(R.string.send_notification_existential_deposit_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.send_notification_existential_deposit_text,
|
||||
wrappedList(deposit),
|
||||
),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
buttonsState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(
|
||||
R.string.send_notification_leave_button,
|
||||
wrappedList(deposit),
|
||||
),
|
||||
onClick = {
|
||||
actions.onLeaveExistentialDeposit(
|
||||
SwapAmount(
|
||||
domainWarning.minAvailableAmount,
|
||||
fromCurrency.decimals,
|
||||
),
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun maybeAddPermissionNeededWarning(
|
||||
quoteModel: SwapState.QuotesLoadedState,
|
||||
warnings: MutableList<SwapWarning>,
|
||||
|
|
@ -468,19 +489,25 @@ internal class StateBuilder(
|
|||
when (quoteModel.preparedSwapConfigState.includeFeeInAmount) {
|
||||
is IncludeFeeInAmount.Included -> {
|
||||
val fee = selectFeeByType(selectedFeeType, quoteModel.txFee) ?: return
|
||||
warnings.add(
|
||||
SwapWarning.GeneralWarning(
|
||||
createNetworkFeeCoverageNotificationConfig(
|
||||
fee.feeCryptoFormatted,
|
||||
fee.feeFiatFormatted,
|
||||
if (needShowNetworkFeeCoverageWarningShow(quoteModel)) {
|
||||
warnings.add(
|
||||
SwapWarning.GeneralWarning(
|
||||
createNetworkFeeCoverageNotificationConfig(
|
||||
fee.feeCryptoFormatted,
|
||||
fee.feeFiatFormatted,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun needShowNetworkFeeCoverageWarningShow(quoteModel: SwapState.QuotesLoadedState): Boolean {
|
||||
return quoteModel.warnings.none { it is Warning.ExistentialDepositWarning }
|
||||
}
|
||||
|
||||
private fun selectFeeByType(feeType: FeeType, txFeeState: TxFeeState): TxFee? {
|
||||
return when (txFeeState) {
|
||||
TxFeeState.Empty -> null
|
||||
|
|
@ -544,8 +571,10 @@ internal class StateBuilder(
|
|||
|
||||
// check has MinAmountWarning warning
|
||||
val hasCriticalWarning = quoteModel.warnings.any {
|
||||
it is Warning.MinAmountWarning || it is Warning.Cardano.InsufficientBalanceToTransferCoin ||
|
||||
it is Warning.Cardano.InsufficientBalanceToTransferToken
|
||||
it is Warning.MinAmountWarning ||
|
||||
it is Warning.Cardano.InsufficientBalanceToTransferCoin ||
|
||||
it is Warning.Cardano.InsufficientBalanceToTransferToken ||
|
||||
it is Warning.ExistentialDepositWarning
|
||||
}
|
||||
|
||||
if (hasCriticalWarning) return false
|
||||
|
|
|
|||
|
|
@ -823,6 +823,10 @@ internal class SwapViewModel @Inject constructor(
|
|||
onAmountChanged(newAmount.formatToUIRepresentation())
|
||||
}
|
||||
|
||||
private fun onLeaveExistentialDepositClicked(newAmount: SwapAmount) {
|
||||
onAmountChanged(newAmount.formatToUIRepresentation())
|
||||
}
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private fun onAmountSelected(selected: Boolean) {
|
||||
if (selected) {
|
||||
|
|
@ -887,6 +891,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
},
|
||||
onMaxAmountSelected = ::onMaxAmountClicked,
|
||||
onReduceAmount = ::onReduceAmountClicked,
|
||||
onLeaveExistentialDeposit = ::onLeaveExistentialDepositClicked,
|
||||
openPermissionBottomSheet = {
|
||||
singleTaskScheduler.cancelTask()
|
||||
analyticsEventHandler.send(SwapEvents.ButtonGivePermissionClicked)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue