Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-05 00:41:17 +05:00
parent 404bcc011a
commit 7ed060a37d
31 changed files with 351 additions and 66 deletions

View file

@ -273,6 +273,18 @@ internal object TokensDomainModule {
)
}
@Provides
@Singleton
fun provideGetMinimumTransactionAmountSyncUseCase(
currencyChecksRepository: CurrencyChecksRepository,
dispatchers: CoroutineDispatcherProvider,
): GetMinimumTransactionAmountSyncUseCase {
return GetMinimumTransactionAmountSyncUseCase(
currencyChecksRepository = currencyChecksRepository,
dispatchers = dispatchers,
)
}
@Provides
@Singleton
fun provideIsCryptoCurrencyCoinCouldHideUseCase(

View file

@ -4,10 +4,15 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.common.ui.R
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.amountScreen.utils.checkExceedBalance
import com.tangem.common.ui.amountScreen.utils.getFiatValue
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.isNullOrZero
@ -22,6 +27,7 @@ import java.math.BigDecimal
*/
class AmountReduceByTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: ReduceByData,
) : Transformer<AmountState> {
@ -47,22 +53,37 @@ class AmountReduceByTransformer(
val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue
val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField)
val isLessThanMinimumIfProvided = minimumTransactionAmount?.amount?.let { decimalCryptoValue < it } ?: false
val isZero = if (amountTextField.isFiatValue) {
decimalFiatValue.isNullOrZero()
} else {
decimalCryptoValue.isNullOrZero()
}
val isCheckFailed = isExceedBalance || isLessThanMinimumIfProvided
return prevState.copy(
isPrimaryButtonEnabled = !isExceedBalance && !isZero,
isPrimaryButtonEnabled = !isZero && !isCheckFailed,
amountTextField = amountTextField.copy(
value = cryptoValue,
fiatValue = fiatValue,
isError = isExceedBalance,
error = resourceReference(R.string.send_validation_amount_exceeds_balance),
isError = isCheckFailed,
error = when {
isExceedBalance -> resourceReference(R.string.send_validation_amount_exceeds_balance)
isLessThanMinimumIfProvided -> {
val minimumAmount = minimumTransactionAmount
?.amount
?.format { crypto(cryptoCurrencyStatus.currency) }
.orEmpty()
resourceReference(
R.string.transfer_notification_invalid_minimum_transaction_amount_text,
wrappedList(minimumAmount, minimumAmount),
)
}
else -> TextReference.EMPTY
},
cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue),
fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue),
keyboardOptions = KeyboardOptions(
imeAction = getKeyboardAction(isExceedBalance, decimalCryptoValue),
imeAction = getKeyboardAction(isCheckFailed, decimalCryptoValue),
keyboardType = KeyboardType.Number,
),
),

View file

