From 679469c91f9759e66fc6cc789576629bf8acdd46 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 4 Jul 2024 15:14:19 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../presentation/state/StakingStateRouter.kt | 3 +- .../impl/presentation/state/StakingUiState.kt | 12 +++- .../ConfirmStakingStatePreviewData.kt | 3 +- ...t => SetConfirmStateConfirmTransformer.kt} | 4 +- .../SetConfirmStateInProgressTransformer.kt | 25 +++++++ ...t => SetConfirmStateLoadingTransformer.kt} | 7 +- .../viewmodel/StakingViewModel.kt | 70 ++++++++++++++++++- 7 files changed, 110 insertions(+), 14 deletions(-) rename features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/{SetConfirmStateDataStateTransformer.kt => SetConfirmStateConfirmTransformer.kt} (91%) create mode 100644 features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateInProgressTransformer.kt rename features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/{SetConfirmLoadingStateTransformer.kt => SetConfirmStateLoadingTransformer.kt} (89%) 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 921430000b..5f277ce4a4 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 @@ -68,6 +68,7 @@ internal class StakingStateRouter( } fun showSuccess() { - stateController.update { it.copy(currentStep = StakingStep.Success) } + // stateController.update { it.copy(currentStep = StakingStep.Success) } + // TODO staking [REDACTED_TASK_KEY] } } \ No newline at end of file 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 8d952f02e4..65fe669de8 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 @@ -82,9 +82,15 @@ internal sealed class StakingStates { val validatorState: ValidatorState, val notifications: ImmutableList, val footerText: String, - val isSuccess: Boolean, - val isStaking: Boolean, - ) : ConfirmStakingState() + val innerState: InnerConfirmStakingState, + ) : ConfirmStakingState() { + + enum class InnerConfirmStakingState { + CONFIRM, + IN_PROGRESS, + SUCCESS, + } + } data class Empty( override val isPrimaryButtonEnabled: Boolean = false, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmStakingStatePreviewData.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmStakingStatePreviewData.kt index 161f39ee33..34916ee421 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmStakingStatePreviewData.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmStakingStatePreviewData.kt @@ -82,7 +82,6 @@ internal object ConfirmStakingStatePreviewData { days = 2, ), ), - isStaking = false, - isSuccess = false, + innerState = StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.CONFIRM, ) } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateConfirmTransformer.kt similarity index 91% rename from features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateDataStateTransformer.kt rename to features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateConfirmTransformer.kt index d37ad3406b..f058a772c3 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateConfirmTransformer.kt @@ -12,7 +12,7 @@ import com.tangem.utils.transformer.Transformer import com.tangem.blockchain.common.Amount @Suppress("UnusedPrivateMember") -internal class SetConfirmStateDataStateTransformer( +internal class SetConfirmStateConfirmTransformer( private val appCurrencyProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, private val stakingGasEstimate: StakingGasEstimate, @@ -42,6 +42,8 @@ internal class SetConfirmStateDataStateTransformer( appCurrency = appCurrencyProvider(), isFeeApproximate = false, ), + isPrimaryButtonEnabled = true, + innerState = StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.CONFIRM, ) } else { return this diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateInProgressTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateInProgressTransformer.kt new file mode 100644 index 0000000000..edad01bfea --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateInProgressTransformer.kt @@ -0,0 +1,25 @@ +package com.tangem.features.staking.impl.presentation.state.transformers + +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 class SetConfirmStateInProgressTransformer : Transformer { + + override fun transform(prevState: StakingUiState): StakingUiState { + return prevState.copy( + confirmStakingState = prevState.confirmStakingState.copyWrapped(), + ) + } + + private fun StakingStates.ConfirmStakingState.copyWrapped(): StakingStates.ConfirmStakingState { + return if (this is StakingStates.ConfirmStakingState.Data) { + copy( + isPrimaryButtonEnabled = false, + innerState = StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.IN_PROGRESS, + ) + } else { + this + } + } +} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmLoadingStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateLoadingTransformer.kt similarity index 89% rename from features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmLoadingStateTransformer.kt rename to features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateLoadingTransformer.kt index 76ff266521..838a5db5cd 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmLoadingStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmStateLoadingTransformer.kt @@ -10,14 +10,14 @@ import com.tangem.utils.transformer.Transformer import kotlinx.collections.immutable.persistentListOf @Suppress("UnusedPrivateMember") -internal class SetConfirmLoadingStateTransformer( +internal class SetConfirmStateLoadingTransformer( private val yield: Yield, ) : Transformer { override fun transform(prevState: StakingUiState): StakingUiState { val possibleConfirmStakingState = prevState.confirmStakingState as? StakingStates.ConfirmStakingState.Data val possibleValidatorState = possibleConfirmStakingState?.validatorState as? ValidatorState.Content - val chosenValidator = possibleValidatorState?.chosenValidator ?: yield.validators[0] // TODO staking add sorting + val chosenValidator = possibleValidatorState?.chosenValidator ?: yield.validators[0] return prevState.copy( confirmStakingState = StakingStates.ConfirmStakingState.Data( @@ -34,8 +34,7 @@ internal class SetConfirmLoadingStateTransformer( ), ), footerText = "", - isSuccess = false, - isStaking = false, // TODO staking move to enum + innerState = StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.CONFIRM, ), ) } 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 23bdae1705..7b76ca2694 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 @@ -6,6 +6,8 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import arrow.core.getOrElse +import com.tangem.blockchain.common.TransactionData +import com.tangem.common.extensions.hexToBytes import com.tangem.common.routing.AppRoute import com.tangem.common.routing.bundle.unbundle import com.tangem.common.ui.amountScreen.models.AmountState @@ -14,9 +16,11 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.staking.InitializeStakingProcessUseCase import com.tangem.domain.staking.model.Yield +import com.tangem.domain.staking.model.transaction.StakingTransaction import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetUserWalletUseCase @@ -24,6 +28,7 @@ import com.tangem.features.staking.impl.navigation.InnerStakingRouter import com.tangem.features.staking.impl.presentation.state.* import com.tangem.features.staking.impl.presentation.state.StakingStateController import com.tangem.features.staking.impl.presentation.state.StakingStateRouter +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.transformers.* import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountChangeStateTransformer @@ -36,6 +41,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject import kotlin.properties.Delegates @@ -49,6 +55,7 @@ internal class StakingViewModel @Inject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getUserWalletUseCase: GetUserWalletUseCase, private val initializeStakingProcessUseCase: InitializeStakingProcessUseCase, + private val sendTransactionUseCase: SendTransactionUseCase, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents { @@ -58,6 +65,8 @@ internal class StakingViewModel @Inject constructor( var stakingStateRouter: StakingStateRouter by Delegates.notNull() private set + private var stakingTransaction: StakingTransaction? = null + private val cryptoCurrencyId: CryptoCurrency.ID = savedStateHandle.get(AppRoute.Staking.CRYPTO_CURRENCY_ID_KEY) ?.unbundle(CryptoCurrency.ID.serializer()) @@ -88,16 +97,30 @@ internal class StakingViewModel @Inject constructor( } override fun onNextClick() { + handleOnNextConfirmClick() stakingStateRouter.onNextClick() if (value.currentStep == StakingStep.Confirm) { initStaking() } } + private fun handleOnNextConfirmClick() { + if (value.currentStep == StakingStep.Confirm && + (value.confirmStakingState as? StakingStates.ConfirmStakingState.Data)?.innerState == + StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.CONFIRM + ) { + viewModelScope.launch { + stakingTransaction?.unsignedTransaction?.let { + sendStakingTransaction(TransactionData.Compiled(value = it.hexToBytes())) + } ?: error("No unsigned transaction available") + } + } + } + private fun initStaking() { viewModelScope.launch { stateController.update( - SetConfirmLoadingStateTransformer( + SetConfirmStateLoadingTransformer( yield = yield, ), ) @@ -111,14 +134,17 @@ internal class StakingViewModel @Inject constructor( validatorAddress = yield.validators.getOrNull(0)?.address ?: error("No available validator"), token = yield.token, ) + val (enterAction, stakingTransaction) = actionWithTransaction.getOrElse { - error("Can't retrieve action and transaction") + error(it) } + this@StakingViewModel.stakingTransaction = stakingTransaction + val stakingGasEstimate = stakingTransaction.gasEstimate ?: error("Can't get fee info") stateController.update( - SetConfirmStateDataStateTransformer( + SetConfirmStateConfirmTransformer( appCurrencyProvider = Provider { appCurrency }, cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, stakingGasEstimate = stakingGasEstimate, @@ -226,4 +252,42 @@ internal class StakingViewModel @Inject constructor( .flowOn(dispatchers.main) .launchIn(viewModelScope) } + + private suspend fun sendStakingTransaction(txData: TransactionData) { + stateController.update(SetConfirmStateInProgressTransformer()) + + sendTransactionUseCase( + txData = txData, + userWallet = userWallet, + network = cryptoCurrencyStatus.currency.network, + ).fold( + ifLeft = { error -> + Timber.e(error.toString()) + val gasEstimate = stakingTransaction?.gasEstimate ?: return@fold + stateController.update( + SetConfirmStateConfirmTransformer( + appCurrencyProvider = Provider { appCurrency }, + cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, + stakingGasEstimate = gasEstimate, + ), + ) + // uiState = eventStateFactory.getSendTransactionErrorState( + // error = error, + // onConsume = { uiState = eventStateFactory.onConsumeEventState() }, + // ) + // analyticsEventHandler.send(SendAnalyticEvents.TransactionError(cryptoCurrency.symbol)) + }, + ifRight = { + val gasEstimate = stakingTransaction?.gasEstimate ?: return@fold + stateController.update( + SetConfirmStateConfirmTransformer( + appCurrencyProvider = Provider { appCurrency }, + cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, + stakingGasEstimate = gasEstimate, + ), + ) + // sendScreenAnalyticSender.sendTransaction() + }, + ) + } } \ No newline at end of file