Updated on 2026-08-14
This commit is contained in:
parent
ea9faf6992
commit
2afe7db48e
7 changed files with 65 additions and 36 deletions
|
|
@ -118,6 +118,7 @@ internal sealed class StakingStates {
|
|||
val footerText: TextReference,
|
||||
val transactionDoneState: TransactionDoneState,
|
||||
val isApprovalNeeded: Boolean,
|
||||
val allowance: BigDecimal,
|
||||
val reduceAmountBy: BigDecimal?,
|
||||
) : ConfirmationState()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.domain.staking.EstimateGasUseCase
|
||||
import com.tangem.domain.staking.model.StakingApproval
|
||||
import com.tangem.domain.staking.model.stakekit.PendingAction
|
||||
import com.tangem.domain.staking.model.stakekit.StakingError
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
|
|
@ -17,7 +16,6 @@ import com.tangem.domain.staking.model.stakekit.transaction.ActionParams
|
|||
import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.GetAllowanceUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStateController
|
||||
|
|
@ -37,13 +35,11 @@ import java.math.BigDecimal
|
|||
@Suppress("LongParameterList")
|
||||
internal class StakingFeeTransactionLoader @AssistedInject constructor(
|
||||
private val stateController: StakingStateController,
|
||||
private val getAllowanceUseCase: GetAllowanceUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val estimateGasUseCase: EstimateGasUseCase,
|
||||
@Assisted private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
@Assisted private val yield: Yield,
|
||||
@Assisted private val stakingApproval: StakingApproval,
|
||||
) {
|
||||
|
||||
suspend fun getFee(
|
||||
|
|
@ -66,31 +62,16 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor(
|
|||
|
||||
val validatorAddress = validatorState.chosenValidator.address
|
||||
|
||||
val approval = stakingApproval as? StakingApproval.Needed
|
||||
if (approval != null && state.actionType == StakingActionCommonType.Enter) {
|
||||
val allowance = getAllowanceUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
spenderAddress = approval.spenderAddress,
|
||||
).getOrElse { BigDecimal.ZERO }
|
||||
|
||||
if (allowance < amount) {
|
||||
getApproveFee(
|
||||
amount = amount,
|
||||
validatorAddress = validatorAddress,
|
||||
onApprovalFee = onApprovalFee,
|
||||
onApprovalFeeError = onFeeError,
|
||||
)
|
||||
} else {
|
||||
estimateGas(
|
||||
pendingAction = pendingAction,
|
||||
pendingActions = pendingActions,
|
||||
amount = amount,
|
||||
validatorAddress = validatorAddress,
|
||||
onStakingFeeError = onStakingFeeError,
|
||||
onStakingFee = onStakingFee,
|
||||
)
|
||||
}
|
||||
val isEnter = state.actionType == StakingActionCommonType.Enter
|
||||
val isApprovalNeeded = confirmationState.isApprovalNeeded
|
||||
val isAllowanceNotEnough = confirmationState.allowance < amount
|
||||
if (isEnter && isApprovalNeeded && isAllowanceNotEnough) {
|
||||
getApproveFee(
|
||||
amount = amount,
|
||||
validatorAddress = validatorAddress,
|
||||
onApprovalFee = onApprovalFee,
|
||||
onApprovalFeeError = onFeeError,
|
||||
)
|
||||
} else {
|
||||
estimateGas(
|
||||
pendingAction = pendingAction,
|
||||
|
|
@ -234,7 +215,6 @@ internal class StakingFeeTransactionLoader @AssistedInject constructor(
|
|||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
userWallet: UserWallet,
|
||||
yield: Yield,
|
||||
stakingApproval: StakingApproval,
|
||||
): StakingFeeTransactionLoader
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ internal object ConfirmationStatePreviewData {
|
|||
transactionDoneState = TransactionDoneState.Empty,
|
||||
pendingAction = null,
|
||||
isApprovalNeeded = false,
|
||||
allowance = BigDecimal.ZERO,
|
||||
reduceAmountBy = null,
|
||||
pendingActions = null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButton
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButtonsState
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
|
|
@ -9,6 +10,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.features.staking.impl.presentation.state.utils.getPendingActionTitle
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -116,13 +118,16 @@ internal class SetButtonsStateTransformer(
|
|||
}
|
||||
|
||||
private fun StakingUiState.getConfirmationButtonText(): TextReference {
|
||||
return if (confirmationState is StakingStates.ConfirmationState.Data) {
|
||||
val confirmationState = confirmationState as? StakingStates.ConfirmationState.Data
|
||||
val amountState = amountState as? AmountState.Data
|
||||
return if (confirmationState != null && amountState != null) {
|
||||
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
|
||||
resourceReference(R.string.common_close)
|
||||
} else {
|
||||
when (actionType) {
|
||||
StakingActionCommonType.Enter -> {
|
||||
if (confirmationState.isApprovalNeeded) {
|
||||
val amount = amountState.amountTextField.cryptoAmount.value.orZero()
|
||||
if (confirmationState.isApprovalNeeded && confirmationState.allowance < amount) {
|
||||
resourceReference(R.string.give_permission_title)
|
||||
} else {
|
||||
resourceReference(R.string.common_stake)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@ import com.tangem.features.staking.impl.presentation.state.utils.isTronStakedBal
|
|||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class SetConfirmationStateInitTransformer(
|
||||
private val isEnter: Boolean,
|
||||
private val stakingApproval: StakingApproval,
|
||||
private val stakingAllowance: BigDecimal,
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val pendingActions: ImmutableList<PendingAction>? = null,
|
||||
private val pendingAction: PendingAction? = pendingActions?.firstOrNull(),
|
||||
|
|
@ -60,6 +62,7 @@ internal class SetConfirmationStateInitTransformer(
|
|||
footerText = TextReference.EMPTY,
|
||||
transactionDoneState = TransactionDoneState.Empty,
|
||||
isApprovalNeeded = stakingApproval is StakingApproval.Needed,
|
||||
allowance = stakingAllowance,
|
||||
reduceAmountBy = null,
|
||||
pendingAction = pendingAction,
|
||||
pendingActions = pendingActions.takeIf { isComposePendingActions },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.confirmation
|
||||
|
||||
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 java.math.BigDecimal
|
||||
|
||||
internal class SetUpdatedAllowanceTransformer(
|
||||
private val allowance: BigDecimal,
|
||||
) : Transformer<StakingUiState> {
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
|
||||
return prevState.copy(
|
||||
confirmationState = confirmationState?.copy(allowance = allowance) ?: prevState.confirmationState,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,10 @@ import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.staking.*
|
||||
import com.tangem.domain.staking.GetActionsUseCase
|
||||
import com.tangem.domain.staking.InvalidatePendingTransactionsUseCase
|
||||
import com.tangem.domain.staking.IsAnyTokenStakedUseCase
|
||||
import com.tangem.domain.staking.IsApproveNeededUseCase
|
||||
import com.tangem.domain.staking.model.StakingApproval
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceItem
|
||||
import com.tangem.domain.staking.model.stakekit.PendingAction
|
||||
|
|
@ -63,6 +66,7 @@ import com.tangem.features.staking.impl.presentation.state.helpers.StakingTransa
|
|||
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.confirmation.SetUpdatedAllowanceTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.notifications.AddStakingNotificationsTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.notifications.DismissStakingNotificationsStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.validator.ValidatorSelectChangeTransformer
|
||||
|
|
@ -167,7 +171,6 @@ internal class StakingViewModel @Inject constructor(
|
|||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
userWallet = userWallet,
|
||||
yield = yield,
|
||||
stakingApproval = stakingApproval,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -192,6 +195,7 @@ internal class StakingViewModel @Inject constructor(
|
|||
)
|
||||
|
||||
private var stakingApproval: StakingApproval = StakingApproval.Empty
|
||||
private var stakingAllowance: BigDecimal = BigDecimal.ZERO
|
||||
private var isAmountSubtractAvailable: Boolean = false
|
||||
private var isAnyTokenStaked: Boolean = false
|
||||
private val allowanceTaskScheduler = SingleTaskScheduler<BigDecimal>()
|
||||
|
|
@ -357,6 +361,7 @@ internal class StakingViewModel @Inject constructor(
|
|||
isEnter = true,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
stakingApproval = stakingApproval,
|
||||
stakingAllowance = stakingAllowance,
|
||||
),
|
||||
ValidatorSelectChangeTransformer(
|
||||
selectedValidator = null,
|
||||
|
|
@ -651,9 +656,11 @@ internal class StakingViewModel @Inject constructor(
|
|||
}
|
||||
},
|
||||
onSuccess = { allowance ->
|
||||
stakingAllowance = allowance
|
||||
val amount = (value.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value
|
||||
?: error("No amount provided")
|
||||
if (allowance >= amount) {
|
||||
stateController.update(SetUpdatedAllowanceTransformer(allowance))
|
||||
getFee()
|
||||
allowanceTaskScheduler.cancelTask()
|
||||
}
|
||||
|
|
@ -730,8 +737,22 @@ internal class StakingViewModel @Inject constructor(
|
|||
this.stakingStateRouter = stateRouter
|
||||
}
|
||||
|
||||
private fun setupApprovalNeeded() {
|
||||
stakingApproval = isApproveNeededUseCase(cryptoCurrencyStatus.currency).getOrElse { StakingApproval.Empty }
|
||||
private suspend fun setupApprovalNeeded() {
|
||||
stakingApproval = isApproveNeededUseCase(cryptoCurrencyStatus.currency).fold(
|
||||
ifRight = { approval ->
|
||||
if (approval is StakingApproval.Needed) {
|
||||
stakingAllowance = getAllowanceUseCase(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
spenderAddress = approval.spenderAddress,
|
||||
).getOrElse { BigDecimal.ZERO }
|
||||
}
|
||||
approval
|
||||
},
|
||||
ifLeft = {
|
||||
StakingApproval.Empty
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun setupIsAnyTokenStaked() {
|
||||
|
|
@ -886,6 +907,7 @@ internal class StakingViewModel @Inject constructor(
|
|||
stakingApproval = stakingApproval,
|
||||
pendingActions = pendingActions,
|
||||
pendingAction = pendingAction,
|
||||
stakingAllowance = stakingAllowance,
|
||||
),
|
||||
ValidatorSelectChangeTransformer(
|
||||
selectedValidator = validator,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue