Updated on 2026-08-14
This commit is contained in:
parent
10d959b0de
commit
679469c91f
7 changed files with 110 additions and 14 deletions
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
@ -82,9 +82,15 @@ internal sealed class StakingStates {
|
|||
val validatorState: ValidatorState,
|
||||
val notifications: ImmutableList<StakingNotification>,
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ internal object ConfirmStakingStatePreviewData {
|
|||
days = 2,
|
||||
),
|
||||
),
|
||||
isStaking = false,
|
||||
isSuccess = false,
|
||||
innerState = StakingStates.ConfirmStakingState.Data.InnerConfirmStakingState.CONFIRM,
|
||||
)
|
||||
}
|
||||
|
|
@ -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<AppCurrency>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
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
|
||||
|
|
@ -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<StakingUiState> {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<StakingUiState> {
|
||||
|
||||
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,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -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<Bundle>(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()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue