Updated on 2026-08-14

This commit is contained in:
Tangem 2024-01-31 11:11:59 +01:00
parent 07bf6c376c
commit 11f62a51bc
8 changed files with 50 additions and 9 deletions

View file

@ -23,6 +23,9 @@ data class ExpressErrorValue(
@Json(name = "minAmount")
val minAmount: String?,
@Json(name = "maxAmount")
val maxAmount: String?,
@Json(name = "decimals")
val decimals: Int?,

View file

@ -232,6 +232,7 @@
<string name="express_provider">Провайдер</string>
<string name="express_provider_best_rate">Лучший курс</string>
<string name="express_provider_min_amount">Доступно с %s</string>
<string name="express_provider_max_amount">Доступно до %s</string>
<string name="express_provider_not_available">Недоступно для этой пары</string>
<string name="express_provider_permission_needed">Требуется разрешение</string>
<string name="express_terms_of_use">Условиями использования</string>
@ -693,8 +694,9 @@
<string name="warning_express_not_enough_fee_for_token_tx_description">Чтобы совершить транзакцию, вам необходимо внести немного %1$s %2$s</string>
<string name="warning_express_not_enough_fee_for_token_tx_title">Невозможно покрыть комиссию %s</string>
<string name="warning_express_refresh_required_title">Cервис временно недоступен</string>
<string name="warning_express_too_minimal_amount_description">Пожалуйста, измените сумму для обмена</string>
<string name="warning_express_wrong_amount_description">Пожалуйста, измените сумму для обмена</string>
<string name="warning_express_too_minimal_amount_title">Сумма для обмена должна быть не менее %s</string>
<string name="warning_express_too_maximum_amount_title">Сумма для обмена должна быть не более %s</string>
<string name="warning_failed_to_verify_card_message">Возможно, данная карта - образец или подделка</string>
<string name="warning_failed_to_verify_card_title">Ошибка проверки подлинности</string>
<string name="warning_low_signatures_message">На этой карте осталось всего %s подписей. Вам следует вывести все ваши средства.</string>

View file

@ -235,6 +235,7 @@
<string name="express_provider">Provider</string>
<string name="express_provider_best_rate">Best rate</string>
<string name="express_provider_min_amount">Available from %s</string>
<string name="express_provider_max_amount">Available up to %s</string>
<string name="express_provider_not_available">Unavailable for this pair</string>
<string name="express_provider_permission_needed">Permission Required</string>
<string name="express_terms_of_use">Terms of Use</string>
@ -709,8 +710,9 @@
<string name="warning_express_not_enough_fee_for_token_tx_description">To make a transaction you need to deposit some %1$s %2$s</string>
<string name="warning_express_not_enough_fee_for_token_tx_title">Unable to cover %s fee</string>
<string name="warning_express_refresh_required_title">Service temporarily unavailable</string>
<string name="warning_express_too_minimal_amount_description">Please change the amount to swap</string>
<string name="warning_express_wrong_amount_description">Please change the amount to swap</string>
<string name="warning_express_too_minimal_amount_title">The amount to swap must be at least %s</string>
<string name="warning_express_too_maximum_amount_title">The amount of tokens to be swapped must not exceed %s</string>
<string name="warning_failed_to_verify_card_message">This card might be a production sample or counterfeit</string>
<string name="warning_failed_to_verify_card_title">Authenticity check failed</string>
<string name="warning_low_signatures_message">Only %s signatures are left on this card. You must withdraw all of your funds.</string>

View file

@ -11,7 +11,7 @@ internal class ErrorsDataConverter(
private val jsonAdapter: JsonAdapter<ExpressErrorResponse>,
) : Converter<String, DataError> {
@Suppress("MagicNumber")
@Suppress("MagicNumber", "CyclomaticComplexMethod")
override fun convert(value: String): DataError {
try {
val error = jsonAdapter.fromJson(value)?.error ?: return DataError.UnknownError
@ -23,6 +23,7 @@ internal class ErrorsDataConverter(
2230 -> DataError.ExchangeProviderNotAvailableError(code = error.code)
2240 -> DataError.ExchangeNotPossibleError(code = error.code)
2250 -> tryParseExchangeTooSmallAmountError(error = error)
2251 -> tryParseExchangeTooBigAmountError(error = error)
2260 -> tryParseExchangeNotEnoughAllowanceError(error = error)
2270 -> DataError.ExchangeNotEnoughBalanceError(code = error.code)
2280 -> DataError.ExchangeInvalidAddressError(code = error.code)
@ -44,6 +45,16 @@ internal class ErrorsDataConverter(
)
}
private fun tryParseExchangeTooBigAmountError(error: ExpressError): DataError {
val minAmount = error.value?.maxAmount ?: return DataError.UnknownErrorWithCode(error.code)
val decimals = error.value?.decimals ?: return DataError.UnknownErrorWithCode(error.code)
return DataError.ExchangeTooBigAmountError(
code = error.code,
amount = createFromAmountWithOffset(minAmount, decimals),
)
}
private fun tryParseExchangeNotEnoughAllowanceError(error: ExpressError): DataError {
val currentAllowance = error.value?.currentAllowance ?: return DataError.UnknownErrorWithCode(error.code)

View file

@ -18,6 +18,8 @@ sealed class DataError {
data class ExchangeTooSmallAmountError(override val code: Int, val amount: SwapAmount) : DataError()
data class ExchangeTooBigAmountError(override val code: Int, val amount: SwapAmount) : DataError()
data class ExchangeNotEnoughAllowanceError(override val code: Int, val currentAllowance: BigDecimal) : DataError()
data class ExchangeNotEnoughBalanceError(override val code: Int) : DataError()

View file

@ -146,7 +146,7 @@ private fun ProviderContentState(
}
Row(
modifier = Modifier.padding(
top = TangemTheme.dimens.spacing8,
top = TangemTheme.dimens.spacing6,
end = TangemTheme.dimens.spacing56,
),
) {
@ -238,7 +238,7 @@ private fun ProviderUnavailableState(
text = it.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
modifier = Modifier.padding(top = TangemTheme.dimens.spacing6),
)
}
}

View file

@ -534,6 +534,16 @@ internal class StateBuilder(
onProviderClick = onProviderClick,
)
}
is DataError.ExchangeTooBigAmountError -> {
swapProvider.convertToAvailableFromProviderState(
alertText = resourceReference(
R.string.express_provider_max_amount,
wrappedList(dataError.amount.getFormattedCryptoAmount(fromToken)),
),
selectionType = selectionType,
onProviderClick = onProviderClick,
)
}
else -> {
ProviderState.Empty()
}
@ -548,7 +558,17 @@ internal class StateBuilder(
id = R.string.warning_express_too_minimal_amount_title,
formatArgs = wrappedList(dataError.amount.getFormattedCryptoAmount(fromToken)),
),
subtitle = resourceReference(R.string.warning_express_too_minimal_amount_description),
subtitle = resourceReference(R.string.warning_express_wrong_amount_description),
iconResId = R.drawable.ic_alert_circle_24,
),
)
is DataError.ExchangeTooBigAmountError -> SwapWarning.GeneralError(
notificationConfig = NotificationConfig(
title = resourceReference(
id = R.string.warning_express_too_maximum_amount_title,
formatArgs = wrappedList(dataError.amount.getFormattedCryptoAmount(fromToken)),
),
subtitle = resourceReference(R.string.warning_express_wrong_amount_description),
iconResId = R.drawable.ic_alert_circle_24,
),
)

View file

@ -99,8 +99,9 @@ internal class SwapViewModel @Inject constructor(
private val lastAmount = mutableStateOf(INITIAL_AMOUNT)
private var swapRouter: SwapRouter by Delegates.notNull()
private val isExchangeTooSmallAmountError: (SwapState) -> Boolean = {
it is SwapState.SwapError && it.error is DataError.ExchangeTooSmallAmountError
private val isUserResolvableError: (SwapState) -> Boolean = {
it is SwapState.SwapError &&
(it.error is DataError.ExchangeTooSmallAmountError || it.error is DataError.ExchangeTooBigAmountError)
}
val currentScreen: SwapNavScreen
@ -1001,7 +1002,7 @@ internal class SwapViewModel @Inject constructor(
private fun Map<SwapProvider, SwapState>.consideredProvidersStates(): Map<SwapProvider, SwapState> {
return this.filter {
it.value is SwapState.QuotesLoadedState || isExchangeTooSmallAmountError(it.value)
it.value is SwapState.QuotesLoadedState || isUserResolvableError(it.value)
}
}