Updated on 2026-08-14
This commit is contained in:
parent
5d69093f1d
commit
7ef0543a78
9 changed files with 91 additions and 32 deletions
|
|
@ -479,8 +479,10 @@
|
|||
<string name="send_notification_exceed_balance_title">Недостаточно средств</string>
|
||||
<string name="send_notification_exceed_fee_text">Размер комиссии превышает баланс сети. Для продолжения необходимо пополнить баланс сети.</string>
|
||||
<string name="send_notification_exceed_fee_title">Комиссия превышает баланс</string>
|
||||
<string name="send_notification_high_fee_text">Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить 0.01.</string>
|
||||
<string name="send_notification_high_fee_title">Увеличение комиссии</string>
|
||||
<string name="send_notification_high_fee_text">Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить 0.01.</string>
|
||||
<string name="send_notification_fee_too_high_accept">Оставить %s XTZ</string>
|
||||
<string name="send_notification_fee_too_high_ignore">Отправить все</string>
|
||||
<string name="send_notification_fee_too_high_title">Установлена высокая комиссия</string>
|
||||
<string name="send_notification_fee_too_high_text">Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.</string>
|
||||
<string name="send_notification_invalid_amount_text">Включенная комиссия превышает сумму перевода, что приводит к отрицательному значению</string>
|
||||
|
|
|
|||
|
|
@ -484,8 +484,10 @@
|
|||
<string name="send_notification_exceed_balance_title">Total exceeds balance</string>
|
||||
<string name="send_notification_exceed_fee_text">The commission fee exceeds the network balance. To continue, it is necessary to replenish the network balance.</string>
|
||||
<string name="send_notification_exceed_fee_title">Fee exceeds balance</string>
|
||||
<string name="send_notification_high_fee_text">The fee for transferring the entire balance is higher. To reduce the commission, you can leave 0.01.</string>
|
||||
<string name="send_notification_high_fee_title">Fee is increased</string>
|
||||
<string name="send_notification_high_fee_text">The fee for transferring the entire balance is higher. To reduce the commission, you can leave 0.01.</string>
|
||||
<string name="send_notification_fee_too_high_accept">Reduce by %s XTZ</string>
|
||||
<string name="send_notification_fee_too_high_ignore">No, send all</string>
|
||||
<string name="send_notification_fee_too_high_title">Custom fee is high</string>
|
||||
<string name="send_notification_fee_too_high_text">The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.</string>
|
||||
<string name="send_notification_invalid_amount_text">The included commission exceeds the transfer amount, leading to a negative value</string>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,13 @@ package com.tangem.domain.transaction.usecase
|
|||
|
||||
import arrow.core.Either
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.transaction.TransactionRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CreateTransactionUseCase(
|
||||
private val transactionRepository: TransactionRepository,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
/**
|
||||
|
|
@ -26,18 +22,16 @@ class CreateTransactionUseCase(
|
|||
destination: String,
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
): Either<Throwable, TransactionData> = withContext(dispatchers.io) {
|
||||
Either.catch {
|
||||
requireNotNull(
|
||||
transactionRepository.createTransaction(
|
||||
amount = amount,
|
||||
fee = fee,
|
||||
memo = memo,
|
||||
destination = destination,
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
),
|
||||
) { "Failed to create transaction" }
|
||||
}
|
||||
) = Either.catch {
|
||||
requireNotNull(
|
||||
transactionRepository.createTransaction(
|
||||
amount = amount,
|
||||
fee = fee,
|
||||
memo = memo,
|
||||
destination = destination,
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
),
|
||||
) { "Failed to create transaction" }
|
||||
}
|
||||
}
|
||||
|
|
@ -57,16 +57,28 @@ internal sealed class SendNotification(val config: NotificationConfig) {
|
|||
sealed class Warning(
|
||||
title: TextReference,
|
||||
subtitle: TextReference,
|
||||
buttonsState: NotificationConfig.ButtonsState? = null,
|
||||
) : SendNotification(
|
||||
config = NotificationConfig(
|
||||
title = title,
|
||||
subtitle = subtitle,
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
buttonsState = buttonsState,
|
||||
),
|
||||
) {
|
||||
data class HighFeeError(val amount: String) : Warning(
|
||||
data class HighFeeError(
|
||||
val amount: String,
|
||||
val onConfirmClick: () -> Unit,
|
||||
val onDismissClick: () -> Unit,
|
||||
) : Warning(
|
||||
title = resourceReference(R.string.send_notification_high_fee_title),
|
||||
subtitle = resourceReference(R.string.send_notification_high_fee_text, wrappedList(amount)),
|
||||
buttonsState = NotificationConfig.ButtonsState.PairButtonsConfig(
|
||||
primaryText = resourceReference(R.string.send_notification_fee_too_high_accept, wrappedList(amount)),
|
||||
onPrimaryClick = onConfirmClick,
|
||||
secondaryText = resourceReference(R.string.send_notification_fee_too_high_ignore),
|
||||
onSecondaryClick = onDismissClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class ExistentialDeposit(val deposit: String) : Warning(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
import com.tangem.utils.Provider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -21,6 +22,7 @@ internal class SendNotificationFactory(
|
|||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val userWalletProvider: Provider<UserWallet>,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val clickIntents: SendClickIntents,
|
||||
) {
|
||||
|
||||
fun create(): Flow<ImmutableList<SendNotification>> = currentStateProvider().currentState
|
||||
|
|
@ -30,19 +32,33 @@ internal class SendNotificationFactory(
|
|||
val feeState = state.feeState ?: return@map persistentListOf()
|
||||
val recipientState = state.recipientState ?: return@map persistentListOf()
|
||||
val feeAmount = feeState.fee?.amount?.value ?: BigDecimal.ZERO
|
||||
val amountValue = state.amountState?.amountTextField?.value?.toBigDecimalOrNull() ?: BigDecimal.ZERO
|
||||
val sendAmount = if (feeState.isSubtract) feeState.receivedAmountValue else amountValue
|
||||
buildList {
|
||||
// errors
|
||||
addExceedBalanceNotification(feeAmount, feeState.receivedAmountValue)
|
||||
addInvalidAmountNotification(feeState.isSubtract, feeState.receivedAmountValue)
|
||||
addMinimumAmountErrorNotification(feeAmount, feeState.receivedAmountValue)
|
||||
addExceedBalanceNotification(feeAmount, sendAmount)
|
||||
addInvalidAmountNotification(feeState.isSubtract, sendAmount)
|
||||
addMinimumAmountErrorNotification(feeAmount, sendAmount)
|
||||
addReserveAmountErrorNotification(recipientState.addressTextField.value)
|
||||
addTransactionLimitErrorNotification(feeAmount, feeState.receivedAmountValue)
|
||||
addTransactionLimitErrorNotification(feeAmount, sendAmount)
|
||||
// warnings
|
||||
addExistentialWarningNotification(feeAmount, feeState.receivedAmountValue)
|
||||
addHighFeeWarningNotification()
|
||||
addExistentialWarningNotification(feeAmount, sendAmount)
|
||||
addHighFeeWarningNotification(amountValue, state.sendState.ignoreAmountReduce)
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
fun dismissHighFeeWarningState(): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val sendState = state.sendState
|
||||
val updatedNotifications = sendState.notifications.filterNot { it is SendNotification.Warning.HighFeeError }
|
||||
return state.copy(
|
||||
sendState = sendState.copy(
|
||||
ignoreAmountReduce = true,
|
||||
notifications = updatedNotifications.toImmutableList(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addExceedBalanceNotification(
|
||||
feeAmount: BigDecimal,
|
||||
receivedAmount: BigDecimal,
|
||||
|
|
@ -173,16 +189,30 @@ internal class SendNotificationFactory(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addHighFeeWarningNotification() {
|
||||
// TODO Move Blockchain check elsewhere
|
||||
if (cryptoCurrencyStatusProvider().currency.network.id.value == Blockchain.Tezos.id) {
|
||||
add(SendNotification.Warning.HighFeeError(TEZOS_FEE_THRESHOLD))
|
||||
private fun MutableList<SendNotification>.addHighFeeWarningNotification(
|
||||
sendAmount: BigDecimal,
|
||||
ignoreAmountReduce: Boolean,
|
||||
) {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
val isTezos = cryptoCurrencyStatus.currency.network.id.value == Blockchain.Tezos.id
|
||||
if (!ignoreAmountReduce && sendAmount == balance && isTezos) {
|
||||
add(
|
||||
SendNotification.Warning.HighFeeError(
|
||||
amount = TEZOS_FEE_THRESHOLD.toPlainString(),
|
||||
onConfirmClick = {
|
||||
val reduceTo = sendAmount.minus(TEZOS_FEE_THRESHOLD).toPlainString()
|
||||
clickIntents.onAmountReduceClick(reduceTo)
|
||||
},
|
||||
onDismissClick = clickIntents::onAmountReduceIgnoreClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CARDANO_MINIMUM = "1"
|
||||
private const val DOGECOIN_MINIMUM = "0.01"
|
||||
private const val TEZOS_FEE_THRESHOLD = "0.01"
|
||||
private val TEZOS_FEE_THRESHOLD = BigDecimal("0.01")
|
||||
}
|
||||
}
|
||||
|
|
@ -88,6 +88,7 @@ internal sealed class SendStates {
|
|||
val isSuccess: Boolean = false,
|
||||
val transactionDate: Long = 0L,
|
||||
val txUrl: String = "",
|
||||
val ignoreAmountReduce: Boolean = false,
|
||||
val notifications: ImmutableList<SendNotification> = persistentListOf(),
|
||||
) : SendStates()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,10 @@ internal fun LazyListScope.notifications(configs: ImmutableList<SendNotification
|
|||
Notification(
|
||||
config = it.config,
|
||||
modifier = modifier.animateItemPlacement(),
|
||||
containerColor = TangemTheme.colors.button.disabled,
|
||||
containerColor = when (it) {
|
||||
is SendNotification.Warning.HighFeeError -> TangemTheme.colors.background.action
|
||||
else -> TangemTheme.colors.button.disabled
|
||||
},
|
||||
iconTint = when (it) {
|
||||
is SendNotification.Error -> TangemTheme.colors.icon.warning
|
||||
is SendNotification.Warning -> null
|
||||
|
|
|
|||
|
|
@ -53,5 +53,9 @@ interface SendClickIntents {
|
|||
fun showFee()
|
||||
|
||||
fun onExploreClick(txUrl: String)
|
||||
|
||||
fun onAmountReduceClick(reducedAmount: String)
|
||||
|
||||
fun onAmountReduceIgnoreClick()
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -109,6 +109,7 @@ internal class SendViewModel @Inject constructor(
|
|||
currentStateProvider = Provider { uiState },
|
||||
userWalletProvider = Provider { userWallet },
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
clickIntents = this,
|
||||
)
|
||||
|
||||
// todo convert to StateFlow
|
||||
|
|
@ -457,6 +458,16 @@ internal class SendViewModel @Inject constructor(
|
|||
|
||||
override fun onExploreClick(txUrl: String) = innerRouter.openUrl(txUrl)
|
||||
|
||||
override fun onAmountReduceClick(reducedAmount: String) {
|
||||
uiState = stateFactory.getOnAmountValueChange(reducedAmount)
|
||||
uiState = sendNotificationFactory.dismissHighFeeWarningState()
|
||||
getFee()
|
||||
}
|
||||
|
||||
override fun onAmountReduceIgnoreClick() {
|
||||
uiState = sendNotificationFactory.dismissHighFeeWarningState()
|
||||
}
|
||||
|
||||
private fun verifyAndSendTransaction() {
|
||||
val recipient = uiState.recipientState?.addressTextField?.value ?: return
|
||||
val feeState = uiState.feeState ?: return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue