Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-31 12:24:45 +05:00
parent d42a9d5b46
commit a7b2779e9f
9 changed files with 58 additions and 24 deletions

View file

@ -83,6 +83,7 @@ internal sealed class StakingStates {
val notifications: ImmutableList<StakingNotification>,
val footerText: String,
val transactionDoneState: TransactionDoneState,
val pendingActionInProgress: PendingAction? = null,
) : ConfirmationState()
data class Empty(

View file

@ -124,13 +124,25 @@ internal class YieldBalancesConverter(
BalanceType.UNSTAKED -> resourceReference(R.string.staking_unstaked) to
resourceReference(R.string.staking_unstaked_footer)
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking) to null
else -> null to null
BalanceType.AVAILABLE -> null to null
BalanceType.PREPARING -> null to null
BalanceType.REWARDS -> null to null
BalanceType.LOCKED -> null to null
BalanceType.UNLOCKING -> null to null
BalanceType.UNKNOWN -> null to null
}
private fun getClickableType(type: BalanceType) = when (type) {
BalanceType.STAKED,
BalanceType.UNSTAKED,
-> true
else -> false
BalanceType.AVAILABLE,
BalanceType.UNSTAKING,
BalanceType.PREPARING,
BalanceType.REWARDS,
BalanceType.LOCKED,
BalanceType.UNLOCKING,
BalanceType.UNKNOWN,
-> false
}
}

View file

