diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 298dffbcda..f12dc6ee9c 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -470,16 +470,17 @@
Комиссия не превысит
Комиссия, которая будет взята за вашу транзакцию. Вы можете выставить своё собственное значение.
Допустим ввод только цифр
- Сумма отправки будет уменьшена на %1$s для покрытия выбранного уровня комиссии. Получателю будет отправлено %2$s.
+ Сумма отправки будет уменьшена на %1$s (%2$s) для покрытия выбранного уровня комиссии
Покрытие сетевой комиссии
Недостаточно средств для перевода, так как сумма комиссии и сумма перевода в совокупности больше имеющегося баланса
Недостаточно средств
- Аккаунт будет удален из блокчейна, если баланс упадет ниже экзистенциального депозита. Пожалуйста, убедитесь, что остаток после отправки будет не менее %s.
+ Оставить %s
+ Аккаунт будет удален из блокчейна, если баланс упадет ниже экзистенциального депозита. Пожалуйста, оставьте %s на балансе.
Экзистенциальный депозит
Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.
Установлена высокая комиссия
- Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить %s.
- Комиссия увеличилась
+ Ввиду особенности сети Tezos комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить %s.
+ Комиссия повышена
Включенная комиссия превышает сумму перевода, что приводит к отрицательному значению
Недопустимая сумма
Минимальная сумма отправки - %1$s. Пожалуйста, убедитесь, что остаток после отправки также не будет меньше %2$s.
@@ -500,7 +501,8 @@
Отправить
Мемо/ Код назначения - это код, разделяющий транзакции к общему получателю в сети криптовалют. Внимание: отсутствие мемо может привести к потере средств.
Мои кошельки
- Это способ измерения комиссии за отправку биткоин-транзакции. Он указывает на количество самой маленькой единицы биткоина (сатоши) за каждый байт данных в транзакции. Чем выше это число, тем быстрее будет обработана транзакция сетью.
+ Способ измерения комиссии за биткоин-транзакцию. Он указывает на количество самой маленькой единицы биткоина (сатоши) за каждый виртуальный байт в транзакции. Чем выше число, тем быстрее будет обработана транзакция майнерами.
+ Сатоши / вбайт
Отправка
Нажмите на любое поле, чтобы изменить его
Отправка %s
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 257e2e4adc..1b3c413136 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -467,16 +467,17 @@
Max fee
The fee that will be charged for your transaction. You can set your own value.
Numbers only for Destination Tag
- Sending amount will be reduced by %1$s to cover the selected commission level. The recipient will get %2$s.
+ Amount sent will be reduced by %1$s (%2$s) to cover the selected fee level
Network fee coverage
Insufficient funds for the transfer, as the total of the fee and transfer amount exceeds the existing balance
Total exceeds balance
- The account will be wiped from the blockchain if a balance goes below the existential deposit. Please ensure that the remaining balance after sending will not be less than %s.
+ Leave %s
+ The account will be wiped from the blockchain if a balance goes below the existential deposit. Please leave %s on your balance.
Existential deposit
The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.
Custom fee is high
- The fee for transferring the entire balance is higher. To reduce the commission, you can leave %s.
- Fee is increased
+ Due to the peculiarities of the Tezos network, the fee for transferring the entire balance is higher. To reduce the commission, you can leave %s.
+ The fee is higher
The included commission exceeds the transfer amount, leading to a negative value
Invalid amount
The minimum sending amount is %1$s. Please ensure that the remaining balance after sending will not be less than %2$s.
@@ -499,8 +500,8 @@
Send to
A Memo/Destination Tag is a unique ID for differentiating transactions sent to the same recipient on the same network. Caution: Omitting a memo may lead to misplaced funds
My wallets
- The fee for a Bitcoin transaction is measured by the number of the smallest Bitcoin unit (Satoshi) per byte of data. The higher this number, the faster the transaction will be processed.
- Satoshi per vbyte
+ A way of measuring Bitcoin transaction fees. It indicates the number of the smallest Bitcoin unit (Satoshi) for each virtual byte in a transaction. The higher the number, the faster the transaction will be processed by miners.
+ Satoshi / vByte
Sending...
Tap any field to change it
Send %s
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
index 3334f3faaa..a22b3ee620 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
@@ -94,9 +94,13 @@ internal sealed class SendNotification(val config: NotificationConfig) {
},
)
- data class ExistentialDeposit(val deposit: String) : Error(
+ data class ExistentialDeposit(val deposit: String, val onConfirmClick: () -> Unit) : Error(
title = resourceReference(R.string.send_notification_existential_deposit_title),
subtitle = resourceReference(R.string.send_notification_existential_deposit_text, wrappedList(deposit)),
+ buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
+ text = resourceReference(R.string.send_notification_existential_deposit_button, wrappedList(deposit)),
+ onClick = onConfirmClick,
+ ),
)
}
@@ -149,9 +153,12 @@ internal sealed class SendNotification(val config: NotificationConfig) {
),
)
- data object FeeCoverageNotification : Warning(
+ data class FeeCoverageNotification(val cryptoAmount: String, val fiatAmount: String) : Warning(
title = resourceReference(R.string.send_network_fee_warning_title),
- subtitle = resourceReference(R.string.swapping_network_fee_warning_content),
+ subtitle = resourceReference(
+ R.string.send_network_fee_warning_content,
+ wrappedList(cryptoAmount, fiatAmount),
+ ),
)
}
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
index 4f4766450f..4b30a9466f 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
@@ -7,6 +7,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.extensions.networkIconResId
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseToBigDecimal
+import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.minimalAmount
import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase
@@ -19,6 +20,8 @@ import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents
import com.tangem.features.send.impl.presentation.state.*
import com.tangem.features.send.impl.presentation.state.fee.*
+import com.tangem.features.send.impl.presentation.state.fields.SendTextField
+import com.tangem.features.send.impl.presentation.utils.getFiatString
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.lib.crypto.BlockchainUtils.isTezos
import com.tangem.utils.Provider
@@ -30,7 +33,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import java.math.BigDecimal
-@Suppress("LongParameterList")
+@Suppress("LongParameterList", "LargeClass")
internal class SendNotificationFactory(
private val cryptoCurrencyStatusProvider: Provider,
private val coinCryptoCurrencyStatusProvider: Provider,
@@ -39,6 +42,7 @@ internal class SendNotificationFactory(
private val currencyChecksRepository: CurrencyChecksRepository,
private val stateRouterProvider: Provider,
private val isSubtractAvailableProvider: Provider,
+ private val appCurrencyProvider: Provider,
private val clickIntents: SendClickIntents,
private val analyticsEventHandler: AnalyticsEventHandler,
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
@@ -77,7 +81,11 @@ internal class SendNotificationFactory(
addTransactionLimitErrorNotification(feeValue, sendingAmount)
// warnings
addExistentialWarningNotification(feeValue, amountValue)
- addFeeCoverageNotification(isFeeCoverage)
+ addFeeCoverageNotification(
+ isFeeCoverage = isFeeCoverage,
+ amountField = amountState.amountTextField,
+ sendingValue = sendingAmount,
+ )
addHighFeeWarningNotification(amountValue, sendState.ignoreAmountReduce)
addTooHighNotification(feeState.feeSelectorState)
addTooLowNotification(feeState)
@@ -193,22 +201,50 @@ internal class SendNotificationFactory(
cryptoCurrency.network,
)
val diff = balance.minus(spendingAmount)
- if (currencyDeposit != null && currencyDeposit > diff) {
+ if (currencyDeposit != null && diff >= BigDecimal.ZERO && currencyDeposit > diff) {
add(
SendNotification.Error.ExistentialDeposit(
- BigDecimalFormatter.formatCryptoAmountUncapped(
+ deposit = BigDecimalFormatter.formatCryptoAmountUncapped(
cryptoAmount = currencyDeposit,
cryptoCurrency = cryptoCurrency,
),
+ onConfirmClick = {
+ clickIntents.onAmountReduceClick(
+ reduceAmountBy = currencyDeposit,
+ clazz = SendNotification.Error.ExistentialDeposit::class.java,
+ )
+ },
),
)
}
}
- private fun MutableList.addFeeCoverageNotification(sendingAmount: Boolean) {
- if (sendingAmount) {
+ private fun MutableList.addFeeCoverageNotification(
+ isFeeCoverage: Boolean,
+ amountField: SendTextField.AmountField,
+ sendingValue: BigDecimal,
+ ) {
+ if (isFeeCoverage) {
analyticsEventHandler.send(SendAnalyticEvents.NoticeFeeCoverage)
- add(SendNotification.Warning.FeeCoverageNotification)
+ val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
+ val cryptoCurrency = cryptoCurrencyStatus.currency
+ val fiatRate = cryptoCurrencyStatus.value.fiatRate
+ val amountValue = amountField.cryptoAmount.value ?: return
+
+ val cryptoDiff = amountValue.minus(sendingValue)
+ add(
+ SendNotification.Warning.FeeCoverageNotification(
+ cryptoAmount = BigDecimalFormatter.formatCryptoAmountUncapped(
+ cryptoAmount = cryptoDiff,
+ cryptoCurrency = cryptoCurrency,
+ ),
+ fiatAmount = getFiatString(
+ value = cryptoDiff,
+ rate = fiatRate,
+ appCurrency = appCurrencyProvider(),
+ ),
+ ),
+ )
}
}
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/RecipientBlock.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/RecipientBlock.kt
index 0801e63cd6..e3b92db56c 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/RecipientBlock.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/RecipientBlock.kt
@@ -35,6 +35,7 @@ internal fun RecipientBlock(
Column(
modifier = Modifier
+ .fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(backgroundColor)
.clickable(enabled = !isSuccess && !isEditingDisabled, onClick = onClick)
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt
index e21fe8c0c5..73ef044814 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt
@@ -5,8 +5,13 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.utils.BigDecimalFormatter
+import com.tangem.core.ui.utils.BigDecimalFormatter.EMPTY_BALANCE_SIGN
import com.tangem.domain.appcurrency.model.AppCurrency
import java.math.BigDecimal
+import java.math.RoundingMode
+
+private const val FIAT_DECIMALS = 2
+private const val FEE_MINIMUM_VALUE = 0.01
internal fun getCryptoReference(amount: Amount?, isFeeApproximate: Boolean): TextReference? {
if (amount == null) return null
@@ -24,11 +29,31 @@ internal fun getCryptoReference(amount: Amount?, isFeeApproximate: Boolean): Tex
internal fun getFiatReference(value: BigDecimal?, rate: BigDecimal?, appCurrency: AppCurrency): TextReference? {
if (value == null || rate == null) return null
- return stringReference(
+ val formattedFiat = getFiatString(value = value, rate = rate, appCurrency = appCurrency)
+ return stringReference(formattedFiat)
+}
+
+internal fun getFiatString(value: BigDecimal?, rate: BigDecimal?, appCurrency: AppCurrency): String {
+ if (value == null || rate == null) return EMPTY_BALANCE_SIGN
+ val feeValue = value.multiply(rate)
+ val scaled = feeValue.setScale(FIAT_DECIMALS, RoundingMode.UP) ?: BigDecimal.ZERO
+ val formattedValue = if (scaled < BigDecimal(FEE_MINIMUM_VALUE)) {
+ buildString {
+ append(BigDecimalFormatter.CAN_BE_LOWER_SIGN)
+ append(
+ BigDecimalFormatter.formatFiatAmount(
+ fiatAmount = BigDecimal(FEE_MINIMUM_VALUE),
+ fiatCurrencyCode = appCurrency.code,
+ fiatCurrencySymbol = appCurrency.symbol,
+ ),
+ )
+ }
+ } else {
BigDecimalFormatter.formatFiatAmount(
- fiatAmount = value.multiply(rate),
+ fiatAmount = feeValue,
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
- ),
- )
+ )
+ }
+ return formattedValue
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
index 5a6260d448..5410b54f17 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
@@ -168,6 +168,7 @@ internal class SendViewModel @Inject constructor(
userWalletProvider = Provider { userWallet },
stateRouterProvider = Provider { stateRouter },
isSubtractAvailableProvider = Provider { isAmountSubtractAvailable },
+ appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
currencyChecksRepository = currencyChecksRepository,
clickIntents = this,
analyticsEventHandler = analyticsEventHandler,
diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml
index 75242285e6..80bda90466 100644
--- a/gradle/dependencies.toml
+++ b/gradle/dependencies.toml
@@ -85,7 +85,7 @@ leakcanary = "2.13"
# endregion Other libraries
# region Tangem
-tangemBlockchainSdk = "release-app_5.9.1-615"
+tangemBlockchainSdk = "release-app_5.10-618"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "release-app_5.9-343"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^