@ -4,11 +4,17 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.common.ui.R
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.amountScreen.utils.checkExceedBalance
import com.tangem.common.ui.amountScreen.utils.getFiatValue
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.isNullOrZero
import com.tangem.utils.transformer.Transformer
@ -22,6 +28,7 @@ import java.math.BigDecimal
*/
class AmountReduceToTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: BigDecimal,
) : Transformer<AmountState> {
private val maxEnterAmountConverter = MaxEnterAmountConverter()
@ -34,6 +41,7 @@ class AmountReduceToTransformer(
val fiatDecimals = amountTextField.fiatAmount.decimals
val cryptoValue = value.parseBigDecimal(cryptoDecimals)
val decimalCryptoValue = cryptoValue.parseToBigDecimal(cryptoDecimals)
val (fiatValue, decimalFiatValue) = cryptoValue.getFiatValue(
fiatRate = cryptoCurrencyStatus.value.fiatRate,
isFiatValue = false,
@ -44,18 +52,33 @@ class AmountReduceToTransformer(
val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue
val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField)
val isLessThanMinimumIfProvided = minimumTransactionAmount?.amount?.let { decimalCryptoValue < it } ?: false
val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isNullOrZero() else value.isNullOrZero()
val isCheckFailed = isExceedBalance || isLessThanMinimumIfProvided
return prevState.copy(
isPrimaryButtonEnabled = !isExceedBalance && !isZero,
isPrimaryButtonEnabled = !isZero && !isCheckFailed,
amountTextField = amountTextField.copy(
value = cryptoValue,
fiatValue = fiatValue,
isError = isExceedBalance,
error = resourceReference(R.string.send_validation_amount_exceeds_balance),
isError = isCheckFailed,
error = when {
isExceedBalance -> resourceReference(R.string.send_validation_amount_exceeds_balance)
isLessThanMinimumIfProvided -> {
val minimumAmount = minimumTransactionAmount
?.amount
?.format { crypto(cryptoCurrencyStatus.currency) }
.orEmpty()
resourceReference(
R.string.transfer_notification_invalid_minimum_transaction_amount_text,
wrappedList(minimumAmount, minimumAmount),
)
}
else -> TextReference.EMPTY
},
cryptoAmount = amountTextField.cryptoAmount.copy(value = value),
fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue),
keyboardOptions = KeyboardOptions(
imeAction = getKeyboardAction(isExceedBalance, value),
imeAction = getKeyboardAction(isCheckFailed, decimalCryptoValue),
keyboardType = KeyboardType.Number,
),
),

View file

@ -6,7 +6,7 @@ import com.tangem.common.ui.amountScreen.converters.field.AmountFieldConverter
import com.tangem.common.ui.amountScreen.models.AmountParameters
import com.tangem.common.ui.amountScreen.models.AmountSegmentedButtonsConfig
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
@ -34,7 +34,7 @@ class AmountStateConverter(
private val clickIntents: AmountScreenClickIntents,
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val maxEnterAmount: MaxEnterAmount,
private val maxEnterAmount: EnterAmountBoundary,
private val iconStateConverter: CryptoCurrencyToIconStateConverter,
) : Converter<AmountParameters, AmountState> {

View file

@ -1,16 +1,16 @@
package com.tangem.common.ui.amountScreen.converters
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.converter.Converter
/**
* Converts [CryptoCurrencyStatus] to [MaxEnterAmount]
* Converts [CryptoCurrencyStatus] to [EnterAmountBoundary]
*/
class MaxEnterAmountConverter : Converter<CryptoCurrencyStatus, MaxEnterAmount> {
class MaxEnterAmountConverter : Converter<CryptoCurrencyStatus, EnterAmountBoundary> {
override fun convert(value: CryptoCurrencyStatus): MaxEnterAmount {
return MaxEnterAmount(
override fun convert(value: CryptoCurrencyStatus): EnterAmountBoundary {
return EnterAmountBoundary(
amount = value.value.amount,
fiatAmount = value.value.fiatAmount,
fiatRate = value.value.fiatRate,

View file

@ -5,14 +5,18 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.common.ui.R
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.amountScreen.utils.checkExceedBalance
import com.tangem.common.ui.amountScreen.utils.getCryptoValue
import com.tangem.common.ui.amountScreen.utils.getFiatValue
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.isNullOrZero
import com.tangem.utils.transformer.Transformer
import java.math.BigDecimal
@ -24,7 +28,9 @@ import java.math.BigDecimal
* @property value amount value
*/
class AmountFieldChangeTransformer(
private val maxEnterAmount: MaxEnterAmount,
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val maxEnterAmount: EnterAmountBoundary,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: String,
) : Transformer<AmountState> {
@ -52,23 +58,37 @@ class AmountFieldChangeTransformer(
val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue
val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField)
val isLessThanMinimumIfProvided = minimumTransactionAmount?.amount?.let { decimalCryptoValue < it } ?: false
val isZero = if (amountTextField.isFiatValue) {
decimalFiatValue.isNullOrZero()
} else {
decimalCryptoValue.isNullOrZero()
}
val isCheckFailed = isExceedBalance || isLessThanMinimumIfProvided
return prevState.copy(
isPrimaryButtonEnabled = !isExceedBalance && !isZero,
isPrimaryButtonEnabled = !isZero && !isCheckFailed,
amountTextField = amountTextField.copy(
value = cryptoValue,
fiatValue = fiatValue,
isError = isExceedBalance,
error = resourceReference(R.string.send_validation_amount_exceeds_balance).takeIf { isExceedBalance }
?: TextReference.EMPTY,
isError = isCheckFailed,
error = when {
isExceedBalance -> resourceReference(R.string.send_validation_amount_exceeds_balance)
isLessThanMinimumIfProvided -> {
val minimumAmount = minimumTransactionAmount
?.amount
?.format { crypto(cryptoCurrencyStatus.currency) }
.orEmpty()
resourceReference(
R.string.transfer_notification_invalid_minimum_transaction_amount_text,
wrappedList(minimumAmount, minimumAmount),
)
}
else -> TextReference.EMPTY
},
cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue),
fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue),
keyboardOptions = KeyboardOptions(
imeAction = getKeyboardAction(isExceedBalance, decimalCryptoValue),
imeAction = getKeyboardAction(isCheckFailed, decimalCryptoValue),
keyboardType = KeyboardType.Number,
),
),

View file

@ -1,12 +1,19 @@
package com.tangem.common.ui.amountScreen.converters.field
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.common.ui.R
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.utils.isNullOrZero
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.extensions.isZero
import com.tangem.utils.transformer.Transformer
import java.math.RoundingMode
@ -16,7 +23,9 @@ import java.math.RoundingMode
* @property maxAmount maximum enter amount
*/
class AmountFieldSetMaxAmountTransformer(
private val maxAmount: MaxEnterAmount,
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val maxAmount: EnterAmountBoundary,
private val minAmount: EnterAmountBoundary?,
) : Transformer<AmountState> {
override fun transform(prevState: AmountState): AmountState {
@ -29,22 +38,35 @@ class AmountFieldSetMaxAmountTransformer(
val decimalCryptoValue = maxAmount.amount
val decimalFiatValue = maxAmount.fiatAmount
if (decimalCryptoValue.isNullOrZero()) return prevState
if (decimalCryptoValue == null || decimalCryptoValue.isZero()) return prevState
val isDoneActionEnabled = !decimalCryptoValue.isNullOrZero()
val cryptoValue = decimalCryptoValue?.parseBigDecimal(cryptoDecimals).orEmpty()
val cryptoValue = decimalCryptoValue.parseBigDecimal(cryptoDecimals)
val fiatValue = decimalFiatValue?.parseBigDecimal(fiatDecimals, roundingMode = RoundingMode.HALF_UP).orEmpty()
val isLessThanMinimumIfProvided = minAmount?.amount?.let { decimalCryptoValue < it } ?: false
return prevState.copy(
isPrimaryButtonEnabled = true,
isPrimaryButtonEnabled = !isLessThanMinimumIfProvided,
amountTextField = amountTextField.copy(
isValuePasted = true,
value = cryptoValue,
fiatValue = fiatValue,
isError = false,
isError = isLessThanMinimumIfProvided,
error = when {
isLessThanMinimumIfProvided -> {
val minimumAmount = minAmount
?.amount
?.format { crypto(cryptoCurrencyStatus.currency) }
.orEmpty()
resourceReference(
R.string.transfer_notification_invalid_minimum_transaction_amount_text,
wrappedList(minimumAmount, minimumAmount),
)
}
else -> TextReference.EMPTY
},
cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue),
fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue),
keyboardOptions = KeyboardOptions(
imeAction = if (isDoneActionEnabled) ImeAction.Done else ImeAction.None,
imeAction = getKeyboardAction(isLessThanMinimumIfProvided, decimalCryptoValue),
keyboardType = KeyboardType.Number,
),
),

View file

@ -0,0 +1,22 @@
package com.tangem.common.ui.amountScreen.models
import java.math.BigDecimal
data class EnterAmountBoundary(
val amount: BigDecimal? = null,
val fiatAmount: BigDecimal? = null,
val fiatRate: BigDecimal? = null,
) {
constructor(
amount: BigDecimal? = null,
fiatRate: BigDecimal? = null,
) : this(
amount = amount,
fiatAmount = if (amount != null && fiatRate != null) {
amount * fiatRate
} else {
null
},
fiatRate = fiatRate,
)
}

View file

@ -1,9 +0,0 @@
package com.tangem.common.ui.amountScreen.models
import java.math.BigDecimal
data class MaxEnterAmount(
val amount: BigDecimal? = null,
val fiatAmount: BigDecimal? = null,
val fiatRate: BigDecimal? = null,
)

View file

@ -2,10 +2,10 @@ package com.tangem.common.ui.amountScreen.utils
import androidx.compose.ui.text.input.ImeAction
import com.tangem.common.ui.amountScreen.models.AmountFieldModel
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.utils.isNullOrZero
import com.tangem.utils.extensions.isZero
import java.math.BigDecimal
import java.math.RoundingMode
@ -36,7 +36,10 @@ internal fun String.getFiatValue(
}
}
internal fun String.checkExceedBalance(maxEnterAmount: MaxEnterAmount, amountTextField: AmountFieldModel): Boolean {
internal fun String.checkExceedBalance(
maxEnterAmount: EnterAmountBoundary,
amountTextField: AmountFieldModel,
): Boolean {
val currencyCryptoAmount = maxEnterAmount.amount ?: BigDecimal.ZERO
val currencyFiatAmount = maxEnterAmount.fiatAmount ?: BigDecimal.ZERO
val fiatDecimal = parseToBigDecimal(amountTextField.fiatAmount.decimals)
@ -48,8 +51,8 @@ internal fun String.checkExceedBalance(maxEnterAmount: MaxEnterAmount, amountTex
}
}
internal fun getKeyboardAction(isExceedBalance: Boolean, decimalCryptoValue: BigDecimal) =
if (!isExceedBalance && !decimalCryptoValue.isNullOrZero()) {
internal fun getKeyboardAction(isCheckFailed: Boolean, decimalCryptoValue: BigDecimal) =
if (!isCheckFailed && !decimalCryptoValue.isZero()) {
ImeAction.Done
} else {
ImeAction.None

View file

@ -47,6 +47,14 @@ sealed class NotificationUM(val config: NotificationConfig) {
),
)
data class MinimumSendAmountError(val amount: String) : Error(
title = resourceReference(R.string.send_notification_invalid_amount_title),
subtitle = resourceReference(
R.string.transfer_notification_invalid_minimum_transaction_amount_text,
wrappedList(amount, amount),
),
)
data class TransactionLimitError(
val cryptoCurrency: String,
val utxoLimit: String,

View file

@ -75,6 +75,20 @@ object NotificationsFactory {
}
}
fun MutableList<NotificationUM>.addMinimumAmountErrorNotification(
minimumSendAmount: BigDecimal?,
sendingAmount: BigDecimal,
cryptoCurrency: CryptoCurrency,
) {
if (minimumSendAmount != null && minimumSendAmount > sendingAmount) {
add(
NotificationUM.Error.MinimumSendAmountError(
amount = minimumSendAmount.format { crypto(cryptoCurrency) },
),
)
}
}
fun MutableList<NotificationUM>.addTransactionLimitErrorNotification(
utxoLimit: UtxoAmountLimit?,
cryptoCurrency: CryptoCurrency,

View file

@ -2,6 +2,7 @@ package com.tangem.data.tokens.repository
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
import com.tangem.blockchain.common.FeeResourceAmountProvider
import com.tangem.blockchain.common.MinimumSendAmountProvider
import com.tangem.blockchain.common.ReserveAmountProvider
import com.tangem.blockchain.common.UtxoAmountLimitProvider
import com.tangem.data.tokens.converters.UtxoConverter
@ -43,6 +44,15 @@ internal class DefaultCurrencyChecksRepository(
return if (manager is ReserveAmountProvider) manager.getReserveAmount() else null
}
override suspend fun getMinimumSendAmount(userWalletId: UserWalletId, network: Network): BigDecimal? {
val manager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,
)
return if (manager is MinimumSendAmountProvider) manager.getMinimumSendAmount() else null
}
override suspend fun getFeeResourceAmount(userWalletId: UserWalletId, network: Network): CurrencyAmount? {
val manager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,

View file

@ -6,6 +6,7 @@ import java.math.BigDecimal
data class CryptoCurrencyCheck(
val dustValue: BigDecimal?,
val reserveAmount: BigDecimal?,
val minimumSendAmount: BigDecimal?,
val existentialDeposit: BigDecimal?,
val utxoAmountLimit: UtxoAmountLimit?,
val isAccountFunded: Boolean,

View file

@ -24,6 +24,7 @@ class GetCurrencyCheckUseCase(
val network = currencyStatus.currency.network
val dustValue = currencyChecksRepository.getDustValue(userWalletId, network)
val reserveAmount = currencyChecksRepository.getReserveAmount(userWalletId, network)
val minimumSendAmount = currencyChecksRepository.getMinimumSendAmount(userWalletId, network)
val existentialDeposit = currencyChecksRepository.getExistentialDeposit(userWalletId, network)
val isAccountFunded = recipientAddress?.let {
currencyChecksRepository.checkIfAccountFunded(
@ -46,6 +47,7 @@ class GetCurrencyCheckUseCase(
CryptoCurrencyCheck(
dustValue = dustValue,
reserveAmount = reserveAmount,
minimumSendAmount = minimumSendAmount,
existentialDeposit = existentialDeposit,
utxoAmountLimit = utxoAmountLimit,
isAccountFunded = isAccountFunded,

View file

@ -0,0 +1,26 @@
package com.tangem.domain.tokens
import arrow.core.Either
import arrow.core.raise.either
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.withContext
import java.math.BigDecimal
class GetMinimumTransactionAmountSyncUseCase(
private val currencyChecksRepository: CurrencyChecksRepository,
private val dispatchers: CoroutineDispatcherProvider,
) {
suspend operator fun invoke(
userWalletId: UserWalletId,
cryptoCurrencyStatus: CryptoCurrencyStatus,
): Either<Throwable, BigDecimal?> = withContext(dispatchers.io) {
either {
val cryptoCurrency = cryptoCurrencyStatus.currency
currencyChecksRepository.getMinimumSendAmount(userWalletId, cryptoCurrency.network)
}
}
}

View file

@ -20,6 +20,9 @@ interface CurrencyChecksRepository {
/** Returns reserve amount which is required to create an account */
suspend fun getReserveAmount(userWalletId: UserWalletId, network: Network): BigDecimal?
/** Returns minimum send transaction amount */
suspend fun getMinimumSendAmount(userWalletId: UserWalletId, network: Network): BigDecimal?
/** Returns a fee resource amount available and max for paying fees in several blockchains */
suspend fun getFeeResourceAmount(userWalletId: UserWalletId, network: Network): CurrencyAmount?

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state.amount
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -16,6 +17,7 @@ internal class AmountStateFactory(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
) {
private val amountFieldChangeConverter by lazy(LazyThreadSafetyMode.NONE) {
@ -23,6 +25,7 @@ internal class AmountStateFactory(
stateRouterProvider = stateRouterProvider,
currentStateProvider = currentStateProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
)
}
private val amountFieldMaxAmountConverter by lazy(LazyThreadSafetyMode.NONE) {
@ -30,6 +33,7 @@ internal class AmountStateFactory(
stateRouterProvider = stateRouterProvider,
currentStateProvider = currentStateProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
)
}
@ -51,6 +55,7 @@ internal class AmountStateFactory(
stateRouterProvider = stateRouterProvider,
currentStateProvider = currentStateProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
)
}
private val amountReduceToConverter by lazy {
@ -58,6 +63,7 @@ internal class AmountStateFactory(
stateRouterProvider = stateRouterProvider,
currentStateProvider = currentStateProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
)
}

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state.amount
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -11,6 +12,7 @@ internal class SendAmountReduceByConverter(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
) : Converter<AmountReduceByTransformer.ReduceByData, SendUiState> {
override fun convert(value: AmountReduceByTransformer.ReduceByData): SendUiState {
@ -23,7 +25,11 @@ internal class SendAmountReduceByConverter(
sendState = state.sendState?.copy(
reduceAmountBy = value.reduceAmountBy,
),
amountState = AmountReduceByTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState),
amountState = AmountReduceByTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
minimumTransactionAmount = minimumTransactionAmountProvider(),
value = value,
).transform(amountState),
)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state.amount
import com.tangem.common.ui.amountScreen.converters.AmountReduceToTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -12,6 +13,7 @@ internal class SendAmountReduceToConverter(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
) : Converter<BigDecimal, SendUiState> {
override fun convert(value: BigDecimal): SendUiState {
@ -21,7 +23,11 @@ internal class SendAmountReduceToConverter(
return state.copyWrapped(
isEditState = isEditState,
amountState = AmountReduceToTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState),
amountState = AmountReduceToTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
minimumTransactionAmount = minimumTransactionAmountProvider(),
value = value,
).transform(amountState),
)
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addExceedsBalance
import com.tangem.common.ui.notifications.NotificationsFactory.addExistentialWarningNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeCoverageNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachableNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addMinimumAmountErrorNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
@ -192,6 +193,11 @@ internal class SendNotificationFactory(
cryptoCurrency = currency,
isAccountFunded = currencyCheck.isAccountFunded,
)
addMinimumAmountErrorNotification(
minimumSendAmount = currencyCheck.minimumSendAmount,
sendingAmount = sendingAmount,
cryptoCurrency = currency,
)
}
private suspend fun MutableList<NotificationUM>.addWarningNotifications(

View file

@ -2,6 +2,7 @@ package com.tangem.features.send.impl.presentation.state.fields
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -12,21 +13,29 @@ internal class SendAmountFieldChangeConverter(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
) : Converter<String, SendUiState> {
private val maxEnterAmountConverter = MaxEnterAmountConverter()
override fun convert(value: String): SendUiState {
val state = currentStateProvider()
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val isEditState = stateRouterProvider().isEditState
val amountState = state.getAmountState(isEditState)
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatusProvider())
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus)
val minimumTransactionAmount = minimumTransactionAmountProvider()
return state.copyWrapped(
isEditState = isEditState,
sendState = state.sendState?.copy(reduceAmountBy = null),
amountState = AmountFieldChangeTransformer(maxEnterAmount, value).transform(amountState),
amountState = AmountFieldChangeTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
maxEnterAmount = maxEnterAmount,
minimumTransactionAmount = minimumTransactionAmount,
value = value,
).transform(amountState),
)
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.features.send.impl.presentation.state.fields
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldSetMaxAmountTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -13,6 +14,7 @@ internal class SendAmountFieldMaxAmountConverter(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
) : Converter<Unit, SendUiState> {
private val maxEnterAmountConverter = MaxEnterAmountConverter()
@ -27,11 +29,16 @@ internal class SendAmountFieldMaxAmountConverter(
if (decimalCryptoValue.isNullOrZero()) return state
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus)
val minimumTransactionAmount = minimumTransactionAmountProvider()
return state.copyWrapped(
isEditState = isEditState,
sendState = state.sendState?.copy(reduceAmountBy = null),
amountState = AmountFieldSetMaxAmountTransformer(maxEnterAmount).transform(amountState),
amountState = AmountFieldSetMaxAmountTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
maxAmount = maxEnterAmount,
minAmount = minimumTransactionAmount,
).transform(amountState),
)
}
}

View file

@ -12,6 +12,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.bundle.unbundle
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.utils.parseBigDecimal
@ -59,6 +60,7 @@ import com.tangem.features.send.impl.presentation.state.recipient.RecipientSendF
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.orZero
import com.tangem.utils.extensions.stripZeroPlainString
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.*
@ -78,6 +80,7 @@ internal class SendViewModel @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getWalletsUseCase: GetWalletsUseCase,
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
private val getCryptoCurrencyUseCase: GetCryptoCurrencyUseCase,
private val getNetworkAddressesUseCase: GetNetworkAddressesUseCase,
private val getTxHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
@ -153,6 +156,7 @@ internal class SendViewModel @Inject constructor(
stateRouterProvider = Provider { stateRouter },
currentStateProvider = Provider { uiState.value },
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
minimumTransactionAmountProvider = Provider { minimumTransactionAmount },
)
private val feeStateFactory = FeeStateFactory(
@ -212,6 +216,7 @@ internal class SendViewModel @Inject constructor(
private var isTapHelpPreviewEnabled: Boolean = false
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus? = null
private var minimumTransactionAmount: EnterAmountBoundary? = null
private var balanceJobHolder = JobHolder()
private var balanceHidingJobHolder = JobHolder()
@ -295,6 +300,7 @@ internal class SendViewModel @Inject constructor(
onDataLoaded(
currencyStatus = cryptoCurrencyStatus,
feeCurrencyStatus = getFeeCurrencyStatusSync(cryptoCurrencyStatus, isMultiCurrency),
minTransactionAmount = getMinimumTransactionAmount(cryptoCurrencyStatus),
)
},
ifLeft = { showErrorAlert() },
@ -336,6 +342,18 @@ internal class SendViewModel @Inject constructor(
}
}
private suspend fun getMinimumTransactionAmount(cryptoCurrencyStatus: CryptoCurrencyStatus): EnterAmountBoundary? {
return getMinimumTransactionAmountSyncUseCase(
userWalletId = userWalletId,
cryptoCurrencyStatus = cryptoCurrencyStatus,
).getOrNull()?.let {
EnterAmountBoundary(
amount = it,
fiatRate = cryptoCurrencyStatus.value.fiatRate.orZero(),
)
}
}
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
return getSelectedAppCurrencyUseCase()
.map { maybeAppCurrency ->
@ -348,9 +366,14 @@ internal class SendViewModel @Inject constructor(
)
}
private fun onDataLoaded(currencyStatus: CryptoCurrencyStatus, feeCurrencyStatus: CryptoCurrencyStatus?) {
private fun onDataLoaded(
currencyStatus: CryptoCurrencyStatus,
feeCurrencyStatus: CryptoCurrencyStatus?,
minTransactionAmount: EnterAmountBoundary?,
) {
cryptoCurrencyStatus = currencyStatus
feeCryptoCurrencyStatus = feeCurrencyStatus
minimumTransactionAmount = minTransactionAmount
subscribeOnQRScannerResult()
when {
uiState.value.sendState?.isSuccess == true -> return

View file

@ -2,7 +2,7 @@ package com.tangem.features.staking.impl.presentation.state.transformers
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
import com.tangem.common.ui.amountScreen.models.AmountParameters
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
@ -37,7 +37,7 @@ internal class SetAmountDataTransformer(
} else {
cryptoBalanceValue.amount to cryptoBalanceValue.fiatAmount
}
val maxEnterAmount = MaxEnterAmount(
val maxEnterAmount = EnterAmountBoundary(
amount = amount,
fiatAmount = fiatAmount,
fiatRate = cryptoBalanceValue.fiatRate,

View file

@ -4,7 +4,7 @@ import com.tangem.common.extensions.remove
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
import com.tangem.common.ui.amountScreen.models.AmountParameters
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.list.RoundedListWithDividersItemData
import com.tangem.core.ui.extensions.*
@ -201,7 +201,7 @@ internal class SetInitialDataStateTransformer(
private fun createInitialAmountState(): AmountState {
val cryptoBalanceValue = cryptoCurrencyStatusProvider().value
val maxEnterAmount = MaxEnterAmount(
val maxEnterAmount = EnterAmountBoundary(
amount = cryptoBalanceValue.amount,
fiatAmount = cryptoBalanceValue.fiatAmount,
fiatRate = cryptoBalanceValue.fiatRate,

View file

@ -2,7 +2,7 @@ package com.tangem.features.staking.impl.presentation.state.transformers.amount
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -11,6 +11,7 @@ import com.tangem.utils.transformer.Transformer
internal class AmountChangeStateTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: String,
private val yield: Yield,
) : Transformer<StakingUiState> {
@ -20,7 +21,7 @@ internal class AmountChangeStateTransformer(
override fun transform(prevState: StakingUiState): StakingUiState {
val actionType = prevState.actionType
val maxEnterAmount = if (actionType == StakingActionCommonType.Exit) {
MaxEnterAmount(
EnterAmountBoundary(
amount = prevState.balanceState?.cryptoAmount,
fiatAmount = prevState.balanceState?.fiatAmount,
fiatRate = cryptoCurrencyStatus.value.fiatRate,
@ -29,7 +30,12 @@ internal class AmountChangeStateTransformer(
maxEnterAmountConverter.convert(cryptoCurrencyStatus)
}
val updatedAmountState = AmountFieldChangeTransformer(maxEnterAmount, value).transform(prevState.amountState)
val updatedAmountState = AmountFieldChangeTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
maxEnterAmount = maxEnterAmount,
minimumTransactionAmount = minimumTransactionAmount,
value = value,
).transform(prevState.amountState)
return prevState.copy(
amountState = AmountRequirementStateTransformer(

View file

@ -2,7 +2,7 @@ package com.tangem.features.staking.impl.presentation.state.transformers.amount
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldSetMaxAmountTransformer
import com.tangem.common.ui.amountScreen.models.MaxEnterAmount
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -11,6 +11,7 @@ import com.tangem.utils.transformer.Transformer
internal class AmountMaxValueStateTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val actionType: StakingActionCommonType,
private val yield: Yield,
) : Transformer<StakingUiState> {
@ -19,7 +20,7 @@ internal class AmountMaxValueStateTransformer(
override fun transform(prevState: StakingUiState): StakingUiState {
val maxEnterAmount = if (actionType == StakingActionCommonType.Exit) {
MaxEnterAmount(
EnterAmountBoundary(
amount = prevState.balanceState?.cryptoAmount,
fiatAmount = prevState.balanceState?.fiatAmount,
fiatRate = cryptoCurrencyStatus.value.fiatRate,
@ -28,8 +29,11 @@ internal class AmountMaxValueStateTransformer(
maxEnterAmountConverter.convert(cryptoCurrencyStatus)
}
val updatedAmountState = AmountFieldSetMaxAmountTransformer(maxEnterAmount)
.transform(prevState.amountState)
val updatedAmountState = AmountFieldSetMaxAmountTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
maxAmount = maxEnterAmount,
minAmount = minimumTransactionAmount,
).transform(prevState.amountState)
return prevState.copy(
amountState = AmountRequirementStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,

View file

@ -2,18 +2,24 @@ package com.tangem.features.staking.impl.presentation.state.transformers.amount
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer.ReduceByData
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.presentation.state.StakingUiState
import com.tangem.utils.transformer.Transformer
internal class AmountReduceByStateTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: ReduceByData,
) : Transformer<StakingUiState> {
override fun transform(prevState: StakingUiState): StakingUiState {
return prevState.copy(
amountState = AmountReduceByTransformer(cryptoCurrencyStatus, value).transform(prevState.amountState),
amountState = AmountReduceByTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
value = value,
).transform(prevState.amountState),
)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.features.staking.impl.presentation.state.transformers.amount
import com.tangem.common.ui.amountScreen.converters.AmountReduceToTransformer
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.presentation.state.StakingUiState
import com.tangem.utils.transformer.Transformer
@ -8,11 +9,16 @@ import java.math.BigDecimal
internal class AmountReduceToStateTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: BigDecimal,
) : Transformer<StakingUiState> {
override fun transform(prevState: StakingUiState): StakingUiState {
return prevState.copy(
amountState = AmountReduceToTransformer(cryptoCurrencyStatus, value).transform(prevState.amountState),
amountState = AmountReduceToTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
value = value,
).transform(prevState.amountState),
)
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.bundle.unbundle
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionBottomSheetConfig
import com.tangem.common.ui.notifications.NotificationUM
@ -72,6 +73,7 @@ import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstake
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.isSingleItem
import com.tangem.utils.extensions.orZero
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -92,6 +94,7 @@ internal class StakingViewModel @Inject constructor(
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val sendTransactionUseCase: SendTransactionUseCase,
@ -139,6 +142,7 @@ internal class StakingViewModel @Inject constructor(
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
private var processingActions: List<StakingAction> = emptyList()
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus? = null
private var minimumTransactionAmount: EnterAmountBoundary? = null
private var innerRouter: InnerStakingRouter by Delegates.notNull()
private var userWallet: UserWallet by Delegates.notNull()
@ -366,7 +370,14 @@ internal class StakingViewModel @Inject constructor(
}
override fun onAmountValueChange(value: String) {
stateController.update(AmountChangeStateTransformer(cryptoCurrencyStatus, value, yield))
stateController.update(
AmountChangeStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
value = value,
yield = yield,
),
)
}
override fun onAmountPasteTriggerDismiss() {
@ -378,6 +389,7 @@ internal class StakingViewModel @Inject constructor(
stateController.update(
AmountMaxValueStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
actionType = uiState.value.actionType,
yield = yield,
),
@ -621,6 +633,7 @@ internal class StakingViewModel @Inject constructor(
) {
AmountReduceByStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
value = AmountReduceByTransformer.ReduceByData(
reduceAmountBy = reduceAmountBy,
reduceAmountByDiff = reduceAmountByDiff,
@ -633,6 +646,7 @@ internal class StakingViewModel @Inject constructor(
stateController.update(
AmountReduceToStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
minimumTransactionAmount = minimumTransactionAmount,
value = reduceAmountTo,
),
)
@ -796,6 +810,13 @@ internal class StakingViewModel @Inject constructor(
feeCryptoCurrencyStatus =
getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull()
minimumTransactionAmount =
getMinimumTransactionAmountSyncUseCase(userWalletId, status).getOrNull()?.let {
EnterAmountBoundary(
amount = it,
fiatRate = status.value.fiatRate.orZero(),
)
}
cryptoCurrencyStatus = status
setupApprovalNeeded()
@ -929,6 +950,7 @@ internal class StakingViewModel @Inject constructor(
AmountChangeStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
value = amountValue,
minimumTransactionAmount = minimumTransactionAmount,
yield = yield,
),
)