diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceByTransformer.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceByTransformer.kt index 9597b3d764..0b9f4c1a5d 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceByTransformer.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceByTransformer.kt @@ -24,6 +24,9 @@ class AmountReduceByTransformer( private val cryptoCurrencyStatus: CryptoCurrencyStatus, private val value: ReduceByData, ) : Transformer { + + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun transform(prevState: AmountState): AmountState { if (prevState !is AmountState.Data) return prevState @@ -40,8 +43,10 @@ class AmountReduceByTransformer( decimals = fiatDecimals, ) + val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus) + val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) + val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField) val isZero = if (amountTextField.isFiatValue) { decimalFiatValue.isNullOrZero() } else { diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceToTransformer.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceToTransformer.kt index c81634b818..74f6e66852 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceToTransformer.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountReduceToTransformer.kt @@ -24,6 +24,8 @@ class AmountReduceToTransformer( private val cryptoCurrencyStatus: CryptoCurrencyStatus, private val value: BigDecimal, ) : Transformer { + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun transform(prevState: AmountState): AmountState { if (prevState !is AmountState.Data) return prevState @@ -38,8 +40,10 @@ class AmountReduceToTransformer( decimals = fiatDecimals, ) + val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus) + val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) + val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField) val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isNullOrZero() else value.isNullOrZero() return prevState.copy( isPrimaryButtonEnabled = !isExceedBalance && !isZero, diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountStateConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountStateConverter.kt index 3445c4859f..e2adb46d11 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountStateConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/AmountStateConverter.kt @@ -3,8 +3,10 @@ package com.tangem.common.ui.amountScreen.converters import com.tangem.common.ui.R import com.tangem.common.ui.amountScreen.AmountScreenClickIntents 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.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference @@ -14,7 +16,6 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.utils.BigDecimalFormatter.formatFiatAmount import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.domain.wallets.models.UserWallet import com.tangem.utils.Provider import com.tangem.utils.converter.Converter import com.tangem.utils.isNullOrZero @@ -25,17 +26,17 @@ import kotlinx.collections.immutable.persistentListOf * * @property clickIntents amount screen clicks * @property appCurrencyProvider selected app currency provider - * @property userWalletProvider selected user wallet provider + * @property maxEnterAmountProvider max enter amount data provider * @property cryptoCurrencyStatusProvider current cryptocurrency status provider * @property iconStateConverter currency icon converter */ class AmountStateConverter( private val clickIntents: AmountScreenClickIntents, private val appCurrencyProvider: Provider, - private val userWalletProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, + private val maxEnterAmountProvider: Provider, private val iconStateConverter: CryptoCurrencyToIconStateConverter, -) : Converter { +) : Converter { private val amountFieldConverter by lazy(LazyThreadSafetyMode.NONE) { AmountFieldConverter( @@ -45,19 +46,19 @@ class AmountStateConverter( ) } - override fun convert(value: String): AmountState { - val userWallet = userWalletProvider() + override fun convert(value: AmountParameters): AmountState { + val maxEnterAmount = maxEnterAmountProvider() val appCurrency = appCurrencyProvider() val status = cryptoCurrencyStatusProvider() - val fiat = formatFiatAmount(status.value.fiatAmount, appCurrency.code, appCurrency.symbol) - val crypto = status.value.amount.format { crypto(status.currency) } + val fiat = formatFiatAmount(maxEnterAmount.fiatAmount, appCurrency.code, appCurrency.symbol) + val crypto = maxEnterAmount.amount.format { crypto(status.currency) } val noFeeRate = status.value.fiatRate.isNullOrZero() return AmountState.Data( - walletName = userWallet.name, - walletBalance = resourceReference(R.string.common_crypto_fiat_format, wrappedList(crypto, fiat)), + title = value.title, + availableBalance = resourceReference(R.string.common_crypto_fiat_format, wrappedList(crypto, fiat)), tokenIconState = iconStateConverter.convert(status), - amountTextField = amountFieldConverter.convert(value), + amountTextField = amountFieldConverter.convert(value.value), isPrimaryButtonEnabled = false, appCurrencyCode = appCurrency.code, segmentedButtonConfig = persistentListOf( diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/MaxEnterAmountConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/MaxEnterAmountConverter.kt new file mode 100644 index 0000000000..1b23b64181 --- /dev/null +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/MaxEnterAmountConverter.kt @@ -0,0 +1,19 @@ +package com.tangem.common.ui.amountScreen.converters + +import com.tangem.common.ui.amountScreen.models.MaxEnterAmount +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.utils.converter.Converter + +/** + * Converts [CryptoCurrencyStatus] to [MaxEnterAmount] + */ +class MaxEnterAmountConverter : Converter { + + override fun convert(value: CryptoCurrencyStatus): MaxEnterAmount { + return MaxEnterAmount( + amount = value.value.amount, + fiatAmount = value.value.fiatAmount, + fiatRate = value.value.fiatRate, + ) + } +} \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldChangeTransformer.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldChangeTransformer.kt index 8de99b1fc5..b51fa49ad2 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldChangeTransformer.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldChangeTransformer.kt @@ -5,6 +5,7 @@ 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.utils.checkExceedBalance import com.tangem.common.ui.amountScreen.utils.getCryptoValue import com.tangem.common.ui.amountScreen.utils.getFiatValue @@ -12,7 +13,6 @@ 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.utils.parseToBigDecimal -import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.utils.isNullOrZero import com.tangem.utils.transformer.Transformer import java.math.BigDecimal @@ -20,11 +20,11 @@ import java.math.BigDecimal /** * Amount value change * - * @property cryptoCurrencyStatus current cryptocurrency status + * @property maxEnterAmount max amount to enter * @property value amount value */ class AmountFieldChangeTransformer( - private val cryptoCurrencyStatus: CryptoCurrencyStatus, + private val maxEnterAmount: MaxEnterAmount, private val value: String, ) : Transformer { @@ -39,19 +39,19 @@ class AmountFieldChangeTransformer( val trimmedValue = value.trim() val cryptoValue = trimmedValue.getCryptoValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, + fiatRate = maxEnterAmount.fiatRate, isFiatValue = amountTextField.isFiatValue, decimals = cryptoDecimals, ) val decimalCryptoValue = cryptoValue.parseToBigDecimal(cryptoDecimals) val (fiatValue, decimalFiatValue) = trimmedValue.getFiatValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, + fiatRate = maxEnterAmount.fiatRate, isFiatValue = amountTextField.isFiatValue, decimals = fiatDecimals, ) val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) + val isExceedBalance = checkValue.checkExceedBalance(maxEnterAmount, amountTextField) val isZero = if (amountTextField.isFiatValue) { decimalFiatValue.isNullOrZero() } else { diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldMaxAmountTransformer.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldSetMaxAmountTransformer.kt similarity index 83% rename from common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldMaxAmountTransformer.kt rename to common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldSetMaxAmountTransformer.kt index 05a8705750..16c67d20f8 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldMaxAmountTransformer.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/converters/field/AmountFieldSetMaxAmountTransformer.kt @@ -4,8 +4,8 @@ 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.amountScreen.models.AmountState +import com.tangem.common.ui.amountScreen.models.MaxEnterAmount import com.tangem.core.ui.utils.parseBigDecimal -import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.utils.isNullOrZero import com.tangem.utils.transformer.Transformer import java.math.RoundingMode @@ -13,10 +13,10 @@ import java.math.RoundingMode /** * Selects maximum amount value * - * @property cryptoCurrencyStatus current cryptocurrency status + * @property maxAmount maximum enter amount */ -class AmountFieldMaxAmountTransformer( - private val cryptoCurrencyStatus: CryptoCurrencyStatus, +class AmountFieldSetMaxAmountTransformer( + private val maxAmount: MaxEnterAmount, ) : Transformer { override fun transform(prevState: AmountState): AmountState { @@ -26,8 +26,8 @@ class AmountFieldMaxAmountTransformer( val cryptoDecimals = amountTextField.cryptoAmount.decimals val fiatDecimals = amountTextField.fiatAmount.decimals - val decimalCryptoValue = cryptoCurrencyStatus.value.amount - val decimalFiatValue = cryptoCurrencyStatus.value.fiatAmount + val decimalCryptoValue = maxAmount.amount + val decimalFiatValue = maxAmount.fiatAmount if (decimalCryptoValue.isNullOrZero()) return prevState diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountParameters.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountParameters.kt new file mode 100644 index 0000000000..e84bfb4330 --- /dev/null +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountParameters.kt @@ -0,0 +1,8 @@ +package com.tangem.common.ui.amountScreen.models + +import com.tangem.core.ui.extensions.TextReference + +data class AmountParameters( + val title: TextReference, + val value: String, +) \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountState.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountState.kt index d23a2892bf..52758a02cc 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountState.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/AmountState.kt @@ -13,8 +13,8 @@ sealed class AmountState { /** * @param isPrimaryButtonEnabled indicates if next state button enabled - * @param walletName user wallet name - * @param walletBalance user crypto currency balance in wallet + * @param title title + * @param availableBalance user crypto currency balance * @param tokenIconState crypto currency icon state * @param segmentedButtonConfig currency switcher config * @param selectedButton selected currency index @@ -24,8 +24,8 @@ sealed class AmountState { */ data class Data( override val isPrimaryButtonEnabled: Boolean, - val walletName: String, - val walletBalance: TextReference, + val title: TextReference, + val availableBalance: TextReference, val tokenIconState: CurrencyIconState, val segmentedButtonConfig: PersistentList, val selectedButton: Int, diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/MaxEnterAmount.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/MaxEnterAmount.kt new file mode 100644 index 0000000000..e9a5f88238 --- /dev/null +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/models/MaxEnterAmount.kt @@ -0,0 +1,9 @@ +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, +) \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/preview/AmountStatePreviewData.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/preview/AmountStatePreviewData.kt index a622f752c9..63c4d0cd5d 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/preview/AmountStatePreviewData.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/preview/AmountStatePreviewData.kt @@ -17,8 +17,8 @@ object AmountStatePreviewData { val amountState = AmountState.Data( isPrimaryButtonEnabled = false, - walletName = "Family Wallet", - walletBalance = stringReference("2 130,88 USDT (2 129,92 \$)"), + title = stringReference("Family Wallet"), + availableBalance = stringReference("2 130,88 USDT (2 129,92 \$)"), tokenIconState = CurrencyIconState.Loading, segmentedButtonConfig = persistentListOf( AmountSegmentedButtonsConfig( diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldContainer.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldContainer.kt index caee01e48c..8b9904cc42 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldContainer.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldContainer.kt @@ -34,14 +34,14 @@ internal fun LazyListScope.amountField( .background(TangemTheme.colors.background.action), ) { Text( - text = amountState.walletName, + text = amountState.title.resolveReference(), style = TangemTheme.typography.subtitle2, color = TangemTheme.colors.text.tertiary, modifier = Modifier .padding(top = TangemTheme.dimens.spacing14), ) - val balance = amountState.walletBalance.orMaskWithStars(isBalanceHidden).resolveReference() + val balance = amountState.availableBalance.orMaskWithStars(isBalanceHidden).resolveReference() AnimatedContent( targetState = balance, label = "Hide Balance Animation", diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/utils/AmountUtils.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/utils/AmountUtils.kt index 26492fa913..3f20ba474c 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/utils/AmountUtils.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/utils/AmountUtils.kt @@ -2,9 +2,9 @@ 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.core.ui.utils.parseBigDecimal import com.tangem.core.ui.utils.parseToBigDecimal -import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.utils.isNullOrZero import java.math.BigDecimal import java.math.RoundingMode @@ -36,12 +36,9 @@ internal fun String.getFiatValue( } } -internal fun String.checkExceedBalance( - cryptoCurrencyStatus: CryptoCurrencyStatus, - amountTextField: AmountFieldModel, -): Boolean { - val currencyCryptoAmount = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO - val currencyFiatAmount = cryptoCurrencyStatus.value.fiatAmount ?: BigDecimal.ZERO +internal fun String.checkExceedBalance(maxEnterAmount: MaxEnterAmount, amountTextField: AmountFieldModel): Boolean { + val currencyCryptoAmount = maxEnterAmount.amount ?: BigDecimal.ZERO + val currencyFiatAmount = maxEnterAmount.fiatAmount ?: BigDecimal.ZERO val fiatDecimal = parseToBigDecimal(amountTextField.fiatAmount.decimals) val cryptoDecimal = parseToBigDecimal(amountTextField.cryptoAmount.decimals) return if (amountTextField.isFiatValue) { diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 7fdccc468b..4313234fb9 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -698,6 +698,7 @@ Name Die Anzahl der zu stakenden Krypros muss mindesten %s betragen Der Stakingbetrag wird aufgrund der Netzwerkregeln auf %1$s TRX aufgerundet. + Der Betrag der unstaked wird, wird aufgrund der Netzwerkregeln auf %1$s TRX gerundet. Nicht gestakte beanspruche Gebühr für das Staking-Konto Ein Staking-Konto ist ein spezielles Konto, auf dem eingesetzte SOL-Token gelagert werden. Es wird erstellt, wenn du deine Token an einen Validator delegierst, um an der Transaktionsvalidierung teilzunehmen und Belohnungen zu verdienen. Für die Erstellung des Staking-Kontos wird eine geringe Gebühr erhoben, die nach Abschluss des Stakings zurückgegeben wird. @@ -783,6 +784,7 @@ Lösen der Bindungen Gelocktes unlocken Entsperren + Die Anzahl der zu stakenden Krypros muss mindesten %s betragen Der Betrag übersteigt das eingesetzte Guthaben Unstaken Staking beenden @@ -810,6 +812,7 @@ Neuer Swap-Anbieter verfügbar! Der Betrag umfasst:\n- Gebühr des Dienstanbieters\n- Netzgebühr für die Rücksendung von %s von der Vermittlungsstelle an die Adresse des Nutzers. Der Betrag enthält die Gebühren des Dienstleisters. + Anbieter-Slippage kann bis zu %s ausfallen. Gebühren Alle dezentralen Börsen benötigen Genehmigungen, um zu verhindern, dass intelligente Verträge ohne Ihre Erlaubnis auf Ihre Geldbörse zugreifen. Smart Contracts können nicht auf Ihre Token zugreifen, wenn Sie nicht zustimmen. Indem Sie Ihre Token \"freischalten\", ermächtigen Sie den 1-Zoll-Smart-Contract, sie auszugeben. Die Miner des Netzwerks erhalten eine (von Ihnen bezahlte) Gasgebühr, um diese Aktion in der Blockchain aufzuzeichnen. Sie können Ihre Token tauschen, nachdem Sie Ihre Zustimmung gegeben haben. Genehmigen diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 03a98284df..a8fc4365c8 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -781,6 +781,7 @@ Desunión Desbloquear Desbloqueando + El monto del staking debe ser al menos %s El monto excede el saldo apostado Sin staking Unstaking diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 7882e38152..42eb2abac8 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -781,6 +781,7 @@ Dissociation Débloquer Déverrouillage + Le montant à staker doit être au moins %s Le montant dépasse le solde misé Non-staké Unstaking diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index de3d33b7d2..8cdaeffe4a 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -688,6 +688,7 @@ 名前 ステーキング金額は %s 以上である必要があります ネットワークルールにより、ステーキング金額は%1$s TRX に切り上げられます。 + ネットワークルールにより、ステーキング解除の量は%1$s TRX に切り上げられます。 ステーキング解除分を請求する ステーキングアカウント手数料 ステーキングアカウントは、ステーキングされたSOLトークンが保管される特別なアカウントです。取引の検証に参加して報酬を得るために、トークンをバリデーターに委任すると、このアカウントが作成されます。ステーキングアカウントの作成には少額の手数料がかかりますが、この手数料はステーキングが完了すると返金されます。 @@ -773,6 +774,7 @@ ステーキング解約中 ロック解除 ロック解除中 + ステーキング金額は %s 以上である必要があります 金額がステーキング残高を超えています ステーキングされていない ステーキング解除 @@ -800,6 +802,7 @@ 新しいスワッププロバイダーが利用可能になりました! この金額には以下が含まれます:\n- サービスプロバイダーの手数料\n- 取引所からユーザーのアドレスに%s を送り返すためのネットワーク手数料。 この金額には、サービスプロバイダーの手数料が含まれています。 + プロバイダーのスリッページは最大%sです。 手数料 すべての分散型取引所は、スマートコントラクトがあなたの許可なくウォレットにアクセスするのを防ぐために承認を必要とします。設計上、スマートコントラクトは承認なしでトークンにアクセスできません。トークンを「ロック解除」することで、あなたは1-inchのスマートコントラクトがトークンを使うことを承認します。ネットワークのマイナーは、このアクションをブロックチェーンに記録するためのガス料金(あなたが支払う)を受け取ります。承認後、トークンを交換することができます。 承認 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index ba6d9c4db6..c600ccc00e 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -798,6 +798,7 @@ Отзыв Разблокировать Разблокировка + Сумма для стейкинга должна быть не менее %s Сумма превышает застейканный баланс Вывод из стейкинга Завершение стейкинга diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 73f301ed3c..18f9697aaa 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -800,6 +800,7 @@ Розблокування Розблокувати Розблокування + Сума для стейкінгу має бути не менше %s Сума перевищує баланс стейкінгу Вивід зі стейкінгу Зняти зі стейкінгу diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 0e98aa2383..3a507e68ab 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -698,6 +698,7 @@ Name The amount to stake must be at least %s Staking amount will be rounded to %1$s TRX due to network rules. + Unstaking amount will be rounded to %1$s TRX due to network rules. Claim unstaked Stake account fee A staking account is a special account where staked SOL tokens are stored. It is created when you delegate your tokens to a validator to participate in transaction validation and earn rewards. A small fee is charged for creating the staking account, which is returned after the staking is completed. @@ -773,6 +774,7 @@ Rewards Stake locked Stake more + Staked amount You stake %1$s and will be receiving your reward %2$s Tap to unlock Tap to unlock or vote @@ -783,6 +785,7 @@ Unbonding Unlock Unlocking + The amount to unstake must be at least %s Amount exceeds staked balance Unstaked Unstaking diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt index ddcc7ab29a..0b69329371 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt @@ -2,10 +2,13 @@ package com.tangem.features.send.impl.presentation.state import com.tangem.blockchain.common.TransactionData import com.tangem.common.ui.amountScreen.converters.AmountStateConverter +import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter +import com.tangem.common.ui.amountScreen.models.AmountParameters import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.event.consumedEvent +import com.tangem.core.ui.extensions.stringReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet @@ -33,14 +36,15 @@ internal class SendStateFactory( private val isTapHelpPreviewEnabledProvider: Provider, ) { private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter) + private val maxEnterAmountConverter = MaxEnterAmountConverter() private val amountStateConverter by lazy(LazyThreadSafetyMode.NONE) { AmountStateConverter( clickIntents = clickIntents, appCurrencyProvider = appCurrencyProvider, iconStateConverter = iconStateConverter, - userWalletProvider = userWalletProvider, cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, + maxEnterAmountProvider = Provider { maxEnterAmountConverter.convert(cryptoCurrencyStatusProvider()) }, ) } private val recipientStateConverter by lazy(LazyThreadSafetyMode.NONE) { @@ -79,7 +83,12 @@ internal class SendStateFactory( fun getReadyState(): SendUiState { val state = currentStateProvider() val amountState = if (state.amountState is AmountState.Empty) { - amountStateConverter.convert("") + amountStateConverter.convert( + AmountParameters( + title = stringReference(userWalletProvider().name), + value = "", + ), + ) } else { state.amountState } @@ -96,7 +105,12 @@ internal class SendStateFactory( fun getReadyState(amount: String, destinationAddress: String, memo: String?): SendUiState { val state = currentStateProvider() val amountState = if (state.amountState is AmountState.Empty) { - amountStateConverter.convert(amount) + amountStateConverter.convert( + AmountParameters( + title = stringReference(userWalletProvider().name), + value = amount, + ), + ) } else { state.amountState } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt index 4b5dda431d..c4f28c469e 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt @@ -1,5 +1,6 @@ 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.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState @@ -13,15 +14,19 @@ internal class SendAmountFieldChangeConverter( private val cryptoCurrencyStatusProvider: Provider, ) : Converter { + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun convert(value: String): SendUiState { val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState - val amountState = state.getAmountState(isEditState) ?: return state + val amountState = state.getAmountState(isEditState) + + val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatusProvider()) return state.copyWrapped( isEditState = isEditState, sendState = state.sendState?.copy(reduceAmountBy = null), - amountState = AmountFieldChangeTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState), + amountState = AmountFieldChangeTransformer(maxEnterAmount, value).transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt index 5577388040..6e071d34d8 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt @@ -1,6 +1,7 @@ package com.tangem.features.send.impl.presentation.state.fields -import com.tangem.common.ui.amountScreen.converters.field.AmountFieldMaxAmountTransformer +import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter +import com.tangem.common.ui.amountScreen.converters.field.AmountFieldSetMaxAmountTransformer 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 @@ -14,6 +15,8 @@ internal class SendAmountFieldMaxAmountConverter( private val cryptoCurrencyStatusProvider: Provider, ) : Converter { + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun convert(value: Unit): SendUiState { val state = currentStateProvider() val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() @@ -23,10 +26,12 @@ internal class SendAmountFieldMaxAmountConverter( val decimalCryptoValue = cryptoCurrencyStatus.value.amount if (decimalCryptoValue.isNullOrZero()) return state + val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus) + return state.copyWrapped( isEditState = isEditState, sendState = state.sendState?.copy(reduceAmountBy = null), - amountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatusProvider()).transform(amountState), + amountState = AmountFieldSetMaxAmountTransformer(maxEnterAmount).transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt index 3324d89836..c588753385 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt @@ -88,7 +88,7 @@ private fun SendAppBar(uiState: SendUiState, currentState: SendUiCurrentScreen) -> resourceReference(R.string.common_fee_selector_title) to null SendUiStateType.Send -> if (uiState.sendState?.isSuccess == false) { resourceReference(R.string.send_summary_title, wrappedList(uiState.cryptoCurrencyName)) to - (uiState.amountState as? AmountState.Data)?.walletName + (uiState.amountState as? AmountState.Data)?.title } else { null to null } @@ -108,7 +108,7 @@ private fun SendAppBar(uiState: SendUiState, currentState: SendUiCurrentScreen) } AppBarWithBackButtonAndIcon( text = titleRes?.resolveReference(), - subtitle = subtitleRes, + subtitle = subtitleRes?.resolveReference(), onBackClick = uiState.clickIntents::onCloseClick, onIconClick = uiState.clickIntents::onQrCodeScanClick, backIconRes = backIcon, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt index b6e5bef985..7fa7d42377 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt @@ -30,9 +30,10 @@ internal data class BalanceState( val subtitle: TextReference?, val isClickable: Boolean, val cryptoValue: String, - val cryptoDecimal: BigDecimal, - val cryptoAmount: TextReference, - val fiatAmount: TextReference, + val cryptoAmount: BigDecimal, + val formattedCryptoAmount: TextReference, + val fiatAmount: BigDecimal?, + val formattedFiatAmount: TextReference, val rawCurrencyId: String?, val validator: Yield.Validator?, val pendingActions: ImmutableList, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateController.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateController.kt index dd8919a82c..71d3c67900 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateController.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateController.kt @@ -75,6 +75,7 @@ internal class StakingStateController @Inject constructor( walletName = "", cryptoCurrencyName = "", cryptoCurrencySymbol = "", + cryptoCurrencyNetworkId = "", currentStep = StakingStep.InitialInfo, initialInfoState = StakingStates.InitialInfoState.Empty(), amountState = AmountState.Empty(), @@ -86,6 +87,7 @@ internal class StakingStateController @Inject constructor( bottomSheetConfig = null, actionType = StakingActionCommonType.Enter, buttonsState = NavigationButtonsState.Empty, + balanceState = null, ) } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt index bcddf3b0df..48823d364f 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt @@ -5,6 +5,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.analytics.StakingAnalyticsEvent import com.tangem.features.staking.impl.analytics.utils.StakingAnalyticSender +import com.tangem.lib.crypto.BlockchainUtils.isSolana internal class StakingStateRouter( private val appRouter: AppRouter, @@ -24,8 +25,13 @@ internal class StakingStateRouter( when (stateController.value.currentStep) { StakingStep.InitialInfo -> when (stateController.value.actionType) { StakingActionCommonType.Enter -> showAmount() + // TODO staking [REDACTED_TASK_KEY] support solana multisize hashes signing + StakingActionCommonType.Exit -> if (isSolana(stateController.value.cryptoCurrencyNetworkId)) { + showConfirmation() + } else { + showAmount() + } StakingActionCommonType.Pending.Other, - StakingActionCommonType.Exit, StakingActionCommonType.Pending.Rewards, -> showConfirmation() StakingActionCommonType.Pending.Restake -> showRestakeValidators() diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt index 0613d78e25..470048621d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt @@ -29,6 +29,7 @@ internal data class StakingUiState( val walletName: String, val cryptoCurrencyName: String, val cryptoCurrencySymbol: String, + val cryptoCurrencyNetworkId: String, val currentStep: StakingStep, val initialInfoState: StakingStates.InitialInfoState, val amountState: AmountState, @@ -40,6 +41,7 @@ internal data class StakingUiState( val actionType: StakingActionCommonType, val buttonsState: NavigationButtonsState, val event: StateEvent, + val balanceState: BalanceState?, ) { fun copyWrapped( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt index 3268482b57..8051fb9e54 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt @@ -47,11 +47,12 @@ internal class BalanceItemConverter( subtitle = getSubtitle(value), type = value.type, cryptoValue = cryptoAmount.parseBigDecimal(cryptoCurrency.decimals), - cryptoDecimal = cryptoAmount, - cryptoAmount = stringReference( + cryptoAmount = cryptoAmount, + formattedCryptoAmount = stringReference( cryptoAmount.format { crypto(cryptoCurrency) }, ), - fiatAmount = stringReference( + fiatAmount = fiatAmount, + formattedFiatAmount = stringReference( BigDecimalFormatter.formatFiatAmount( fiatAmount = fiatAmount, fiatCurrencyCode = appCurrency.code, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt index b03ba279ed..b151140d55 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt @@ -71,7 +71,7 @@ internal class RewardsValidatorStateConverter( crypto(cryptoCurrency) }, ) - val fiatAmount = stringReference( + val formattedFiatAmount = stringReference( BigDecimalFormatter.formatFiatAmount( fiatAmount = fiatValue, fiatCurrencyCode = appCurrency.code, @@ -85,9 +85,10 @@ internal class RewardsValidatorStateConverter( title = stringReference(this.name), subtitle = null, cryptoValue = cryptoValue.parseBigDecimal(cryptoCurrency.decimals), - cryptoDecimal = cryptoValue, - cryptoAmount = cryptoAmount, - fiatAmount = fiatAmount, + cryptoAmount = cryptoValue, + formattedCryptoAmount = cryptoAmount, + fiatAmount = fiatValue, + formattedFiatAmount = formattedFiatAmount, rawCurrencyId = cryptoCurrency.id.rawCurrencyId, pendingActions = balance.pendingActions.toPersistentList(), isClickable = true, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt index cb9490bdc8..29ccbc1d29 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt @@ -63,7 +63,7 @@ internal class YieldBalancesConverter( private fun List.mapBalances() = asSequence() .filterNot { it.amount.isZero() || it.type == BalanceType.REWARDS } .mapNotNull(balanceItemConverter::convert) - .sortedByDescending { it.cryptoDecimal } + .sortedByDescending { it.cryptoAmount } .sortedBy { it.type.order } .toPersistentList() diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt index 207436cf09..9167845687 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt @@ -20,7 +20,7 @@ import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.features.staking.impl.presentation.state.StakingStateController import com.tangem.features.staking.impl.presentation.state.StakingStates -import com.tangem.features.staking.impl.presentation.state.utils.isComposePendingActions +import com.tangem.features.staking.impl.presentation.state.utils.isCompositePendingActions import com.tangem.utils.extensions.orZero import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -95,7 +95,11 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor( val sourceAddress = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value ?: error("No available address") - val gasEstimate = if (isComposePendingActions(cryptoCurrencyStatus.currency.network.id.value, pendingActions)) { + val gasEstimate = if (isCompositePendingActions( + networkId = cryptoCurrencyStatus.currency.network.id.value, + pendingActions = pendingActions, + ) + ) { val result = coroutineScope { pendingActions?.map { action -> async { diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt index 3a7bacaf46..3ccad868cc 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt @@ -20,7 +20,7 @@ import com.tangem.domain.utils.convertToSdkAmount import com.tangem.domain.wallets.models.UserWallet import com.tangem.features.staking.impl.presentation.state.* import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount -import com.tangem.features.staking.impl.presentation.state.utils.isComposePendingActions +import com.tangem.features.staking.impl.presentation.state.utils.isCompositePendingActions import com.tangem.utils.extensions.orZero import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -96,7 +96,7 @@ internal class StakingTransactionSender @AssistedInject constructor( confirmationState: StakingStates.ConfirmationState.Data, onConstructError: (StakingError) -> Unit, ) = coroutineScope { - val isComposePendingActions = isComposePendingActions( + val isComposePendingActions = isCompositePendingActions( cryptoCurrencyStatus.currency.network.id.value, confirmationState.pendingActions, ) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt index 4d3dc0ad83..293ba68c01 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt @@ -73,9 +73,10 @@ internal object InitialStakingStatePreview { groupId = "groupId", title = stringReference("Binance"), cryptoValue = "100", - cryptoAmount = stringReference("100 SOL"), - cryptoDecimal = "100".toBigDecimal(), - fiatAmount = stringReference("100 $"), + formattedCryptoAmount = stringReference("100 SOL"), + cryptoAmount = "100".toBigDecimal(), + fiatAmount = null, + formattedFiatAmount = stringReference("100 $"), rawCurrencyId = null, validator = Yield.Validator( address = "address", diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt index 9da7141f5a..514a94fc76 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt @@ -26,7 +26,7 @@ internal object StakingClickIntentsStub : StakingClickIntents { override fun onInfoClick(infoType: InfoType) {} - override fun onEnterClick() {} + override fun onAmountEnterClick() {} override fun onAmountValueChange(value: String) {} diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetAmountDataTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetAmountDataTransformer.kt new file mode 100644 index 0000000000..434b40908c --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetAmountDataTransformer.kt @@ -0,0 +1,55 @@ +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.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.staking.impl.R +import com.tangem.features.staking.impl.presentation.state.* +import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents +import com.tangem.utils.Provider +import com.tangem.utils.transformer.Transformer + +internal class SetAmountDataTransformer( + private val clickIntents: StakingClickIntents, + private val cryptoCurrencyStatusProvider: Provider, + private val userWalletProvider: Provider, + private val appCurrencyProvider: Provider, + private val maxEnterAmountProvider: Provider, +) : Transformer { + + private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter) + + private val amountStateConverter by lazy(LazyThreadSafetyMode.NONE) { + AmountStateConverter( + clickIntents = clickIntents, + cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, + appCurrencyProvider = appCurrencyProvider, + iconStateConverter = iconStateConverter, + maxEnterAmountProvider = maxEnterAmountProvider, + ) + } + + override fun transform(prevState: StakingUiState): StakingUiState { + val title = if (prevState.actionType == StakingActionCommonType.Exit) { + resourceReference(R.string.staking_staked_amount) + } else { + stringReference(userWalletProvider().name) + } + + return prevState.copy( + amountState = amountStateConverter.convert( + AmountParameters( + title = title, + value = "", + ), + ), + ) + } +} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt index 5d7d0260e8..e989a47670 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt @@ -148,7 +148,7 @@ internal class SetButtonsStateTransformer( StakingStep.Validators, StakingStep.RestakeValidator, -> clickIntents.onNextClick() - StakingStep.Amount -> clickIntents.onEnterClick() + StakingStep.Amount -> clickIntents.onAmountEnterClick() StakingStep.Confirmation -> onConfirmationClick() StakingStep.RewardsValidators -> Unit } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateEmptyTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateEmptyTransformer.kt index 84cd59a951..4bf8d5ce5d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateEmptyTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateEmptyTransformer.kt @@ -11,6 +11,7 @@ internal object SetConfirmationStateEmptyTransformer : Transformer? = null, private val pendingAction: PendingAction? = pendingActions?.firstOrNull(), + ) : Transformer { private val networkId get() = cryptoCurrencyStatus.currency.network.id.value private val isComposePendingActions - get() = isComposePendingActions(networkId, pendingActions) + get() = isCompositePendingActions(networkId, pendingActions) private val isTronStakedBalance get() = isTronStakedBalance(networkId, pendingAction) - private val isExit: Boolean + private val isImplicitExit: Boolean get() = pendingAction == null && pendingActions?.isEmpty() == true || isTronStakedBalance override fun transform(prevState: StakingUiState): StakingUiState { val actionType = when { isEnter -> StakingActionCommonType.Enter - isExit -> StakingActionCommonType.Exit + isImplicitExit || isExplicitExit -> StakingActionCommonType.Exit else -> when (pendingAction?.type) { StakingActionType.STAKE -> StakingActionCommonType.Enter StakingActionType.UNSTAKE -> StakingActionCommonType.Exit @@ -54,6 +57,7 @@ internal class SetConfirmationStateInitTransformer( return prevState.copy( actionType = actionType, + balanceState = balanceState, confirmationState = StakingStates.ConfirmationState.Data( isPrimaryButtonEnabled = false, innerState = InnerConfirmationStakingState.ASSENT, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index 9689522cd7..e4cc55d35c 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -2,7 +2,9 @@ package com.tangem.features.staking.impl.presentation.state.transformers 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.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.components.list.RoundedListWithDividersItemData import com.tangem.core.ui.extensions.* @@ -39,6 +41,7 @@ internal class SetInitialDataStateTransformer( private val userWalletProvider: Provider, private val appCurrencyProvider: Provider, private val balancesToShowProvider: Provider>, + private val maxEnterAmountProvider: Provider, ) : Transformer { private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter) @@ -48,8 +51,8 @@ internal class SetInitialDataStateTransformer( clickIntents = clickIntents, cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, appCurrencyProvider = appCurrencyProvider, - userWalletProvider = userWalletProvider, iconStateConverter = iconStateConverter, + maxEnterAmountProvider = maxEnterAmountProvider, ) } @@ -72,6 +75,7 @@ internal class SetInitialDataStateTransformer( title = TextReference.EMPTY, cryptoCurrencyName = cryptoCurrency.name, cryptoCurrencySymbol = cryptoCurrency.symbol, + cryptoCurrencyNetworkId = cryptoCurrency.network.id.value, clickIntents = clickIntents, currentStep = StakingStep.InitialInfo, initialInfoState = createInitialInfoState(), @@ -207,7 +211,12 @@ internal class SetInitialDataStateTransformer( } private fun createInitialAmountState(): AmountState { - return amountStateConverter.convert("") + return amountStateConverter.convert( + AmountParameters( + title = stringReference(userWalletProvider().name), + value = "", + ), + ) } private fun getAprRange(validators: List): TextReference { diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt index f91d878456..cd74d47116 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt @@ -1,7 +1,10 @@ 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.domain.staking.model.stakekit.Yield +import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.staking.impl.presentation.state.StakingUiState import com.tangem.utils.transformer.Transformer @@ -12,11 +15,21 @@ internal class AmountChangeStateTransformer( private val yield: Yield, ) : Transformer { + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun transform(prevState: StakingUiState): StakingUiState { - val updatedAmountState = AmountFieldChangeTransformer( - cryptoCurrencyStatus, - value, - ).transform(prevState.amountState) + val actionType = prevState.actionType + val maxEnterAmount = if (actionType == StakingActionCommonType.Exit) { + MaxEnterAmount( + amount = prevState.balanceState?.cryptoAmount, + fiatAmount = prevState.balanceState?.fiatAmount, + fiatRate = cryptoCurrencyStatus.value.fiatRate, + ) + } else { + maxEnterAmountConverter.convert(cryptoCurrencyStatus) + } + + val updatedAmountState = AmountFieldChangeTransformer(maxEnterAmount, value).transform(prevState.amountState) return prevState.copy( amountState = AmountRequirementStateTransformer( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt index 088528794d..034398c337 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt @@ -1,18 +1,35 @@ package com.tangem.features.staking.impl.presentation.state.transformers.amount -import com.tangem.common.ui.amountScreen.converters.field.AmountFieldMaxAmountTransformer +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.domain.staking.model.stakekit.Yield +import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.staking.impl.presentation.state.StakingUiState import com.tangem.utils.transformer.Transformer internal class AmountMaxValueStateTransformer( private val cryptoCurrencyStatus: CryptoCurrencyStatus, + private val actionType: StakingActionCommonType, private val yield: Yield, ) : Transformer { + private val maxEnterAmountConverter = MaxEnterAmountConverter() + override fun transform(prevState: StakingUiState): StakingUiState { - val updatedAmountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatus).transform(prevState.amountState) + val maxEnterAmount = if (actionType == StakingActionCommonType.Exit) { + MaxEnterAmount( + amount = prevState.balanceState?.cryptoAmount, + fiatAmount = prevState.balanceState?.fiatAmount, + fiatRate = cryptoCurrencyStatus.value.fiatRate, + ) + } else { + maxEnterAmountConverter.convert(cryptoCurrencyStatus) + } + + val updatedAmountState = AmountFieldSetMaxAmountTransformer(maxEnterAmount) + .transform(prevState.amountState) return prevState.copy( amountState = AmountRequirementStateTransformer( cryptoCurrencyStatus = cryptoCurrencyStatus, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt index 88ac2c09f5..199707ada1 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt @@ -61,10 +61,17 @@ internal class AmountRequirementStateTransformer( }, ), ) - isIntegerOnlyError -> resourceReference( - R.string.staking_amount_tron_integer_error, - wrappedList(value), - ) + isIntegerOnlyError -> when (actionType) { + StakingActionCommonType.Enter -> resourceReference( + R.string.staking_amount_tron_integer_error, + wrappedList(value), + ) + StakingActionCommonType.Exit -> resourceReference( + R.string.staking_amount_tron_integer_error_unstaking, + wrappedList(value), + ) + else -> TODO() + } else -> TextReference.EMPTY } val isError = amountState.amountTextField.isError || isRequirementError @@ -101,12 +108,12 @@ internal class AmountRequirementStateTransformer( private fun isIntegerOnlyError(amountState: AmountState.Data, actionType: StakingActionCommonType): Boolean { val cryptoAmountValue = amountState.amountTextField.cryptoAmount.value ?: return false - val isEnter = actionType == StakingActionCommonType.Enter + val isEnterOrExit = actionType == StakingActionCommonType.Enter || actionType == StakingActionCommonType.Exit val isTron = isTron(cryptoCurrencyStatus.currency.network.id.value) val isIntegerOnly = cryptoAmountValue.isZero() || cryptoAmountValue.remainder(BigDecimal.ONE).isZero() - return isEnter && isTron && !isIntegerOnly + return isEnterOrExit && isTron && !isIntegerOnly } data class Data( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt index 2a8113944f..558aa4252e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/utils/StakingPendingActionUtils.kt @@ -35,12 +35,12 @@ internal fun StakingActionType?.getPendingActionTitle(): TextReference = when (t internal fun isSingleAction(networkId: String, activeStake: BalanceState): Boolean { val isSingleAction = activeStake.pendingActions.size <= 1 // Either single or none pending actions - val isComposePendingActions = isComposePendingActions(networkId, activeStake.pendingActions) + val isCompositePendingActions = isCompositePendingActions(networkId, activeStake.pendingActions) val isBscRestake = isBSC(networkId) && activeStake.pendingActions.any { it.type == StakingActionType.RESTAKE } - return isSingleAction && !isBscRestake || isComposePendingActions + return isSingleAction && !isBscRestake || isCompositePendingActions } internal fun withStubUnstakeAction(networkId: String, activeStake: BalanceState) = if (isBSC(networkId)) { @@ -59,7 +59,7 @@ internal fun isTronStakedBalance(networkId: String, pendingAction: PendingAction return isTron(networkId) && pendingAction?.type == StakingActionType.REVOTE } -internal fun isComposePendingActions(networkId: String, pendingActions: ImmutableList?): Boolean { +internal fun isCompositePendingActions(networkId: String, pendingActions: ImmutableList?): Boolean { return when { isSolana(networkId) -> pendingActions?.any { it.type == StakingActionType.WITHDRAW } == true else -> false diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt index faaf8c499c..180306b99e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt @@ -47,8 +47,8 @@ internal fun StakingClaimRewardsValidatorContent( ) }, ), - infoTitle = item.fiatAmount, - infoSubtitle = item.cryptoAmount, + infoTitle = item.formattedFiatAmount, + infoSubtitle = item.formattedCryptoAmount, imageUrl = item.validator?.image.orEmpty(), onImageError = { ValidatorImagePlaceholder() }, modifier = modifier diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 2895d3619c..d0d364184d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -270,8 +270,8 @@ private fun ActiveStakingBlock( InputRowImageInfo( subtitle = balance.title, caption = balance.subtitle ?: balance.getAprText(), - infoTitle = balance.fiatAmount.orMaskWithStars(isBalanceHidden), - infoSubtitle = balance.cryptoAmount.orMaskWithStars(isBalanceHidden), + infoTitle = balance.formattedFiatAmount.orMaskWithStars(isBalanceHidden), + infoSubtitle = balance.formattedCryptoAmount.orMaskWithStars(isBalanceHidden), imageUrl = balance.getImage(), iconRes = icon, iconTint = iconTint, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt index 7e23d53fc6..1b4d3eeee4 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt @@ -26,7 +26,7 @@ internal interface StakingClickIntents : AmountScreenClickIntents { fun onInfoClick(infoType: InfoType) - fun onEnterClick() + fun onAmountEnterClick() fun getFee() diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index 998261a393..a15947fe0e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -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.MaxEnterAmount 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 @@ -31,10 +32,6 @@ import com.tangem.domain.staking.InvalidatePendingTransactionsUseCase import com.tangem.domain.staking.IsAnyTokenStakedUseCase import com.tangem.domain.staking.IsApproveNeededUseCase import com.tangem.domain.staking.model.StakingApproval -import com.tangem.domain.staking.model.stakekit.BalanceItem -import com.tangem.domain.staking.model.stakekit.PendingAction -import com.tangem.domain.staking.model.stakekit.Yield -import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.staking.model.stakekit.action.StakingAction import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction @@ -52,6 +49,7 @@ import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.staking.analytics.StakeScreenSource import com.tangem.domain.staking.analytics.StakingAnalyticsEvent +import com.tangem.domain.staking.model.stakekit.* import com.tangem.features.staking.impl.analytics.StakingParamsInterceptor import com.tangem.features.staking.impl.analytics.utils.StakingAnalyticSender import com.tangem.features.staking.impl.navigation.InnerStakingRouter @@ -156,6 +154,14 @@ internal class StakingViewModel @Inject constructor( ).getOrElse { emptyList() } } + private val maxEnterAmount: MaxEnterAmount + get() = + MaxEnterAmount( + amount = uiState.value.balanceState?.cryptoAmount, + fiatAmount = uiState.value.balanceState?.fiatAmount, + fiatRate = cryptoCurrencyStatus.value.fiatRate, + ) + private var isInitialInfoAnalyticSent: Boolean = false private val balanceUpdater by lazy(LazyThreadSafetyMode.NONE) { @@ -227,6 +233,18 @@ internal class StakingViewModel @Inject constructor( } override fun onNextClick(balanceState: BalanceState?) { + if (value.currentStep == StakingStep.InitialInfo && balanceState == null) { + stateController.update( + SetConfirmationStateInitTransformer( + isEnter = true, + isExplicitExit = false, + balanceState = null, + cryptoCurrencyStatus = cryptoCurrencyStatus, + stakingApproval = stakingApproval, + stakingAllowance = stakingAllowance, + ), + ) + } stakingStateRouter.onNextClick() } @@ -350,24 +368,20 @@ internal class StakingViewModel @Inject constructor( ) } - override fun onEnterClick() { + override fun onAmountEnterClick() { if (yield.preferredValidators.isEmpty()) { stateController.updateEvent( StakingEvent.ShowAlert(StakingAlertUM.NoAvailableValidators), ) } else { - stateController.updateAll( - SetConfirmationStateInitTransformer( - isEnter = true, - cryptoCurrencyStatus = cryptoCurrencyStatus, - stakingApproval = stakingApproval, - stakingAllowance = stakingAllowance, - ), - ValidatorSelectChangeTransformer( - selectedValidator = null, - yield = yield, - ), - ) + if (uiState.value.actionType == StakingActionCommonType.Enter) { + stateController.updateAll( + ValidatorSelectChangeTransformer( + selectedValidator = null, + yield = yield, + ), + ) + } onNextClick() } } @@ -382,7 +396,13 @@ internal class StakingViewModel @Inject constructor( override fun onMaxValueClick() { analyticsEventHandler.send(StakingAnalyticsEvent.ButtonMax) - stateController.update(AmountMaxValueStateTransformer(cryptoCurrencyStatus, yield)) + stateController.update( + AmountMaxValueStateTransformer( + cryptoCurrencyStatus = cryptoCurrencyStatus, + actionType = uiState.value.actionType, + yield = yield, + ), + ) } override fun onCurrencyChangeClick(isFiat: Boolean) { @@ -439,23 +459,27 @@ internal class StakingViewModel @Inject constructor( val networkId = cryptoCurrencyStatus.currency.network.id.value if (isSingleAction(networkId, activeStake)) { prepareForConfirmation( + balanceType = activeStake.type, pendingActions = activeStake.pendingActions, + balanceState = activeStake, validator = activeStake.validator, amountValue = activeStake.cryptoValue, ) - onNextClick(balanceState = activeStake) + onNextClick(activeStake) } else { stateController.update( ShowActionSelectorBottomSheetTransformer( pendingActions = withStubUnstakeAction(networkId, activeStake), onActionSelect = { action -> prepareForConfirmation( + balanceType = activeStake.type, pendingAction = action, + balanceState = activeStake, validator = activeStake.validator, amountValue = activeStake.cryptoValue, ) stateController.update(DismissBottomSheetStateTransformer) - onNextClick(balanceState = activeStake) + onNextClick(activeStake) }, onDismiss = { stateController.update(DismissBottomSheetStateTransformer) }, ), @@ -889,12 +913,15 @@ internal class StakingViewModel @Inject constructor( userWalletProvider = Provider { userWallet }, appCurrencyProvider = Provider { appCurrency }, balancesToShowProvider = Provider { balancesToShow }, + maxEnterAmountProvider = Provider { maxEnterAmount }, ), SetConfirmationStateEmptyTransformer, ) } private fun prepareForConfirmation( + balanceType: BalanceType, + balanceState: BalanceState, pendingActions: ImmutableList = persistentListOf(), pendingAction: PendingAction? = pendingActions.firstOrNull(), validator: Yield.Validator?, @@ -903,6 +930,8 @@ internal class StakingViewModel @Inject constructor( stateController.updateAll( SetConfirmationStateInitTransformer( isEnter = false, + isExplicitExit = balanceType == BalanceType.STAKED, + balanceState = balanceState, cryptoCurrencyStatus = cryptoCurrencyStatus, stakingApproval = stakingApproval, pendingActions = pendingActions, @@ -913,6 +942,13 @@ internal class StakingViewModel @Inject constructor( selectedValidator = validator, yield = yield, ), + SetAmountDataTransformer( + clickIntents = this, + cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, + userWalletProvider = Provider { userWallet }, + appCurrencyProvider = Provider { appCurrency }, + maxEnterAmountProvider = Provider { maxEnterAmount }, + ), AmountChangeStateTransformer( cryptoCurrencyStatus = cryptoCurrencyStatus, value = amountValue,