@ -13,6 +13,8 @@ object StakingClickIntentsStub : StakingClickIntents {
override fun onNextClick(pendingActions: ImmutableList<PendingAction>) {}
override fun onActionClick(pendingAction: PendingAction?) {}
override fun onPrevClick() {}
override fun onInfoClick(infoType: InfoType) {}
@ -33,8 +35,6 @@ object StakingClickIntentsStub : StakingClickIntents {
override fun openRewardsValidators() {}
override fun selectRewardValidator(rewardValue: String) {}
override fun onExploreClick() {}
override fun onShareClick() {}

View file

@ -19,6 +19,7 @@ internal class SetConfirmationStateAssentTransformer(
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val stakingGasEstimate: StakingGasEstimate,
private val pendingActionList: ImmutableList<PendingAction>,
private val pendingAction: PendingAction?,
) : Transformer<StakingUiState> {
override fun transform(prevState: StakingUiState): StakingUiState {
@ -48,6 +49,7 @@ internal class SetConfirmationStateAssentTransformer(
),
validatorState = validatorState.copySealed(isClickable = true),
pendingActions = pendingActionList,
pendingActionInProgress = pendingAction,
isPrimaryButtonEnabled = true,
)
} else {

View file

@ -33,6 +33,7 @@ internal class SetConfirmationStateLoadingTransformer(
footerText = "",
transactionDoneState = TransactionDoneState.Empty,
pendingActions = persistentListOf(),
pendingActionInProgress = null,
),
)
}

View file

@ -63,7 +63,7 @@ internal fun StakingClaimRewardsValidatorContent(
.background(TangemTheme.colors.background.action)
.clickable(
onClick = {
clickIntents.selectRewardValidator(item.cryptoValue)
clickIntents.onActiveStake(item)
},
),
)

View file

@ -14,6 +14,8 @@ internal interface StakingClickIntents : AmountScreenClickIntents {
fun onNextClick(pendingActions: ImmutableList<PendingAction> = persistentListOf())
fun onActionClick(pendingAction: PendingAction?)
fun onPrevClick()
fun onInfoClick(infoType: InfoType)
@ -26,8 +28,6 @@ internal interface StakingClickIntents : AmountScreenClickIntents {
fun openRewardsValidators()
fun selectRewardValidator(rewardValue: String)
fun onActiveStake(activeStake: BalanceState)
fun onExploreClick()

View file

@ -22,6 +22,7 @@ import com.tangem.domain.staking.model.stakekit.transaction.ActionParams
import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
@ -62,6 +63,7 @@ internal class StakingViewModel @Inject constructor(
private val saveUnsubmittedHashUseCase: SaveUnsubmittedHashUseCase,
private val submitHashUseCase: SubmitHashUseCase,
private val isStakeMoreAvailableUseCase: IsStakeMoreAvailableUseCase,
private val stakingYieldBalanceUseCase: FetchStakingYieldBalanceUseCase,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents {
@ -101,14 +103,18 @@ internal class StakingViewModel @Inject constructor(
}
override fun onNextClick(pendingActions: ImmutableList<PendingAction>) {
handleOnNextConfirmationClick()
stakingStateRouter.onNextClick()
if (isAssentState()) {
estimateGas(pendingActions)
}
}
private fun handleOnNextConfirmationClick() {
override fun onActionClick(pendingAction: PendingAction?) {
handleOnNextConfirmationClick(pendingAction)
stakingStateRouter.onNextClick()
}
private fun handleOnNextConfirmationClick(pendingAction: PendingAction?) {
if (isAssentState()) {
viewModelScope.launch {
stateController.update(SetConfirmationStateInProgressTransformer())
@ -117,7 +123,6 @@ internal class StakingViewModel @Inject constructor(
value.confirmationState as? StakingStates.ConfirmationState.Data ?: error("No confirmation state")
val validatorState = confirmationState.validatorState as? ValidatorState.Content
?: error("No validator provided")
val pendingActions = confirmationState.pendingActions
val stakingTransaction = getStakingTransactionUseCase(
userWalletId = userWalletId,
@ -131,8 +136,8 @@ internal class StakingViewModel @Inject constructor(
?: error("No available address"),
validatorAddress = validatorState.chosenValidator.address,
token = yield.token,
passthrough = pendingActions.firstOrNull()?.passthrough,
type = pendingActions.firstOrNull()?.type,
passthrough = pendingAction?.passthrough,
type = pendingAction?.type,
),
).getOrElse {
error(it)
@ -143,7 +148,8 @@ internal class StakingViewModel @Inject constructor(
transactionId = stakingTransaction.id,
gasEstimate = stakingTransaction.gasEstimate ?: error("No gas estimate available"),
txData = TransactionData.Compiled(value = it.hexToBytes()),
pendingActions = pendingActions,
pendingActionList = confirmationState.pendingActions,
pendingAction = pendingAction,
)
} ?: error("No unsigned transaction available")
}
@ -159,6 +165,7 @@ internal class StakingViewModel @Inject constructor(
)
val cryptoCurrencyValue = cryptoCurrencyStatus.value
val pendingAction = pendingActions.firstOrNull()
val stakingGasEstimate = estimateGasUseCase(
userWalletId = userWalletId,
network = cryptoCurrencyStatus.currency.network,
@ -171,8 +178,8 @@ internal class StakingViewModel @Inject constructor(
?: error("No available address"),
validatorAddress = yield.validators.getOrNull(0)?.address ?: error("No available validator"),
token = yield.token,
passthrough = pendingActions.firstOrNull()?.passthrough,
type = pendingActions.firstOrNull()?.type,
passthrough = pendingAction?.passthrough,
type = pendingAction?.type,
),
).getOrElse { error("Can't get fee info") }
@ -182,6 +189,7 @@ internal class StakingViewModel @Inject constructor(
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
stakingGasEstimate = stakingGasEstimate,
pendingActionList = pendingActions,
pendingAction = pendingAction,
),
)
}
@ -226,11 +234,6 @@ internal class StakingViewModel @Inject constructor(
onNextClick()
}
override fun selectRewardValidator(rewardValue: String) {
stateController.update(AmountChangeStateTransformer(cryptoCurrencyStatus, yield, rewardValue))
onNextClick()
}
override fun onActiveStake(activeStake: BalanceState) {
val routeType = if (activeStake.pendingActions.isEmpty()) {
RouteType.UNSTAKE
@ -321,7 +324,8 @@ internal class StakingViewModel @Inject constructor(
transactionId: String,
gasEstimate: StakingGasEstimate,
txData: TransactionData,
pendingActions: ImmutableList<PendingAction>,
pendingActionList: ImmutableList<PendingAction>,
pendingAction: PendingAction?,
) {
sendTransactionUseCase(
txData = txData,
@ -335,14 +339,15 @@ internal class StakingViewModel @Inject constructor(
appCurrencyProvider = Provider { appCurrency },
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
stakingGasEstimate = gasEstimate,
pendingActionList = pendingActions,
pendingActionList = pendingActionList,
pendingAction = pendingAction,
),
)
// todo add error dialog
},
ifRight = { txHash ->
submitHash(transactionId, txHash)
updateStakeBalance()
val txUrl = getExplorerTransactionUrlUseCase(
txHash = txHash,
networkId = cryptoCurrencyStatus.currency.network.id,
@ -375,6 +380,19 @@ internal class StakingViewModel @Inject constructor(
}
}
private fun updateStakeBalance() {
viewModelScope.launch {
stakingYieldBalanceUseCase(
userWalletId = userWalletId,
address = CryptoCurrencyAddress(
cryptoCurrencyStatus.currency,
cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value.orEmpty(),
),
refresh = true,
)
}
}
private fun isAssentState(): Boolean {
return value.currentStep == StakingStep.Confirmation &&
(value.confirmationState as? StakingStates.ConfirmationState.Data)?.innerState ==

View file

@ -88,7 +88,7 @@ markdown = "0.7.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-711"
tangemBlockchainSdk = "develop-713"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-375"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^