diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 46365c5cc0..a0beef5668 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -735,6 +735,7 @@
Staking is currently unavailable due to network conditions. Please try again later.
Staking in the %1$s network with a new validator will automatically transfer all previously staked funds to this validator
Reinvests your earned rewards in your staked amount, increasing potential earnings.
+ Restake lets you move your funds from one validator to another without the need to unstake
Unlock your money to withdraw it from staking process. Unlocking takes %s.
Your funds will be available for use after the 21-day unbonding period. Reward will be withdrawn along with your unstaking funds.
Your funds will be available for use after the %s unbonding period.
diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt
index c3161be225..729477a5cc 100644
--- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt
+++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt
@@ -151,7 +151,7 @@ internal class DefaultStakingRepository(
val yield = getYield(cryptoCurrencyId, symbol)
StakingEntryInfo(
- apr = requireNotNull(yield.validators.maxByOrNull { it.apr.orZero() }?.apr),
+ apr = requireNotNull(yield.preferredValidators.maxByOrNull { it.apr.orZero() }?.apr),
rewardSchedule = yield.metadata.rewardSchedule,
tokenSymbol = yield.token.symbol,
)
@@ -207,23 +207,21 @@ internal class DefaultStakingRepository(
): StakingAction {
return withContext(dispatchers.io) {
val response = when (params.actionCommonType) {
- StakingActionCommonType.ENTER -> stakeKitApi.createEnterAction(
+ StakingActionCommonType.Enter -> stakeKitApi.createEnterAction(
createActionRequestBody(
userWalletId,
network,
params,
),
)
- StakingActionCommonType.EXIT -> stakeKitApi.createExitAction(
+ StakingActionCommonType.Exit -> stakeKitApi.createExitAction(
createActionRequestBody(
userWalletId,
network,
params,
),
)
- StakingActionCommonType.PENDING_OTHER,
- StakingActionCommonType.PENDING_REWARDS,
- -> stakeKitApi.createPendingAction(
+ is StakingActionCommonType.Pending -> stakeKitApi.createPendingAction(
createPendingActionRequestBody(params),
)
}
@@ -239,23 +237,21 @@ internal class DefaultStakingRepository(
): StakingGasEstimate {
return withContext(dispatchers.io) {
val gasEstimateDTO = when (params.actionCommonType) {
- StakingActionCommonType.ENTER -> stakeKitApi.estimateGasOnEnter(
+ StakingActionCommonType.Enter -> stakeKitApi.estimateGasOnEnter(
createActionRequestBody(
userWalletId,
network,
params,
),
)
- StakingActionCommonType.EXIT -> stakeKitApi.estimateGasOnExit(
+ StakingActionCommonType.Exit -> stakeKitApi.estimateGasOnExit(
createActionRequestBody(
userWalletId,
network,
params,
),
)
- StakingActionCommonType.PENDING_REWARDS,
- StakingActionCommonType.PENDING_OTHER,
- -> stakeKitApi.estimateGasOnPending(
+ is StakingActionCommonType.Pending -> stakeKitApi.estimateGasOnPending(
createPendingActionRequestBody(params),
)
}
diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt
index a2a0a6b7fe..9f201fb81e 100644
--- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt
+++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt
@@ -18,6 +18,11 @@ data class Yield(
val isAvailable: Boolean,
) {
+ val preferredValidators: List
+ get() = validators.filter { it.preferred }
+
+ fun getCurrentToken(rawCurrencyId: String?) = tokens.firstOrNull { rawCurrencyId == it.coinGeckoId } ?: token
+
@Serializable
data class Status(
val enter: Boolean,
@@ -130,8 +135,6 @@ data class Yield(
APR, // simple rate
UNKNOWN,
}
-
- fun getCurrentToken(rawCurrencyId: String?) = tokens.firstOrNull { rawCurrencyId == it.coinGeckoId } ?: token
}
@Serializable
diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionCommonType.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionCommonType.kt
index 5a59ba211c..0e2d7abe32 100644
--- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionCommonType.kt
+++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/action/StakingActionCommonType.kt
@@ -1,8 +1,12 @@
package com.tangem.domain.staking.model.stakekit.action
-enum class StakingActionCommonType {
- ENTER,
- EXIT,
- PENDING_REWARDS,
- PENDING_OTHER,
+sealed class StakingActionCommonType {
+
+ data object Enter : StakingActionCommonType()
+ data object Exit : StakingActionCommonType()
+ sealed class Pending : StakingActionCommonType() {
+ data object Restake : Pending()
+ data object Rewards : Pending()
+ data object Other : Pending()
+ }
}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt
index 0b3f4fcd35..7fcb116702 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt
@@ -33,10 +33,10 @@ internal class StakingAnalyticSender(
fun confirmationScreen(value: StakingUiState) {
val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
- val validatorState = confirmationState?.validatorState as? ValidatorState.Content
+ val validatorState = value.validatorState as? StakingStates.ValidatorState.Data
val validatorName = validatorState?.chosenValidator?.name ?: return
- if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) return
+ if (confirmationState?.innerState == InnerConfirmationStakingState.COMPLETED) return
analyticsEventHandler.send(
StakingAnalyticsEvents.ConfirmationScreenOpened(
@@ -55,6 +55,7 @@ internal class StakingAnalyticSender(
StakingStep.Amount -> StakeScreenSource.Amount
StakingStep.Confirmation -> StakeScreenSource.Confirmation
StakingStep.Validators,
+ StakingStep.RestakeValidator,
StakingStep.RewardsValidators,
-> StakeScreenSource.Validators
},
@@ -78,8 +79,7 @@ internal class StakingAnalyticSender(
}
fun sendTransactionStakingAnalytics(value: StakingUiState) {
- val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
- val validatorState = confirmationState?.validatorState as? ValidatorState.Content
+ val validatorState = value.validatorState as? StakingStates.ValidatorState.Data
val validatorName = validatorState?.chosenValidator?.name ?: return
analyticsEventHandler.send(
@@ -102,8 +102,7 @@ internal class StakingAnalyticSender(
}
fun sendTransactionStakingClickedAnalytics(value: StakingUiState) {
- val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
- val validatorState = confirmationState?.validatorState as? ValidatorState.Content
+ val validatorState = value.validatorState as? StakingStates.ValidatorState.Data
val validatorName = validatorState?.chosenValidator?.name ?: return
analyticsEventHandler.send(
@@ -119,11 +118,9 @@ internal class StakingAnalyticSender(
val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
return when (value.actionType) {
- StakingActionCommonType.ENTER -> StakingActionType.STAKE
- StakingActionCommonType.EXIT -> StakingActionType.UNSTAKE
- StakingActionCommonType.PENDING_REWARDS,
- StakingActionCommonType.PENDING_OTHER,
- -> confirmationState?.pendingAction?.type ?: StakingActionType.UNKNOWN
+ StakingActionCommonType.Enter -> StakingActionType.STAKE
+ StakingActionCommonType.Exit -> StakingActionType.UNSTAKE
+ is StakingActionCommonType.Pending -> confirmationState?.pendingAction?.type ?: StakingActionType.UNKNOWN
}
}
}
\ No newline at end of file
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 0b04c60e11..dd8919a82c 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
@@ -45,6 +45,12 @@ internal class StakingStateController @Inject constructor(
mutableUiState.update(function = titleTransformer::transform)
}
+ fun updateAll(vararg transformer: Transformer) {
+ transformer.forEach { mutableUiState.update(function = it::transform) }
+ mutableUiState.update(function = buttonsTransformer::transform)
+ mutableUiState.update(function = titleTransformer::transform)
+ }
+
fun clear() {
mutableUiState.update { getInitialState() }
mutableUiState.update(function = buttonsTransformer::transform)
@@ -72,12 +78,13 @@ internal class StakingStateController @Inject constructor(
currentStep = StakingStep.InitialInfo,
initialInfoState = StakingStates.InitialInfoState.Empty(),
amountState = AmountState.Empty(),
+ validatorState = StakingStates.ValidatorState.Empty(),
rewardsValidatorsState = StakingStates.RewardsValidatorsState.Empty(),
confirmationState = StakingStates.ConfirmationState.Empty(),
isBalanceHidden = false,
event = consumedEvent(),
bottomSheetConfig = null,
- actionType = StakingActionCommonType.ENTER,
+ actionType = StakingActionCommonType.Enter,
buttonsState = NavigationButtonsState.Empty,
)
}
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 69cca72194..e0e42070ac 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
@@ -23,12 +23,14 @@ internal class StakingStateRouter(
fun onNextClick() {
when (stateController.value.currentStep) {
StakingStep.InitialInfo -> when (stateController.value.actionType) {
- StakingActionCommonType.ENTER -> showAmount()
- StakingActionCommonType.PENDING_OTHER,
- StakingActionCommonType.EXIT,
+ StakingActionCommonType.Enter -> showAmount()
+ StakingActionCommonType.Pending.Other,
+ StakingActionCommonType.Exit,
+ StakingActionCommonType.Pending.Rewards,
-> showConfirmation()
- StakingActionCommonType.PENDING_REWARDS -> showRewardsValidators()
+ StakingActionCommonType.Pending.Restake -> showRestakeValidators()
}
+ StakingStep.RestakeValidator,
StakingStep.RewardsValidators,
StakingStep.Validators,
StakingStep.Amount,
@@ -41,25 +43,31 @@ internal class StakingStateRouter(
val uiState = stateController.uiState.value
when (uiState.currentStep) {
StakingStep.InitialInfo -> onBackClick()
- StakingStep.Amount -> showInitial()
+ StakingStep.RestakeValidator,
+ StakingStep.RewardsValidators,
+ StakingStep.Amount,
+ -> showInitial()
StakingStep.Confirmation -> {
- if (uiState.actionType != StakingActionCommonType.ENTER) {
+ if (uiState.actionType != StakingActionCommonType.Enter) {
showInitial()
} else {
showAmount()
}
}
StakingStep.Validators -> showConfirmation()
- StakingStep.RewardsValidators -> showInitial()
}
}
+ fun showValidators() {
+ stateController.update { it.copy(currentStep = StakingStep.Validators) }
+ }
+
private fun showInitial() {
analyticSender.initialInfoScreen(stateController.value)
stateController.update { it.copy(currentStep = StakingStep.InitialInfo) }
}
- private fun showRewardsValidators() {
+ fun showRewardsValidators() {
analyticsEventsHandler.send(
StakingAnalyticsEvents.RewardScreenOpened(stateController.value.cryptoCurrencySymbol),
)
@@ -73,8 +81,8 @@ internal class StakingStateRouter(
stateController.update { it.copy(currentStep = StakingStep.Amount) }
}
- fun showValidators() {
- stateController.update { it.copy(currentStep = StakingStep.Validators) }
+ private fun showRestakeValidators() {
+ stateController.update { it.copy(currentStep = StakingStep.RestakeValidator) }
}
private fun showConfirmation() {
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 4bc8b84bda..56aa176637 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
@@ -11,6 +11,7 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.pullToRefresh.PullToRefreshConfig
import com.tangem.domain.staking.model.PendingTransaction
import com.tangem.domain.staking.model.stakekit.PendingAction
+import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType
import com.tangem.features.staking.impl.presentation.state.events.StakingEvent
@@ -34,6 +35,7 @@ internal data class StakingUiState(
val amountState: AmountState,
val rewardsValidatorsState: StakingStates.RewardsValidatorsState,
val confirmationState: StakingStates.ConfirmationState,
+ val validatorState: StakingStates.ValidatorState,
val isBalanceHidden: Boolean,
val bottomSheetConfig: TangemBottomSheetConfig?,
val actionType: StakingActionCommonType,
@@ -45,10 +47,12 @@ internal data class StakingUiState(
initialInfoState: StakingStates.InitialInfoState = this.initialInfoState,
amountState: AmountState = this.amountState,
confirmationState: StakingStates.ConfirmationState = this.confirmationState,
+ validatorState: StakingStates.ValidatorState = this.validatorState,
): StakingUiState = copy(
initialInfoState = initialInfoState,
amountState = amountState,
confirmationState = confirmationState,
+ validatorState = validatorState,
)
}
@@ -85,13 +89,30 @@ internal sealed class StakingStates {
) : RewardsValidatorsState()
}
+ sealed class ValidatorState : StakingStates() {
+ abstract val isClickable: Boolean
+
+ data class Data(
+ override val isPrimaryButtonEnabled: Boolean,
+ override val isClickable: Boolean,
+ val isVisibleOnConfirmation: Boolean,
+ val chosenValidator: Yield.Validator,
+ val activeValidator: Yield.Validator?,
+ val availableValidators: List,
+ ) : ValidatorState()
+
+ data class Empty(
+ override val isClickable: Boolean = false,
+ override val isPrimaryButtonEnabled: Boolean = false,
+ ) : ValidatorState()
+ }
+
/** Confirmation state */
sealed class ConfirmationState : StakingStates() {
data class Data(
override val isPrimaryButtonEnabled: Boolean,
val innerState: InnerConfirmationStakingState,
val feeState: FeeState,
- val validatorState: ValidatorState,
val pendingAction: PendingAction?,
val pendingActions: ImmutableList?,
val notifications: ImmutableList,
@@ -112,6 +133,7 @@ enum class StakingStep {
InitialInfo,
RewardsValidators,
Amount,
+ RestakeValidator,
Confirmation,
Validators,
}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/ValidatorState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/ValidatorState.kt
deleted file mode 100644
index 7871149443..0000000000
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/ValidatorState.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.tangem.features.staking.impl.presentation.state
-
-import androidx.compose.runtime.Immutable
-import com.tangem.domain.staking.model.stakekit.Yield
-
-@Immutable
-internal sealed class ValidatorState {
-
- abstract val isClickable: Boolean
-
- data class Content(
- override val isClickable: Boolean,
- val chosenValidator: Yield.Validator,
- val availableValidators: List,
- ) : ValidatorState()
-
- data object Loading : ValidatorState() {
- override val isClickable: Boolean
- get() = false
- }
-
- data object Error : ValidatorState() {
- override val isClickable: Boolean
- get() = false
- }
-
- fun copySealed(isClickable: Boolean): ValidatorState {
- return if (this is Content) {
- copy(isClickable = isClickable)
- } else {
- this
- }
- }
-}
\ No newline at end of file
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 33559d6211..2daa181826 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
@@ -22,8 +22,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.ValidatorState
-import com.tangem.features.staking.impl.presentation.state.utils.isSolanaWithdraw
+import com.tangem.features.staking.impl.presentation.state.utils.isComposePendingActions
import com.tangem.utils.extensions.orZero
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -48,8 +47,6 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor(
) {
suspend fun getFee(
- pendingAction: PendingAction?,
- pendingActions: ImmutableList?,
onStakingFee: (Fee) -> Unit,
onStakingFeeError: (StakingError) -> Unit,
onApprovalFee: (TransactionFee) -> Unit,
@@ -57,17 +54,20 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor(
) {
val state = stateController.value
val confirmationState = state.confirmationState as? StakingStates.ConfirmationState.Data
- ?: error("No confirmation state")
- val validatorState = confirmationState.validatorState as? ValidatorState.Content
+ ?: error("Illegal state")
+ val validatorState = state.validatorState as? StakingStates.ValidatorState.Data
?: error("No validator provided")
val amount = (state.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value
?: error("No amount provided")
+ val pendingAction = confirmationState.pendingAction
+ val pendingActions = confirmationState.pendingActions
+
val validatorAddress = validatorState.chosenValidator.address
val approval = stakingApproval as? StakingApproval.Needed
- if (approval != null && state.actionType == StakingActionCommonType.ENTER) {
+ if (approval != null && state.actionType == StakingActionCommonType.Enter) {
val allowance = getAllowanceUseCase(
userWalletId = userWallet.walletId,
cryptoCurrency = cryptoCurrencyStatus.currency,
@@ -114,7 +114,7 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor(
val sourceAddress = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
?: error("No available address")
- val gasEstimate = if (isSolanaWithdraw(cryptoCurrencyStatus.currency.network.id.value, pendingActions)) {
+ val gasEstimate = if (isComposePendingActions(cryptoCurrencyStatus.currency.network.id.value, 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 f334c448f4..90fc4e9295 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
@@ -21,9 +21,12 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.staking.impl.analytics.StakingAnalyticsEvents
-import com.tangem.features.staking.impl.presentation.state.*
+import com.tangem.features.staking.impl.presentation.state.FeeState
+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.StakingUiState
import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount
-import com.tangem.features.staking.impl.presentation.state.utils.isSolanaWithdraw
+import com.tangem.features.staking.impl.presentation.state.utils.isComposePendingActions
import com.tangem.utils.extensions.orZero
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -99,7 +102,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
}
private fun composePendingTransaction(confirmationState: StakingStates.ConfirmationState.Data): PendingTransaction {
- return confirmationState.possiblePendingTransaction ?: composeStakeTransaction(confirmationState)
+ return confirmationState.possiblePendingTransaction ?: composeStakeTransaction()
}
private suspend fun getStakingTransactions(
@@ -107,11 +110,11 @@ internal class StakingTransactionSender @AssistedInject constructor(
confirmationState: StakingStates.ConfirmationState.Data,
onConstructError: (StakingError) -> Unit,
) = coroutineScope {
- val isAllWithdrawAction = isSolanaWithdraw(
+ val isComposePendingActions = isComposePendingActions(
cryptoCurrencyStatus.currency.network.id.value,
confirmationState.pendingActions,
)
- if (isAllWithdrawAction) {
+ if (isComposePendingActions) {
confirmationState.pendingActions?.map { action ->
async {
getStakingTransaction(
@@ -172,7 +175,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
action: PendingAction? = confirmationState.pendingAction,
onConstructError: (StakingError) -> Unit,
): List {
- val validatorState = confirmationState.validatorState as? ValidatorState.Content
+ val validatorState = state.validatorState as? StakingStates.ValidatorState.Data
?: error("No validator provided")
val fee = (confirmationState.feeState as? FeeState.Content)?.fee
?: error("No fee provided")
@@ -278,7 +281,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
private fun getAmount(amountState: AmountState.Data, fee: Fee, reduceAmountBy: BigDecimal?): BigDecimal {
val amountValue = amountState.amountTextField.cryptoAmount.value ?: error("No amount value")
val feeValue = fee.amount.value ?: error("No fee value")
- val isEnterAction = stateController.value.actionType == StakingActionCommonType.ENTER
+ val isEnterAction = stateController.value.actionType == StakingActionCommonType.Enter
return checkAndCalculateSubtractedAmount(
isAmountSubtractAvailable = isAmountSubtractAvailable && isEnterAction,
@@ -289,7 +292,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
)
}
- private fun composeStakeTransaction(confirmationState: StakingStates.ConfirmationState.Data): PendingTransaction {
+ private fun composeStakeTransaction(): PendingTransaction {
val state = stateController.value
val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data
@@ -301,7 +304,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
type = BalanceType.STAKED,
amount = (state.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value ?: BigDecimal.ZERO,
rawCurrencyId = cryptoCurrencyStatus.currency.id.rawCurrencyId,
- validator = (confirmationState.validatorState as? ValidatorState.Content)?.chosenValidator,
+ validator = (state.validatorState as? StakingStates.ValidatorState.Data)?.chosenValidator,
balancesId = yieldBalance?.getBalancesUniqueId() ?: 0,
)
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt
index d9c7263d8e..016a6a0625 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt
@@ -7,8 +7,6 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.appcurrency.model.AppCurrency
-import com.tangem.domain.staking.model.stakekit.Yield
-import com.tangem.domain.staking.model.stakekit.Yield.Validator.ValidatorStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.*
import kotlinx.collections.immutable.persistentListOf
@@ -16,48 +14,6 @@ import java.math.BigDecimal
internal object ConfirmationStatePreviewData {
- private val validatorList = listOf(
- Yield.Validator(
- address = "0xa6e768fef2d1af36c0cfdb276422e7881a83e951",
- status = ValidatorStatus.ACTIVE,
- name = "Luganodes",
- image = "https://assets.stakek.it/validators/luganodes.png",
- apr = BigDecimal("0.054823398040640445"),
- commission = 0.1,
- stakedBalance = "355544384.45009977",
- website = "https://luganodes.com/",
- votingPower = 0.09778360195377911,
- preferred = true,
- isStrategicPartner = false,
- ),
- Yield.Validator(
- address = "0x35b1ca0f398905cf752e6fe122b51c88022fca32",
- status = ValidatorStatus.ACTIVE,
- name = "InfStones",
- image = "https://assets.stakek.it/validators/infstones.png",
- apr = BigDecimal("0.057786472172836965"),
- commission = 0.05,
- stakedBalance = "12495684.05643019",
- website = "https://infstones.com/",
- votingPower = 0.0034366257754399774,
- preferred = true,
- isStrategicPartner = false,
- ),
- Yield.Validator(
- address = "0xd14a87025109013b0a2354a775cb335f926af65a",
- status = ValidatorStatus.ACTIVE,
- name = "Kiln",
- image = "https://assets.stakek.it/validators/kiln.png",
- apr = BigDecimal("0.057786472172836965"),
- commission = 0.05,
- stakedBalance = "85400369.96393165",
- website = "https://infstones.com/",
- votingPower = 0.023487238579718264,
- preferred = true,
- isStrategicPartner = true,
- ),
- )
-
private val fee = Fee.Common(
amount = Amount(
currencySymbol = "MATIC",
@@ -77,11 +33,6 @@ internal object ConfirmationStatePreviewData {
isFeeApproximate = false,
isFeeConvertibleToFiat = true,
),
- validatorState = ValidatorState.Content(
- isClickable = true,
- chosenValidator = validatorList[0],
- availableValidators = validatorList,
- ),
footerText = stringReference("You stake \$715.11 and will be receiving ~\$35 monthly"),
notifications = persistentListOf(
StakingNotification.Info.EarnRewards(
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ValidatorStatePreviewData.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ValidatorStatePreviewData.kt
new file mode 100644
index 0000000000..225057c19c
--- /dev/null
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ValidatorStatePreviewData.kt
@@ -0,0 +1,60 @@
+package com.tangem.features.staking.impl.presentation.state.previewdata
+
+import com.tangem.domain.staking.model.stakekit.Yield
+import com.tangem.domain.staking.model.stakekit.Yield.Validator.ValidatorStatus
+import com.tangem.features.staking.impl.presentation.state.StakingStates
+import java.math.BigDecimal
+
+internal object ValidatorStatePreviewData {
+
+ private val validatorList = listOf(
+ Yield.Validator(
+ address = "0xa6e768fef2d1af36c0cfdb276422e7881a83e951",
+ status = ValidatorStatus.ACTIVE,
+ name = "Luganodes",
+ image = "https://assets.stakek.it/validators/luganodes.png",
+ apr = BigDecimal("0.054823398040640445"),
+ commission = 0.1,
+ stakedBalance = "355544384.45009977",
+ website = "https://luganodes.com/",
+ votingPower = 0.09778360195377911,
+ preferred = true,
+ isStrategicPartner = false,
+ ),
+ Yield.Validator(
+ address = "0x35b1ca0f398905cf752e6fe122b51c88022fca32",
+ status = ValidatorStatus.ACTIVE,
+ name = "InfStones",
+ image = "https://assets.stakek.it/validators/infstones.png",
+ apr = BigDecimal("0.057786472172836965"),
+ commission = 0.05,
+ stakedBalance = "12495684.05643019",
+ website = "https://infstones.com/",
+ votingPower = 0.0034366257754399774,
+ preferred = true,
+ isStrategicPartner = true,
+ ),
+ Yield.Validator(
+ address = "0xd14a87025109013b0a2354a775cb335f926af65a",
+ status = ValidatorStatus.ACTIVE,
+ name = "Kiln",
+ image = "https://assets.stakek.it/validators/kiln.png",
+ apr = BigDecimal("0.057786472172836965"),
+ commission = 0.05,
+ stakedBalance = "85400369.96393165",
+ website = "https://infstones.com/",
+ votingPower = 0.023487238579718264,
+ preferred = true,
+ isStrategicPartner = false,
+ ),
+ )
+
+ val validatorState = StakingStates.ValidatorState.Data(
+ availableValidators = validatorList,
+ chosenValidator = validatorList.first(),
+ isPrimaryButtonEnabled = true,
+ activeValidator = null,
+ isClickable = true,
+ isVisibleOnConfirmation = true,
+ )
+}
\ No newline at end of file
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 716cab0e93..9da7141f5a 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
@@ -2,14 +2,11 @@ package com.tangem.features.staking.impl.presentation.state.stub
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
import com.tangem.common.ui.notifications.NotificationUM
-import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.staking.model.stakekit.Yield
-import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
-import kotlinx.collections.immutable.ImmutableList
import java.math.BigDecimal
@Suppress("TooManyFunctions")
@@ -17,13 +14,7 @@ internal object StakingClickIntentsStub : StakingClickIntents {
override fun onBackClick() {}
- override fun onNextClick(
- actionTypeToOverwrite: StakingActionCommonType?,
- pendingAction: PendingAction?,
- pendingActions: ImmutableList?,
- balanceState: BalanceState?,
- ) {
- }
+ override fun onNextClick(balanceState: BalanceState?) {}
override fun onActionClick() {}
@@ -67,8 +58,7 @@ internal object StakingClickIntentsStub : StakingClickIntents {
override fun onActiveStake(activeStake: BalanceState) {}
- override fun getFee(pendingAction: PendingAction?, pendingActions: ImmutableList?) {
- }
+ override fun getFee() {}
override fun onAmountReduceByClick(
reduceAmountBy: BigDecimal,
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ActionTypeActiveStakeTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ActionTypeActiveStakeTransformer.kt
deleted file mode 100644
index 31e1f97f96..0000000000
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ActionTypeActiveStakeTransformer.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.tangem.features.staking.impl.presentation.state.transformers
-
-import com.tangem.domain.staking.model.stakekit.BalanceType
-import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
-import com.tangem.domain.tokens.model.CryptoCurrencyStatus
-import com.tangem.domain.tokens.model.Network
-import com.tangem.features.staking.impl.presentation.state.*
-import com.tangem.lib.crypto.BlockchainUtils.isTron
-import com.tangem.utils.transformer.Transformer
-
-internal class ActionTypeActiveStakeTransformer(
- private val cryptoCurrencyStatus: CryptoCurrencyStatus,
- private val activeStake: BalanceState,
-) : Transformer {
-
- override fun transform(prevState: StakingUiState): StakingUiState {
- val isTronStakedBalance = isTronStakedBalance(
- networkId = cryptoCurrencyStatus.currency.network.id,
- activeStake = activeStake,
- )
- val actionType = if (activeStake.pendingActions.isEmpty() || isTronStakedBalance) {
- StakingActionCommonType.EXIT
- } else {
- StakingActionCommonType.PENDING_OTHER
- }
-
- return prevState.copy(actionType = actionType)
- }
-
- private fun isTronStakedBalance(networkId: Network.ID, activeStake: BalanceState): Boolean {
- return isTron(networkId.value) && activeStake.type == BalanceType.STAKED
- }
-}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt
index c8066c1dc2..5c3bfbd6e0 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt
@@ -65,7 +65,7 @@ internal class AddStakingNotificationsTransformer(
val feeValue = feeState?.fee?.amount?.value.orZero()
val reduceAmountBy = confirmationState.reduceAmountBy.orZero()
- val isEnterAction = prevState.actionType == StakingActionCommonType.ENTER
+ val isEnterAction = prevState.actionType == StakingActionCommonType.Enter
val isFeeCoverage = checkFeeCoverage(
amountValue = amountValue,
feeValue = feeValue,
@@ -93,12 +93,7 @@ internal class AddStakingNotificationsTransformer(
prevState = prevState,
feeError = feeError,
sendingAmount = sendingAmount,
- onReload = {
- prevState.clickIntents.getFee(
- confirmationState.pendingAction,
- confirmationState.pendingActions,
- )
- },
+ onReload = prevState.clickIntents::getFee,
feeValue = feeValue,
)
// warnings
@@ -228,7 +223,7 @@ internal class AddStakingNotificationsTransformer(
val showNotification = sendingAmount + feeAmount > balance
if (showNotification) {
- val notification = if (actionType == StakingActionCommonType.ENTER) {
+ val notification = if (actionType == StakingActionCommonType.Enter) {
NotificationUM.Error.TotalExceedsBalance
} else {
with(cryptoCurrencyStatus.currency) {
@@ -249,9 +244,9 @@ internal class AddStakingNotificationsTransformer(
private fun MutableList.addInfoNotifications(prevState: StakingUiState) {
when (prevState.actionType) {
- StakingActionCommonType.EXIT -> addExitInfoNotifications()
- StakingActionCommonType.ENTER -> addEnterInfoNotifications()
- else -> addPendingInfoNotifications(prevState)
+ StakingActionCommonType.Enter -> addEnterInfoNotifications()
+ StakingActionCommonType.Exit -> addExitInfoNotifications()
+ is StakingActionCommonType.Pending -> addPendingInfoNotifications(prevState)
}
}
@@ -312,6 +307,10 @@ internal class AddStakingNotificationsTransformer(
resourceReference(R.string.staking_revote) to
resourceReference(R.string.staking_notifications_revote_tron_text)
}
+ StakingActionType.RESTAKE -> {
+ resourceReference(R.string.staking_restake) to
+ resourceReference(R.string.staking_notification_restake_text)
+ }
else -> null to null
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetActionToExecuteTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetActionToExecuteTransformer.kt
deleted file mode 100644
index e3adab9f50..0000000000
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetActionToExecuteTransformer.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.tangem.features.staking.impl.presentation.state.transformers
-
-import com.tangem.domain.staking.model.stakekit.PendingAction
-import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
-import com.tangem.features.staking.impl.presentation.state.StakingStates
-import com.tangem.features.staking.impl.presentation.state.StakingUiState
-import com.tangem.utils.transformer.Transformer
-import kotlinx.collections.immutable.ImmutableList
-
-internal class SetActionToExecuteTransformer(
- private val actionTypeToOverwrite: StakingActionCommonType,
- private val pendingAction: PendingAction?,
- private val pendingActions: ImmutableList?,
-) : Transformer {
- override fun transform(prevState: StakingUiState): StakingUiState {
- val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
- return prevState.copy(
- actionType = actionTypeToOverwrite,
- confirmationState = confirmationState?.copy(
- pendingAction = pendingAction,
- pendingActions = pendingActions,
- ) ?: StakingStates.ConfirmationState.Empty(),
- )
- }
-}
\ 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 52251d7408..c2761a0713 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
@@ -109,6 +109,7 @@ internal class SetButtonsStateTransformer(
StakingStep.Confirmation -> getConfirmationButtonText()
StakingStep.Validators -> resourceReference(R.string.common_continue)
StakingStep.Amount,
+ StakingStep.RestakeValidator,
StakingStep.RewardsValidators,
-> resourceReference(R.string.common_next)
}
@@ -120,17 +121,15 @@ internal class SetButtonsStateTransformer(
resourceReference(R.string.common_close)
} else {
when (actionType) {
- StakingActionCommonType.ENTER -> {
+ StakingActionCommonType.Enter -> {
if (confirmationState.isApprovalNeeded) {
resourceReference(R.string.give_permission_title)
} else {
resourceReference(R.string.common_stake)
}
}
- StakingActionCommonType.EXIT -> resourceReference(R.string.common_unstake)
- StakingActionCommonType.PENDING_OTHER,
- StakingActionCommonType.PENDING_REWARDS,
- -> confirmationState.pendingAction?.type.getPendingActionTitle()
+ StakingActionCommonType.Exit -> resourceReference(R.string.common_unstake)
+ is StakingActionCommonType.Pending -> confirmationState.pendingAction?.type.getPendingActionTitle()
}
}
} else {
@@ -140,18 +139,11 @@ internal class SetButtonsStateTransformer(
private fun StakingUiState.onPrimaryClick() {
when (currentStep) {
- StakingStep.InitialInfo -> clickIntents.onEnterClick()
- StakingStep.Validators -> {
- if (confirmationState is StakingStates.ConfirmationState.Data) {
- clickIntents.onNextClick(
- pendingActions = confirmationState.pendingActions,
- pendingAction = confirmationState.pendingAction,
- )
- } else {
- clickIntents.onNextClick()
- }
- }
- StakingStep.Amount -> clickIntents.onNextClick()
+ StakingStep.InitialInfo -> clickIntents.onNextClick()
+ StakingStep.Validators,
+ StakingStep.RestakeValidator,
+ -> clickIntents.onNextClick()
+ StakingStep.Amount -> clickIntents.onEnterClick()
StakingStep.Confirmation -> onConfirmationClick()
StakingStep.RewardsValidators -> Unit
}
@@ -162,7 +154,7 @@ internal class SetButtonsStateTransformer(
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
clickIntents.onNextClick()
} else {
- val isEnterAction = actionType == StakingActionCommonType.ENTER
+ val isEnterAction = actionType == StakingActionCommonType.Enter
val isApproveNeeded = confirmationState.isApprovalNeeded
if (isEnterAction && isApproveNeeded) {
@@ -179,6 +171,7 @@ internal class SetButtonsStateTransformer(
private fun StakingStep.isPrevButtonVisible(): Boolean = when (this) {
StakingStep.InitialInfo,
StakingStep.RewardsValidators,
+ StakingStep.RestakeValidator,
StakingStep.Confirmation,
StakingStep.Validators,
-> false
@@ -192,7 +185,9 @@ internal class SetButtonsStateTransformer(
StakingStep.Amount -> amountState.isPrimaryButtonEnabled
StakingStep.Confirmation -> confirmationState.isPrimaryButtonEnabled
StakingStep.RewardsValidators -> rewardsValidatorsState.isPrimaryButtonEnabled
- StakingStep.Validators -> true
+ StakingStep.RestakeValidator,
+ StakingStep.Validators,
+ -> true
}
}
}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt
index 196784785f..85443b4096 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt
@@ -2,22 +2,17 @@ package com.tangem.features.staking.impl.presentation.state.transformers
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.appcurrency.model.AppCurrency
-import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.presentation.state.FeeState
-import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState
import com.tangem.features.staking.impl.presentation.state.StakingStates
import com.tangem.features.staking.impl.presentation.state.StakingUiState
import com.tangem.utils.Provider
import com.tangem.utils.transformer.Transformer
-import kotlinx.collections.immutable.ImmutableList
internal class SetConfirmationStateAssentTransformer(
private val appCurrencyProvider: Provider,
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus?,
private val fee: Fee,
- private val action: PendingAction?,
- private val actions: ImmutableList?,
) : Transformer {
override fun transform(prevState: StakingUiState): StakingUiState {
@@ -30,7 +25,6 @@ internal class SetConfirmationStateAssentTransformer(
if (this is StakingStates.ConfirmationState.Data) {
val isFeeConvertibleToFiat = feeCryptoCurrencyStatus?.currency?.network?.hasFiatFeeRate == true
return copy(
- innerState = InnerConfirmationStakingState.ASSENT,
feeState = FeeState.Content(
fee = fee,
rate = feeCryptoCurrencyStatus?.value?.fiatRate,
@@ -38,11 +32,7 @@ internal class SetConfirmationStateAssentTransformer(
appCurrency = appCurrencyProvider(),
isFeeApproximate = false,
),
- validatorState = validatorState.copySealed(isClickable = true),
- pendingAction = action,
- pendingActions = actions,
isPrimaryButtonEnabled = true,
- isApprovalNeeded = false,
)
} else {
return this
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
index db27e0c2d9..4ecbf95344 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
@@ -16,11 +16,10 @@ internal class SetConfirmationStateCompletedTransformer(
}
private fun StakingStates.ConfirmationState.copyWrapped(): StakingStates.ConfirmationState {
- if (this is StakingStates.ConfirmationState.Data) {
- return copy(
+ return if (this is StakingStates.ConfirmationState.Data) {
+ copy(
isPrimaryButtonEnabled = true,
innerState = InnerConfirmationStakingState.COMPLETED,
- validatorState = validatorState.copySealed(isClickable = false),
footerText = TextReference.EMPTY,
notifications = persistentListOf(),
transactionDoneState = TransactionDoneState.Content(
@@ -29,7 +28,7 @@ internal class SetConfirmationStateCompletedTransformer(
),
)
} else {
- return this
+ this
}
}
}
\ No newline at end of file
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
new file mode 100644
index 0000000000..84cd59a951
--- /dev/null
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateEmptyTransformer.kt
@@ -0,0 +1,16 @@
+package com.tangem.features.staking.impl.presentation.state.transformers
+
+import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
+import com.tangem.features.staking.impl.presentation.state.StakingStates
+import com.tangem.features.staking.impl.presentation.state.StakingUiState
+import com.tangem.utils.transformer.Transformer
+
+internal object SetConfirmationStateEmptyTransformer : Transformer {
+ override fun transform(prevState: StakingUiState): StakingUiState {
+ return prevState.copy(
+ actionType = StakingActionCommonType.Enter,
+ validatorState = StakingStates.ValidatorState.Empty(),
+ confirmationState = StakingStates.ConfirmationState.Empty(),
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateInProgressTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateInProgressTransformer.kt
index 24bdd43c84..9043cc8ae9 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateInProgressTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateInProgressTransformer.kt
@@ -19,7 +19,6 @@ internal class SetConfirmationStateInProgressTransformer : 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)
+
+ private val isTronStakedBalance
+ get() = isTronStakedBalance(networkId, pendingAction)
+
+ private val isExit: Boolean
+ get() = pendingAction == null && pendingActions?.isEmpty() == true || isTronStakedBalance
+
+ override fun transform(prevState: StakingUiState): StakingUiState {
+ val actionType = when {
+ isEnter -> StakingActionCommonType.Enter
+ isExit -> StakingActionCommonType.Exit
+ else -> when (pendingAction?.type) {
+ StakingActionType.STAKE -> StakingActionCommonType.Enter
+ StakingActionType.UNSTAKE -> StakingActionCommonType.Exit
+ StakingActionType.CLAIM_REWARDS,
+ StakingActionType.RESTAKE_REWARDS,
+ -> StakingActionCommonType.Pending.Rewards
+ StakingActionType.VOTE_LOCKED,
+ StakingActionType.RESTAKE,
+ -> StakingActionCommonType.Pending.Restake
+ else -> StakingActionCommonType.Pending.Other
+ }
+ }
+
+ return prevState.copy(
+ actionType = actionType,
+ confirmationState = StakingStates.ConfirmationState.Data(
+ isPrimaryButtonEnabled = false,
+ innerState = InnerConfirmationStakingState.ASSENT,
+ feeState = FeeState.Loading,
+ notifications = persistentListOf(),
+ footerText = TextReference.EMPTY,
+ transactionDoneState = TransactionDoneState.Empty,
+ isApprovalNeeded = stakingApproval is StakingApproval.Needed,
+ reduceAmountBy = null,
+ pendingAction = pendingAction,
+ pendingActions = pendingActions.takeIf { isComposePendingActions },
+ possiblePendingTransaction = null,
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt
index e32fc821f9..dae491e1b8 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt
@@ -10,10 +10,11 @@ import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.features.staking.impl.R
-import com.tangem.features.staking.impl.presentation.state.*
+import com.tangem.features.staking.impl.presentation.state.FeeState
+import com.tangem.features.staking.impl.presentation.state.StakingStates
+import com.tangem.features.staking.impl.presentation.state.StakingUiState
import com.tangem.features.staking.impl.presentation.state.utils.getRewardSchedule
import com.tangem.utils.transformer.Transformer
-import kotlinx.collections.immutable.persistentListOf
internal class SetConfirmationStateLoadingTransformer(
private val yield: Yield,
@@ -22,39 +23,21 @@ internal class SetConfirmationStateLoadingTransformer(
) : Transformer {
override fun transform(prevState: StakingUiState): StakingUiState {
- val filteredValidators = yield.validators.filter {
- it.preferred
- }
val possibleConfirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
- val possibleValidatorState = possibleConfirmationState?.validatorState as? ValidatorState.Content
- val chosenValidator = possibleValidatorState?.chosenValidator ?: filteredValidators[0]
return prevState.copy(
- confirmationState = StakingStates.ConfirmationState.Data(
+ confirmationState = possibleConfirmationState?.copy(
isPrimaryButtonEnabled = false,
- innerState = InnerConfirmationStakingState.ASSENT,
feeState = FeeState.Loading,
- validatorState = ValidatorState.Content(
- isClickable = true,
- chosenValidator = chosenValidator,
- availableValidators = filteredValidators,
- ),
- notifications = persistentListOf(),
footerText = getFooter(prevState),
- transactionDoneState = TransactionDoneState.Empty,
- pendingAction = possibleConfirmationState?.pendingAction,
- pendingActions = possibleConfirmationState?.pendingActions,
- isApprovalNeeded = false,
- reduceAmountBy = null,
- possiblePendingTransaction = null,
- ),
+ ) ?: prevState.confirmationState,
)
}
private fun getFooter(state: StakingUiState): TextReference {
val amountState = state.amountState as? AmountState.Data
- val isEnterAction = state.actionType == StakingActionCommonType.ENTER
+ val isEnterAction = state.actionType == StakingActionCommonType.Enter
val amountDecimal = amountState?.amountTextField?.fiatAmount?.value
val amountValue = BigDecimalFormatter.formatFiatAmount(
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt
index ee866db72c..1c1c7103dc 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateResetAssentTransformer.kt
@@ -13,7 +13,6 @@ internal object SetConfirmationStateResetAssentTransformer : Transformer,
private val userWalletProvider: Provider,
@@ -76,7 +74,7 @@ internal class SetInitialDataStateTransformer(
currentStep = StakingStep.InitialInfo,
initialInfoState = createInitialInfoState(),
amountState = createInitialAmountState(),
- confirmationState = createInitialConfirmationState(),
+ confirmationState = StakingStates.ConfirmationState.Empty(),
rewardsValidatorsState = rewardsValidatorStateConverter.convert(Unit),
bottomSheetConfig = null,
)
@@ -87,7 +85,7 @@ internal class SetInitialDataStateTransformer(
return StakingStates.InitialInfoState.Data(
isPrimaryButtonEnabled = !cryptoCurrencyStatusProvider().value.amount.isNullOrZero(),
showBanner = !isAnyTokenStaked && yieldBalance == InnerYieldBalanceState.Empty,
- aprRange = getAprRange(yield.validators),
+ aprRange = getAprRange(yield.preferredValidators),
infoItems = getInfoItems(),
onInfoClick = clickIntents::onInfoClick,
yieldBalance = yieldBalance,
@@ -113,7 +111,7 @@ internal class SetInitialDataStateTransformer(
}
private fun createAnnualPercentageRateItem(): RoundedListWithDividersItemData {
- val validators = yield.validators
+ val validators = yield.preferredValidators
return RoundedListWithDividersItemData(
id = R.string.staking_details_annual_percentage_rate,
startText = TextReference.Res(R.string.staking_details_annual_percentage_rate),
@@ -214,23 +212,6 @@ internal class SetInitialDataStateTransformer(
return amountStateConverter.convert("")
}
- private fun createInitialConfirmationState(): StakingStates.ConfirmationState {
- return StakingStates.ConfirmationState.Data(
- isPrimaryButtonEnabled = false,
- innerState = InnerConfirmationStakingState.ASSENT,
- feeState = FeeState.Loading,
- validatorState = ValidatorState.Loading,
- notifications = persistentListOf(),
- footerText = TextReference.EMPTY,
- transactionDoneState = TransactionDoneState.Empty,
- pendingAction = null,
- pendingActions = null,
- isApprovalNeeded = isApprovalNeeded,
- reduceAmountBy = null,
- possiblePendingTransaction = null,
- )
- }
-
private fun getAprRange(validators: List): TextReference {
val aprValues = validators.mapNotNull { it.apr }
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetTitleTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetTitleTransformer.kt
index 578af70403..a29c1a8a85 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetTitleTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetTitleTransformer.kt
@@ -20,7 +20,9 @@ internal object SetTitleTransformer : Transformer {
val title = when (currentStep) {
StakingStep.Amount -> resourceReference(R.string.send_amount_label)
- StakingStep.Validators -> resourceReference(R.string.staking_validators)
+ StakingStep.RestakeValidator,
+ StakingStep.Validators,
+ -> resourceReference(R.string.staking_validators)
StakingStep.RewardsValidators -> resourceReference(R.string.common_claim_rewards)
StakingStep.InitialInfo -> resourceReference(
R.string.staking_title_stake,
@@ -29,11 +31,11 @@ internal object SetTitleTransformer : Transformer {
StakingStep.Confirmation -> {
when (actionType) {
- StakingActionCommonType.ENTER -> resourceReference(
+ StakingActionCommonType.Enter -> resourceReference(
R.string.staking_title_stake,
wrappedList(prevState.cryptoCurrencyName),
)
- StakingActionCommonType.EXIT -> resourceReference(
+ StakingActionCommonType.Exit -> resourceReference(
R.string.staking_title_unstake,
wrappedList(prevState.cryptoCurrencyName),
)
@@ -51,7 +53,7 @@ internal object SetTitleTransformer : Transformer {
}
}
- val subtitle = if (currentStep == StakingStep.Confirmation && actionType == StakingActionCommonType.ENTER) {
+ val subtitle = if (currentStep == StakingStep.Confirmation && actionType == StakingActionCommonType.Enter) {
stringReference(prevState.walletName)
} else {
null
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 d669d5a7e9..284f9b239b 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
@@ -102,7 +102,7 @@ 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 isEnter = actionType == StakingActionCommonType.Enter
val isTron = isTron(cryptoCurrencyStatus.currency.network.id.value)
val isIntegerOnly = cryptoAmountValue.isZero() || cryptoAmountValue.remainder(BigDecimal.ONE).isZero()
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetConfirmationStateAssentApprovalTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetConfirmationStateAssentApprovalTransformer.kt
index 939c6877dc..6f331795e4 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetConfirmationStateAssentApprovalTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetConfirmationStateAssentApprovalTransformer.kt
@@ -35,7 +35,6 @@ internal class SetConfirmationStateAssentApprovalTransformer(
appCurrency = appCurrencyProvider(),
isFeeApproximate = false,
),
- validatorState = validatorState.copySealed(isClickable = true),
isPrimaryButtonEnabled = true,
isApprovalNeeded = true,
)
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt
index b5631913ad..ca32d6c1be 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt
@@ -12,7 +12,6 @@ import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.FeeState
import com.tangem.features.staking.impl.presentation.state.StakingStates
import com.tangem.features.staking.impl.presentation.state.StakingUiState
-import com.tangem.features.staking.impl.presentation.state.ValidatorState
import com.tangem.utils.Provider
import com.tangem.utils.transformer.Transformer
@@ -28,7 +27,7 @@ internal class ShowApprovalBottomSheetTransformer(
val amountState = prevState.amountState as? AmountState.Data ?: return prevState
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data ?: return prevState
- val validatorState = confirmationState.validatorState as? ValidatorState.Content ?: return prevState
+ val validatorState = prevState.validatorState as? StakingStates.ValidatorState.Data ?: return prevState
val feeState = confirmationState.feeState as? FeeState.Content ?: return prevState
val fee = feeState.fee ?: return prevState
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/validator/ValidatorSelectChangeTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/validator/ValidatorSelectChangeTransformer.kt
index e6ba4e32db..0f79a3ab26 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/validator/ValidatorSelectChangeTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/validator/ValidatorSelectChangeTransformer.kt
@@ -1,29 +1,45 @@
package com.tangem.features.staking.impl.presentation.state.transformers.validator
import com.tangem.domain.staking.model.stakekit.Yield
+import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
+import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.features.staking.impl.presentation.state.StakingStates
+import com.tangem.features.staking.impl.presentation.state.StakingStep
import com.tangem.features.staking.impl.presentation.state.StakingUiState
-import com.tangem.features.staking.impl.presentation.state.ValidatorState
import com.tangem.utils.transformer.Transformer
internal class ValidatorSelectChangeTransformer(
+ private val yield: Yield,
private val selectedValidator: Yield.Validator?,
) : Transformer {
override fun transform(prevState: StakingUiState): StakingUiState {
- val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data ?: return prevState
- selectedValidator ?: return prevState
- val validatorState = (confirmationState.validatorState as? ValidatorState.Content)?.copy(
- chosenValidator = selectedValidator,
- ) ?: ValidatorState.Content(
- isClickable = false,
- availableValidators = emptyList(),
- chosenValidator = selectedValidator,
- )
+ val validatorState = prevState.validatorState as? StakingStates.ValidatorState.Data
+ val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
+
+ val isRestake = prevState.actionType == StakingActionCommonType.Pending.Restake
+ val isEnter = prevState.actionType == StakingActionCommonType.Enter
+ val isFromInfoScreen = prevState.currentStep == StakingStep.InitialInfo
+ val isVoteLocked = confirmationState?.pendingAction?.type == StakingActionType.VOTE_LOCKED
+
+ val activeValidator = selectedValidator.takeIf { isFromInfoScreen && isRestake }
+ ?: validatorState?.activeValidator
+ val filteredValidators = yield.preferredValidators.filterNot { it == activeValidator }
+
+ val selectedValidator = if (isRestake && isFromInfoScreen) {
+ filteredValidators.firstOrNull()
+ } else {
+ selectedValidator
+ }
return prevState.copy(
- confirmationState = confirmationState.copy(
- validatorState = validatorState,
+ validatorState = StakingStates.ValidatorState.Data(
+ chosenValidator = selectedValidator ?: yield.preferredValidators.first(),
+ availableValidators = filteredValidators,
+ isPrimaryButtonEnabled = true,
+ isClickable = true,
+ activeValidator = activeValidator,
+ isVisibleOnConfirmation = isEnter || isRestake || isVoteLocked,
),
)
}
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 efda617b73..ae8f6d4cb2 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
@@ -5,8 +5,12 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
+import com.tangem.features.staking.impl.presentation.state.BalanceState
+import com.tangem.lib.crypto.BlockchainUtils.isBSC
import com.tangem.lib.crypto.BlockchainUtils.isSolana
+import com.tangem.lib.crypto.BlockchainUtils.isTron
import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toPersistentList
@Suppress("CyclomaticComplexMethod")
internal fun StakingActionType?.getPendingActionTitle(): TextReference = when (this) {
@@ -29,8 +33,35 @@ internal fun StakingActionType?.getPendingActionTitle(): TextReference = when (t
null -> TextReference.EMPTY
}
-internal fun isSolanaWithdraw(networkId: String, pendingActions: ImmutableList?): Boolean {
- val isSolana = isSolana(networkId)
- val isWithdraw = pendingActions?.all { it.type == StakingActionType.WITHDRAW } == true
- return isSolana && isWithdraw && !pendingActions.isNullOrEmpty()
+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 isBscRestake = isBSC(networkId) && activeStake.pendingActions.any {
+ it.type == StakingActionType.RESTAKE
+ }
+
+ return isSingleAction && !isBscRestake || isComposePendingActions
+}
+
+internal fun withStubUnstakeAction(networkId: String, activeStake: BalanceState) = if (isBSC(networkId)) {
+ activeStake.pendingActions.plus(
+ PendingAction(
+ type = StakingActionType.UNSTAKE,
+ passthrough = "",
+ args = null,
+ ),
+ ).toPersistentList()
+} else {
+ activeStake.pendingActions
+}
+
+internal fun isTronStakedBalance(networkId: String, pendingAction: PendingAction?): Boolean {
+ return isTron(networkId) && pendingAction?.type == StakingActionType.REVOKE
+}
+
+internal fun isComposePendingActions(networkId: String, pendingActions: ImmutableList?): Boolean {
+ return when {
+ isSolana(networkId) -> pendingActions?.any { it.type == StakingActionType.WITHDRAW } == true
+ else -> false
+ }
}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
index 255fd36faa..ad11c31650 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
@@ -19,13 +19,13 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
-import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState
import com.tangem.features.staking.impl.presentation.state.StakingNotification
import com.tangem.features.staking.impl.presentation.state.StakingStates
import com.tangem.features.staking.impl.presentation.state.TransactionDoneState
import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmationStatePreviewData
+import com.tangem.features.staking.impl.presentation.state.previewdata.ValidatorStatePreviewData
import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub
import com.tangem.features.staking.impl.presentation.ui.block.NotificationsBlock
import com.tangem.features.staking.impl.presentation.ui.block.StakingFeeBlock
@@ -36,12 +36,12 @@ import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickInten
internal fun StakingConfirmationContent(
amountState: AmountState,
state: StakingStates.ConfirmationState,
+ validatorState: StakingStates.ValidatorState,
clickIntents: StakingClickIntents,
type: StakingActionCommonType,
) {
if (state !is StakingStates.ConfirmationState.Data) return
- val isEnterAction = type == StakingActionCommonType.ENTER
- val showValidatorBlock = isEnterAction || state.pendingAction?.type == StakingActionType.VOTE_LOCKED
+ val isEnterAction = type == StakingActionCommonType.Enter
val isTransactionSent = state.innerState == InnerConfirmationStakingState.COMPLETED
val isTransactionInProgress = state.notifications.any { it is StakingNotification.Warning.TransactionInProgress }
Column(
@@ -67,13 +67,11 @@ internal fun StakingConfirmationContent(
isEditingDisabled = !isEnterAction && state.innerState != InnerConfirmationStakingState.COMPLETED,
onClick = clickIntents::onPrevClick,
)
- if (showValidatorBlock) {
- ValidatorBlock(
- validatorState = state.validatorState,
- isClickable = !isTransactionInProgress,
- onClick = clickIntents::openValidators,
- )
- }
+ ValidatorBlock(
+ validatorState = validatorState,
+ isClickable = !isTransactionInProgress,
+ onClick = clickIntents::openValidators,
+ )
StakingFeeBlock(feeState = state.feeState, isTransactionSent = isTransactionSent)
NotificationsBlock(notifications = state.notifications)
}
@@ -88,8 +86,9 @@ private fun Preview_StakingConfirmationContent() {
StakingConfirmationContent(
amountState = AmountStatePreviewData.amountState,
state = ConfirmationStatePreviewData.assentStakingState,
+ validatorState = ValidatorStatePreviewData.validatorState,
clickIntents = StakingClickIntentsStub,
- type = StakingActionCommonType.ENTER,
+ type = StakingActionCommonType.Enter,
)
}
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt
index 5c2e5ceb51..21be700364 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt
@@ -3,7 +3,6 @@ package com.tangem.features.staking.impl.presentation.ui
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentTransitionScope
-import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
@@ -89,15 +88,12 @@ private fun StakingAppBar(uiState: StakingUiState) {
val (backIcon, click) = when (uiState.currentStep) {
StakingStep.Amount,
StakingStep.Confirmation,
- -> {
- R.drawable.ic_close_24 to uiState.clickIntents::onBackClick
- }
+ -> R.drawable.ic_close_24 to uiState.clickIntents::onBackClick
StakingStep.Validators,
StakingStep.RewardsValidators,
+ StakingStep.RestakeValidator,
StakingStep.InitialInfo,
- -> {
- R.drawable.ic_back_24 to uiState.clickIntents::onPrevClick
- }
+ -> R.drawable.ic_back_24 to uiState.clickIntents::onPrevClick
}
AppBarWithBackButtonAndIcon(
text = uiState.title.resolveReference(),
@@ -109,7 +105,6 @@ private fun StakingAppBar(uiState: StakingUiState) {
)
}
-@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = Modifier) {
val currentScreen = uiState.currentStep
@@ -172,17 +167,16 @@ private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = M
StakingStep.Confirmation -> StakingConfirmationContent(
amountState = uiState.amountState,
state = uiState.confirmationState,
+ validatorState = uiState.validatorState,
clickIntents = uiState.clickIntents,
type = uiState.actionType,
)
- StakingStep.Validators -> {
- val confirmState = uiState.confirmationState
- if (confirmState !is StakingStates.ConfirmationState.Data) return@AnimatedContent
- StakingValidatorListContent(
- state = confirmState.validatorState,
- clickIntents = uiState.clickIntents,
- )
- }
+ StakingStep.RestakeValidator,
+ StakingStep.Validators,
+ -> StakingValidatorListContent(
+ state = uiState.validatorState,
+ clickIntents = uiState.clickIntents,
+ )
}
}
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt
index 9ddda86f32..692f5b3050 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt
@@ -28,8 +28,8 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.features.staking.impl.R
-import com.tangem.features.staking.impl.presentation.state.ValidatorState
-import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmationStatePreviewData
+import com.tangem.features.staking.impl.presentation.state.StakingStates
+import com.tangem.features.staking.impl.presentation.state.previewdata.ValidatorStatePreviewData
import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
import com.tangem.utils.extensions.orZero
@@ -39,7 +39,7 @@ import com.tangem.utils.extensions.orZero
*/
@Composable
internal fun StakingValidatorListContent(
- state: ValidatorState,
+ state: StakingStates.ValidatorState,
clickIntents: StakingClickIntents,
modifier: Modifier = Modifier,
) {
@@ -51,7 +51,7 @@ internal fun StakingValidatorListContent(
.background(TangemTheme.colors.background.secondary)
.padding(horizontal = TangemTheme.dimens.spacing16),
) {
- if (state is ValidatorState.Content) {
+ if (state is StakingStates.ValidatorState.Data) {
val validators = state.availableValidators
items(
count = validators.size,
@@ -131,7 +131,7 @@ private fun RowScope.ValidatorLabel(isStrategicPartner: Boolean) {
@Composable
private fun StakingValidatorListContent_Preview(
@PreviewParameter(StakingValidatorListContentPreviewProvider::class)
- data: ValidatorState,
+ data: StakingStates.ValidatorState,
) {
TangemThemePreview {
StakingValidatorListContent(
@@ -141,8 +141,8 @@ private fun StakingValidatorListContent_Preview(
}
}
-private class StakingValidatorListContentPreviewProvider : PreviewParameterProvider {
- override val values: Sequence
- get() = sequenceOf(ConfirmationStatePreviewData.assentStakingState.validatorState)
+private class StakingValidatorListContentPreviewProvider : PreviewParameterProvider {
+ override val values: Sequence
+ get() = sequenceOf(ValidatorStatePreviewData.validatorState)
}
// endregion
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt
index 192d1e5397..2da1751f34 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt
@@ -15,39 +15,40 @@ import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.features.staking.impl.R
-import com.tangem.features.staking.impl.presentation.state.ValidatorState
+import com.tangem.features.staking.impl.presentation.state.StakingStates
import com.tangem.features.staking.impl.presentation.ui.ValidatorImagePlaceholder
import com.tangem.utils.extensions.orZero
@Composable
-internal fun ValidatorBlock(validatorState: ValidatorState, isClickable: Boolean, onClick: () -> Unit) {
+internal fun ValidatorBlock(validatorState: StakingStates.ValidatorState, isClickable: Boolean, onClick: () -> Unit) {
+ val state = validatorState as? StakingStates.ValidatorState.Data ?: return
+ if (!state.isVisibleOnConfirmation) return
+
Column(
modifier = Modifier
.fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action)
.clickable(
- enabled = validatorState.isClickable && isClickable,
+ enabled = state.isClickable && isClickable,
interactionSource = remember { MutableInteractionSource() },
indication = ripple(),
onClick = onClick,
),
) {
- if (validatorState is ValidatorState.Content) {
- InputRowImageInfo(
- title = resourceReference(R.string.staking_validator),
- subtitle = stringReference(validatorState.chosenValidator.name),
- infoTitle = annotatedReference {
- append(resourceReference(R.string.staking_details_apr).resolveReference())
- appendSpace()
- appendColored(
- text = BigDecimalFormatter.formatPercent(validatorState.chosenValidator.apr.orZero(), true),
- color = TangemTheme.colors.text.accent,
- )
- },
- imageUrl = validatorState.chosenValidator.image.orEmpty(),
- onImageError = { ValidatorImagePlaceholder() },
- )
- }
+ InputRowImageInfo(
+ title = resourceReference(R.string.staking_validator),
+ subtitle = stringReference(state.chosenValidator.name),
+ infoTitle = annotatedReference {
+ append(resourceReference(R.string.staking_details_apr).resolveReference())
+ appendSpace()
+ appendColored(
+ text = BigDecimalFormatter.formatPercent(state.chosenValidator.apr.orZero(), true),
+ color = TangemTheme.colors.text.accent,
+ )
+ },
+ imageUrl = state.chosenValidator.image.orEmpty(),
+ onImageError = { ValidatorImagePlaceholder() },
+ )
}
}
\ No newline at end of file
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 8e55492aa8..7e23d53fc6 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
@@ -3,13 +3,10 @@ package com.tangem.features.staking.impl.presentation.viewmodel
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
import com.tangem.common.ui.notifications.NotificationUM
-import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.staking.model.stakekit.Yield
-import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType
-import kotlinx.collections.immutable.ImmutableList
import java.math.BigDecimal
@Suppress("TooManyFunctions")
@@ -17,12 +14,7 @@ internal interface StakingClickIntents : AmountScreenClickIntents {
fun onBackClick()
- fun onNextClick(
- actionTypeToOverwrite: StakingActionCommonType? = null,
- pendingAction: PendingAction? = null,
- pendingActions: ImmutableList? = null,
- balanceState: BalanceState? = null,
- )
+ fun onNextClick(balanceState: BalanceState? = null)
fun onActionClick()
@@ -36,9 +28,9 @@ internal interface StakingClickIntents : AmountScreenClickIntents {
fun onEnterClick()
- fun getFee(pendingAction: PendingAction?, pendingActions: ImmutableList?)
+ fun getFee()
- override fun onAmountNext() = onNextClick(actionTypeToOverwrite = null)
+ override fun onAmountNext() = onNextClick()
fun openValidators()
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 a6a90596ef..8e3d7ac5ee 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
@@ -63,12 +63,14 @@ import com.tangem.features.staking.impl.presentation.state.transformers.*
import com.tangem.features.staking.impl.presentation.state.transformers.amount.*
import com.tangem.features.staking.impl.presentation.state.transformers.approval.*
import com.tangem.features.staking.impl.presentation.state.transformers.validator.ValidatorSelectChangeTransformer
-import com.tangem.features.staking.impl.presentation.state.utils.isSolanaWithdraw
+import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction
+import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.isSingleItem
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
@@ -185,6 +187,7 @@ internal class StakingViewModel @Inject constructor(
private var stakingApproval: StakingApproval = StakingApproval.Empty
private var isAmountSubtractAvailable: Boolean = false
+ private var isAnyTokenStaked: Boolean = false
private val allowanceTaskScheduler = SingleTaskScheduler()
private val transactionsInProgress: CopyOnWriteArrayList = CopyOnWriteArrayList()
@@ -210,70 +213,16 @@ internal class StakingViewModel @Inject constructor(
stakingStateRouter.onBackClick()
}
- override fun onNextClick(
- actionTypeToOverwrite: StakingActionCommonType?,
- pendingAction: PendingAction?,
- pendingActions: ImmutableList?,
- balanceState: BalanceState?,
- ) {
- if (actionTypeToOverwrite != null) {
- stateController.update(SetActionToExecuteTransformer(actionTypeToOverwrite, pendingAction, pendingActions))
- }
+ override fun onNextClick(balanceState: BalanceState?) {
stakingStateRouter.onNextClick()
- when {
- isInitState() -> {
- stateController.update(SetConfirmationStateResetAssentTransformer)
- stateController.update(
- SetConfirmationStateLoadingTransformer(
- yield = yield,
- appCurrency = appCurrency,
- cryptoCurrency = cryptoCurrencyStatus.currency,
- ),
- )
- if (balanceState != null) {
- stateController.update(
- SetPossiblePendingTransactionTransformer(yield, balanceState, cryptoCurrencyStatus),
- )
- }
-
- stateController.update(
- transformer = SetInitialDataStateTransformer(
- clickIntents = this@StakingViewModel,
- yield = yield,
- isAnyTokenStaked = true,
- isApprovalNeeded = stakingApproval is StakingApproval.Needed,
- cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
- userWalletProvider = Provider { userWallet },
- appCurrencyProvider = Provider { appCurrency },
- balancesToShowProvider = Provider { balancesToShow },
- ),
- )
- onRefreshSwipe(isRefreshing = false)
- }
- isAssentState() -> {
- getFee(pendingAction, pendingActions)
- if (balanceState != null) {
- stateController.update(
- SetPossiblePendingTransactionTransformer(yield, balanceState, cryptoCurrencyStatus),
- )
- }
- val amountState = value.amountState as? AmountState.Data
- if (amountState?.amountTextField?.isWarning == true) {
- stateController.update(
- AmountRoundToIntegerTransformer(
- cryptoCurrencyStatus = cryptoCurrencyStatus,
- ),
- )
- }
- }
+ if (balanceState != null && (isInitState() || isAssentState())) {
+ stateController.update(
+ SetPossiblePendingTransactionTransformer(yield, balanceState, cryptoCurrencyStatus),
+ )
}
}
- override fun onActionClick() {
- handleOnNextConfirmationClick()
- }
-
- override fun getFee(pendingAction: PendingAction?, pendingActions: ImmutableList?) {
+ override fun getFee() {
stateController.update(
SetConfirmationStateLoadingTransformer(
yield = yield,
@@ -283,16 +232,12 @@ internal class StakingViewModel @Inject constructor(
)
viewModelScope.launch {
feeLoader.getFee(
- pendingAction = pendingAction,
- pendingActions = pendingActions,
onStakingFee = { gasEstimate ->
stateController.update(
SetConfirmationStateAssentTransformer(
appCurrencyProvider = Provider { appCurrency },
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
fee = gasEstimate,
- action = pendingAction,
- actions = pendingActions,
),
)
updateNotifications()
@@ -326,7 +271,7 @@ internal class StakingViewModel @Inject constructor(
}.saveIn(feeJobHolder)
}
- private fun handleOnNextConfirmationClick() {
+ override fun onActionClick() {
if (isAssentState()) {
viewModelScope.launch {
stakingAnalyticSender.sendTransactionStakingClickedAnalytics(value)
@@ -412,28 +357,23 @@ internal class StakingViewModel @Inject constructor(
}
override fun onEnterClick() {
- onAmountValueChange("") // reset amount state
-
- // TODO refactor in [REDACTED_JIRA]
- val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
- val filteredValidator = yield.validators.filter { it.preferred }
- if (filteredValidator.isEmpty()) {
+ if (yield.preferredValidators.isEmpty()) {
stateController.updateEvent(
StakingEvent.ShowAlert(StakingAlertUM.NoAvailableValidators),
)
} else {
- stateController.update {
- value.copy(
- confirmationState = confirmationState?.copy(
- validatorState = ValidatorState.Content(
- isClickable = true,
- chosenValidator = filteredValidator[0],
- availableValidators = filteredValidator,
- ),
- ) as StakingStates.ConfirmationState,
- )
- }
- onNextClick(StakingActionCommonType.ENTER)
+ stateController.updateAll(
+ SetConfirmationStateInitTransformer(
+ isEnter = true,
+ cryptoCurrencyStatus = cryptoCurrencyStatus,
+ stakingApproval = stakingApproval,
+ ),
+ ValidatorSelectChangeTransformer(
+ selectedValidator = null,
+ yield = yield,
+ ),
+ )
+ onNextClick()
}
}
@@ -474,7 +414,12 @@ internal class StakingViewModel @Inject constructor(
validator.name,
),
)
- stateController.update(ValidatorSelectChangeTransformer(validator))
+ stateController.update(
+ ValidatorSelectChangeTransformer(
+ selectedValidator = validator,
+ yield = yield,
+ ),
+ )
}
override fun openRewardsValidators() {
@@ -493,50 +438,38 @@ internal class StakingViewModel @Inject constructor(
token = value.cryptoCurrencySymbol,
),
)
- onNextClick(actionTypeToOverwrite = StakingActionCommonType.PENDING_REWARDS)
+ stateController.update {
+ value.copy(actionType = StakingActionCommonType.Pending.Rewards)
+ }
+ stakingStateRouter.showRewardsValidators()
}
}
override fun onActiveStake(activeStake: BalanceState) {
- val isAllWithdrawActions = isSolanaWithdraw(
- cryptoCurrencyStatus.currency.network.id.value,
- activeStake.pendingActions,
- )
- val isMultiplePendingActions = activeStake.pendingActions.size > 1
- if (isMultiplePendingActions && !isAllWithdrawActions) {
+ val networkId = cryptoCurrencyStatus.currency.network.id.value
+ if (isSingleAction(networkId, activeStake)) {
+ prepareForConfirmation(
+ pendingActions = activeStake.pendingActions,
+ validator = activeStake.validator,
+ amountValue = activeStake.cryptoValue,
+ )
+ onNextClick(balanceState = activeStake)
+ } else {
stateController.update(
ShowActionSelectorBottomSheetTransformer(
- pendingActions = activeStake.pendingActions,
+ pendingActions = withStubUnstakeAction(networkId, activeStake),
onActionSelect = { action ->
- stateController.update(ValidatorSelectChangeTransformer(activeStake.validator))
- stateController.update(
- AmountChangeStateTransformer(
- cryptoCurrencyStatus,
- activeStake.cryptoValue,
- yield,
- ),
- )
- onNextClick(
- actionTypeToOverwrite = StakingActionCommonType.PENDING_OTHER,
+ prepareForConfirmation(
pendingAction = action,
- balanceState = activeStake,
+ validator = activeStake.validator,
+ amountValue = activeStake.cryptoValue,
)
stateController.update(DismissBottomSheetStateTransformer)
+ onNextClick(balanceState = activeStake)
},
onDismiss = { stateController.update(DismissBottomSheetStateTransformer) },
),
)
- } else {
- stateController.update(ActionTypeActiveStakeTransformer(cryptoCurrencyStatus, activeStake))
- stateController.update(ValidatorSelectChangeTransformer(activeStake.validator))
- stateController.update(AmountChangeStateTransformer(cryptoCurrencyStatus, activeStake.cryptoValue, yield))
-
- onNextClick(
- actionTypeToOverwrite = null,
- pendingAction = activeStake.pendingActions.firstOrNull(),
- pendingActions = activeStake.pendingActions.takeIf { isAllWithdrawActions },
- balanceState = activeStake,
- )
}
}
@@ -632,7 +565,7 @@ internal class StakingViewModel @Inject constructor(
stakingAnalyticSender.sendTransactionApprovalAnalytics(tokenCryptoCurrency)
stateController.update(SetApprovalInProgressTransformer)
stateController.update(DismissBottomSheetStateTransformer)
- awaitForAllowance(confirmationState.pendingAction)
+ awaitForAllowance()
},
)
}.saveIn(approvalJobHolder)
@@ -718,7 +651,7 @@ internal class StakingViewModel @Inject constructor(
stateController.update(DismissStakingNotificationsStateTransformer(notification))
}
- private fun awaitForAllowance(pendingAction: PendingAction?) {
+ private fun awaitForAllowance() {
val approval = stakingApproval as? StakingApproval.Needed ?: return
allowanceTaskScheduler.scheduleTask(
scope = viewModelScope,
@@ -737,7 +670,7 @@ internal class StakingViewModel @Inject constructor(
val amount = (value.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value
?: error("No amount provided")
if (allowance >= amount) {
- getFee(pendingAction = pendingAction, pendingActions = null)
+ getFee()
allowanceTaskScheduler.cancelTask()
}
},
@@ -775,7 +708,7 @@ internal class StakingViewModel @Inject constructor(
val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrElse { error("CardInfo must be not null") }
val amountState = uiState.value.amountState as? AmountState.Data
val confirmationState = uiState.value.confirmationState as? StakingStates.ConfirmationState.Data
- val validatorState = confirmationState?.validatorState as? ValidatorState.Content
+ val validatorState = uiState.value.validatorState as? StakingStates.ValidatorState.Data
val feeState = confirmationState?.feeState as? FeeState.Content
val validator = validatorState?.chosenValidator
@@ -817,6 +750,10 @@ internal class StakingViewModel @Inject constructor(
stakingApproval = isApproveNeededUseCase(cryptoCurrencyStatus.currency).getOrElse { StakingApproval.Empty }
}
+ private suspend fun setupIsAnyTokenStaked() {
+ isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false
+ }
+
private fun subscribeOnCurrencyStatusUpdates() {
getUserWalletUseCase(userWalletId).fold(
ifRight = { wallet ->
@@ -849,23 +786,11 @@ internal class StakingViewModel @Inject constructor(
feeCryptoCurrencyStatus =
getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull()
cryptoCurrencyStatus = status
- val isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false
setupApprovalNeeded()
+ setupIsAnyTokenStaked()
checkIfSubtractAvailable()
-
- stateController.update(
- transformer = SetInitialDataStateTransformer(
- clickIntents = this@StakingViewModel,
- yield = yield,
- isAnyTokenStaked = isAnyTokenStaked,
- isApprovalNeeded = stakingApproval is StakingApproval.Needed,
- cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
- userWalletProvider = Provider { userWallet },
- appCurrencyProvider = Provider { appCurrency },
- balancesToShowProvider = Provider { balancesToShow },
- ),
- )
+ subscribeOnStepChanges()
},
ifLeft = { error ->
Timber.e(error.toString())
@@ -900,6 +825,69 @@ internal class StakingViewModel @Inject constructor(
.launchIn(viewModelScope)
}
+ private fun subscribeOnStepChanges() {
+ uiState
+ .distinctUntilChangedBy { it.currentStep }
+ .onEach {
+ when {
+ isInitState() -> {
+ stateController.updateAll(
+ SetInitialDataStateTransformer(
+ clickIntents = this@StakingViewModel,
+ yield = yield,
+ isAnyTokenStaked = isAnyTokenStaked,
+ cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
+ userWalletProvider = Provider { userWallet },
+ appCurrencyProvider = Provider { appCurrency },
+ balancesToShowProvider = Provider { balancesToShow },
+ ),
+ SetConfirmationStateEmptyTransformer,
+ )
+ onRefreshSwipe(isRefreshing = false)
+ }
+ isAssentState() -> {
+ getFee()
+ val amountState = value.amountState as? AmountState.Data
+ if (amountState?.amountTextField?.isWarning == true) {
+ stateController.update(
+ AmountRoundToIntegerTransformer(
+ cryptoCurrencyStatus = cryptoCurrencyStatus,
+ ),
+ )
+ }
+ }
+ }
+ }
+ .flowOn(dispatchers.main)
+ .launchIn(viewModelScope)
+ }
+
+ private fun prepareForConfirmation(
+ pendingActions: ImmutableList = persistentListOf(),
+ pendingAction: PendingAction? = pendingActions.firstOrNull(),
+ validator: Yield.Validator?,
+ amountValue: String,
+ ) {
+ stateController.updateAll(
+ SetConfirmationStateInitTransformer(
+ isEnter = false,
+ cryptoCurrencyStatus = cryptoCurrencyStatus,
+ stakingApproval = stakingApproval,
+ pendingActions = pendingActions,
+ pendingAction = pendingAction,
+ ),
+ ValidatorSelectChangeTransformer(
+ selectedValidator = validator,
+ yield = yield,
+ ),
+ AmountChangeStateTransformer(
+ cryptoCurrencyStatus = cryptoCurrencyStatus,
+ value = amountValue,
+ yield = yield,
+ ),
+ )
+ }
+
private fun isAssentState(): Boolean {
return value.currentStep == StakingStep.Confirmation &&
(value.confirmationState as? StakingStates.ConfirmationState.Data)?.innerState ==
diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt
index 1c340dabc3..fe67dcf443 100644
--- a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt
+++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt
@@ -88,6 +88,11 @@ object BlockchainUtils {
return blockchain == Blockchain.Cosmos || blockchain == Blockchain.CosmosTestnet
}
+ fun isBSC(networkId: String): Boolean {
+ val blockchain = Blockchain.fromId(networkId)
+ return blockchain == Blockchain.BSC || blockchain == Blockchain.BSCTestnet
+ }
+
data class BlockchainInfo(
val blockchainId: String,
val name: String,