Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-11 16:09:32 +05:00
parent 505400888d
commit 230aff6ed6
5 changed files with 34 additions and 29 deletions

View file

@ -8,7 +8,7 @@ sealed class SendTransactionError {
data class DataError(val message: String?) : SendTransactionError() data class DataError(val message: String?) : SendTransactionError()
data class NetworkError(val message: String?) : SendTransactionError() data class NetworkError(val message: String?, val code: String?) : SendTransactionError()
data class BlockchainSdkError(val code: Int, val message: String?) : SendTransactionError() data class BlockchainSdkError(val code: Int, val message: String?) : SendTransactionError()

View file

@ -67,7 +67,12 @@ class SendTransactionUseCase(
} }
private fun handleError(result: SimpleResult.Failure): SendTransactionError { private fun handleError(result: SimpleResult.Failure): SendTransactionError {
if (ResultChecker.isNetworkError(result)) return SendTransactionError.NetworkError(result.error.message) if (ResultChecker.isNetworkError(result)) {
return SendTransactionError.NetworkError(
code = result.error.message,
message = result.error.customMessage,
)
}
val error = result.error as? BlockchainSdkError ?: return SendTransactionError.UnknownError() val error = result.error as? BlockchainSdkError ?: return SendTransactionError.UnknownError()
return when (error) { return when (error) {
is BlockchainSdkError.WrappedTangemError -> { is BlockchainSdkError.WrappedTangemError -> {

View file

@ -29,8 +29,8 @@ internal class SendTransactionAlertConverter(
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) }, onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) },
) )
is SendTransactionError.NetworkError -> SendAlertState.TransactionError( is SendTransactionError.NetworkError -> SendAlertState.TransactionError(
code = "", code = value.code.orEmpty(),
cause = value.message, cause = value.message.orEmpty(),
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) }, onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) },
) )
is SendTransactionError.UnknownError -> SendAlertState.TransactionError( is SendTransactionError.UnknownError -> SendAlertState.TransactionError(

View file

@ -20,6 +20,7 @@ import com.tangem.features.send.impl.presentation.state.*
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fee.FeeType import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.lib.crypto.BlockchainUtils.isDogecoin
import com.tangem.utils.Provider import com.tangem.utils.Provider
import com.tangem.utils.isNullOrZero import com.tangem.utils.isNullOrZero
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -52,18 +53,17 @@ internal class SendNotificationFactory(
val feeState = state.feeState ?: return@map persistentListOf() val feeState = state.feeState ?: return@map persistentListOf()
val feeAmount = feeState.fee?.amount?.value ?: BigDecimal.ZERO val feeAmount = feeState.fee?.amount?.value ?: BigDecimal.ZERO
val amountValue = state.amountState?.amountTextField?.cryptoAmount?.value ?: BigDecimal.ZERO val amountValue = state.amountState?.amountTextField?.cryptoAmount?.value ?: BigDecimal.ZERO
val sendAmount = if (sendState.isSubtract) amountValue.minus(feeAmount) else amountValue
buildList { buildList {
// errors // errors
addExceedBalanceNotification(feeAmount, sendAmount) addExceedBalanceNotification(feeAmount, amountValue)
addExceedsBalanceNotification(feeState.fee) addExceedsBalanceNotification(feeState.fee)
addInvalidAmountNotification(sendState.isSubtract, sendAmount) addInvalidAmountNotification(sendState.isSubtract, amountValue)
addMinimumAmountErrorNotification(feeAmount, sendAmount) addMinimumAmountErrorNotification(feeAmount, amountValue)
addDustWarningNotification(feeAmount, sendAmount) addDustWarningNotification(feeAmount, amountValue)
addTransactionLimitErrorNotification(feeAmount, sendAmount) addTransactionLimitErrorNotification(feeAmount, amountValue)
// warnings // warnings
addExistentialWarningNotification(feeAmount, sendAmount) addExistentialWarningNotification(feeAmount, amountValue)
addHighFeeWarningNotification(sendAmount, sendState.ignoreAmountReduce) addHighFeeWarningNotification(feeAmount, amountValue, sendState.ignoreAmountReduce)
addTooLowNotification(feeState) addTooLowNotification(feeState)
}.toImmutableList() }.toImmutableList()
} }
@ -121,20 +121,11 @@ internal class SendNotificationFactory(
val totalAmount = feeAmount + receivedAmount val totalAmount = feeAmount + receivedAmount
val balance = coinCryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO val balance = coinCryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
// TODO Move Blockchain check elsewhere if (isDogecoin(coinCryptoCurrencyStatus.currency.network.id.value)) {
when (coinCryptoCurrencyStatus.currency.network.id.value) { val minimum = BigDecimal(DOGECOIN_MINIMUM)
Blockchain.Cardano.id -> { if (receivedAmount < minimum || balance - totalAmount < minimum) {
if (receivedAmount > BigDecimal.ONE || balance - totalAmount < BigDecimal.ONE) { add(SendNotification.Error.MinimumAmountError(DOGECOIN_MINIMUM))
add(SendNotification.Error.MinimumAmountError(CARDANO_MINIMUM))
}
} }
Blockchain.Dogecoin.id -> {
val minimum = BigDecimal(DOGECOIN_MINIMUM)
if (receivedAmount > minimum || balance - totalAmount < minimum) {
add(SendNotification.Error.MinimumAmountError(DOGECOIN_MINIMUM))
}
}
else -> Unit
} }
} }
@ -199,7 +190,9 @@ internal class SendNotificationFactory(
receivedAmount: BigDecimal, receivedAmount: BigDecimal,
) { ) {
val userWalletId = userWalletProvider().walletId val userWalletId = userWalletProvider().walletId
val cryptoCurrency = cryptoCurrencyStatusProvider().currency val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val cryptoCurrency = cryptoCurrencyStatus.currency
val balance = cryptoCurrencyStatus.value.amount ?: return
val spendingAmount = if (cryptoCurrency is CryptoCurrency.Token) { val spendingAmount = if (cryptoCurrency is CryptoCurrency.Token) {
feeAmount feeAmount
} else { } else {
@ -209,7 +202,8 @@ internal class SendNotificationFactory(
userWalletId, userWalletId,
cryptoCurrency.network, cryptoCurrency.network,
) )
if (currencyDeposit != null && currencyDeposit > spendingAmount) { val diff = balance.minus(spendingAmount)
if (currencyDeposit != null && currencyDeposit > diff) {
add( add(
SendNotification.Error.ExistentialDeposit( SendNotification.Error.ExistentialDeposit(
BigDecimalFormatter.formatCryptoAmount( BigDecimalFormatter.formatCryptoAmount(
@ -222,13 +216,15 @@ internal class SendNotificationFactory(
} }
private fun MutableList<SendNotification>.addHighFeeWarningNotification( private fun MutableList<SendNotification>.addHighFeeWarningNotification(
feeAmount: BigDecimal,
sendAmount: BigDecimal, sendAmount: BigDecimal,
ignoreAmountReduce: Boolean, ignoreAmountReduce: Boolean,
) { ) {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
val isTezos = cryptoCurrencyStatus.currency.network.id.value == Blockchain.Tezos.id val isTezos = cryptoCurrencyStatus.currency.network.id.value == Blockchain.Tezos.id
if (!ignoreAmountReduce && sendAmount == balance && isTezos) { val isTotalBalance = feeAmount.plus(sendAmount) >= balance
if (!ignoreAmountReduce && isTotalBalance && isTezos) {
add( add(
SendNotification.Warning.HighFeeError( SendNotification.Warning.HighFeeError(
amount = TEZOS_FEE_THRESHOLD.toPlainString(), amount = TEZOS_FEE_THRESHOLD.toPlainString(),
@ -361,7 +357,6 @@ internal class SendNotificationFactory(
} }
companion object { companion object {
private const val CARDANO_MINIMUM = "1"
private const val DOGECOIN_MINIMUM = "0.01" private const val DOGECOIN_MINIMUM = "0.01"
private val TEZOS_FEE_THRESHOLD = BigDecimal("0.01") private val TEZOS_FEE_THRESHOLD = BigDecimal("0.01")
} }

View file

@ -32,4 +32,9 @@ object BlockchainUtils {
val blockchain = Blockchain.fromId(networkId) val blockchain = Blockchain.fromId(networkId)
return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
} }
fun isDogecoin(networkId: String): Boolean {
val blockchain = Blockchain.fromId(networkId)
return blockchain == Blockchain.Dogecoin
}
} }