Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-04 15:03:46 +02:00
parent 46c3f635f9
commit ebd588756c
4 changed files with 158 additions and 52 deletions

View file

@ -3,6 +3,7 @@ package com.tangem.features.staking.impl.presentation.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
@ -397,62 +398,122 @@ internal class StakingModel @Inject constructor(
modelScope.launch {
stakingAnalyticSender.sendTransactionStakingClickedAnalytics(value)
stateController.update(SetConfirmationStateInProgressTransformer())
transactionSender.send(
StakingTransactionSender.Callbacks(
onConstructSuccess = { constructedTransactions ->
transactionsInProgress.addAll(constructedTransactions)
},
onConstructError = { error ->
stakingEventFactory.createStakingErrorAlert(error)
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
},
onSendSuccess = { txUrl ->
stakingAnalyticSender.sendTransactionStakingAnalytics(
stateController.value,
cryptoCurrencyStatus,
)
transactionsInProgress.clear()
stateController.update(
SetConfirmationStateCompletedTransformer(txUrl, cryptoCurrencyStatus),
)
},
onSendError = { error ->
analyticsEventHandler.send(
StakingAnalyticsEvent.TransactionError(
errorCode = error.getAnalyticsDescription(),
),
)
stakingEventFactory.createSendTransactionErrorAlert(error)
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
},
onFeeIncreased = { increasedFee, isFeeApproximate ->
stateController.updateAll(
SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus),
SetConfirmationStateAssentTransformer(
appCurrencyProvider = Provider { appCurrency },
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
fee = increasedFee,
isFeeApproximate = isFeeApproximate,
cryptoCurrencyStatus = cryptoCurrencyStatus,
),
)
stateController.updateEvent(
StakingEvent.ShowAlert(
StakingAlertUM.FeeIncreased(stateController::dismissAlert),
),
)
updateNotifications()
},
onTransactionExpired = {
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
getFee()
},
),
)
if (integration is P2PEthPoolIntegration) {
checkFeeAndSendP2PTransaction()
} else {
sendTransaction()
}
}.saveIn(sendTransactionJobHolder)
}
}
private suspend fun checkFeeAndSendP2PTransaction() {
val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
val currentFeeState = confirmationState?.feeState as? FeeState.Content
val currentFee = currentFeeState?.fee
var actualFee: Fee? = null
feeLoader.getFee(
onStakingFee = { fee, _ ->
actualFee = fee
},
onStakingFeeError = { error ->
stakingEventFactory.createStakingErrorAlert(error)
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
},
onApprovalFee = { },
onFeeError = { error ->
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
updateNotifications(error)
},
)
val newFee = actualFee ?: return
val currentFeeAmount = when (currentFee) {
is Fee.Common -> currentFee.amount.value ?: BigDecimal.ZERO
is Fee.Ethereum -> currentFee.amount.value ?: BigDecimal.ZERO
else -> BigDecimal.ZERO
}
val newFeeAmount = when (newFee) {
is Fee.Common -> newFee.amount.value ?: BigDecimal.ZERO
is Fee.Ethereum -> newFee.amount.value ?: BigDecimal.ZERO
else -> BigDecimal.ZERO
}
if (newFeeAmount > currentFeeAmount) {
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
stakingEventFactory.createNetworkFeeUpdatedAlert(
onConfirm = {
modelScope.launch {
stateController.update(UpdateConfirmationFeeTransformer(newFee))
stateController.update(SetConfirmationStateInProgressTransformer())
sendTransaction()
}
},
)
} else {
sendTransaction()
}
}
private suspend fun sendTransaction() {
transactionSender.send(
StakingTransactionSender.Callbacks(
onConstructSuccess = { constructedTransactions ->
transactionsInProgress.addAll(constructedTransactions)
},
onConstructError = { error ->
stakingEventFactory.createStakingErrorAlert(error)
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
},
onSendSuccess = { txUrl ->
stakingAnalyticSender.sendTransactionStakingAnalytics(
stateController.value,
cryptoCurrencyStatus,
)
transactionsInProgress.clear()
stateController.update(
SetConfirmationStateCompletedTransformer(txUrl, cryptoCurrencyStatus),
)
},
onSendError = { error ->
analyticsEventHandler.send(
StakingAnalyticsEvent.TransactionError(
errorCode = error.getAnalyticsDescription(),
),
)
stakingEventFactory.createSendTransactionErrorAlert(error)
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
},
onFeeIncreased = { increasedFee, isFeeApproximate ->
stateController.updateAll(
SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus),
SetConfirmationStateAssentTransformer(
appCurrencyProvider = Provider { appCurrency },
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
fee = increasedFee,
isFeeApproximate = isFeeApproximate,
cryptoCurrencyStatus = cryptoCurrencyStatus,
),
)
stateController.updateEvent(
StakingEvent.ShowAlert(
StakingAlertUM.FeeIncreased(stateController::dismissAlert),
),
)
updateNotifications()
},
onTransactionExpired = {
stateController.update(SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus))
getFee()
},
),
)
}
override fun onPrevClick() {
if (value.currentStep == StakingStep.Confirmation) {
val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data

View file

@ -74,4 +74,12 @@ internal sealed class StakingAlertUM : AlertUM {
)
override val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
}
data class NetworkFeeUpdated(
override val onConfirmClick: () -> Unit,
) : StakingAlertUM() {
override val title: TextReference = resourceReference(R.string.staking_alert_network_fee_updated_title)
override val message: TextReference = resourceReference(R.string.staking_alert_network_fee_updated_message)
override val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
}
}

View file

@ -57,4 +57,13 @@ internal class StakingEventFactory(
),
)
}
fun createNetworkFeeUpdatedAlert(onConfirm: () -> Unit) {
val alert = StakingEvent.ShowAlert(
alert = StakingAlertUM.NetworkFeeUpdated(
onConfirmClick = onConfirm,
),
)
stateController.updateEvent(alert)
}
}

View file

@ -0,0 +1,28 @@
package com.tangem.features.staking.impl.presentation.state.transformers
import com.tangem.blockchain.common.transaction.Fee
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.utils.transformer.Transformer
internal class UpdateConfirmationFeeTransformer(
private val newFee: Fee,
) : Transformer<StakingUiState> {
override fun transform(prevState: StakingUiState): StakingUiState {
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
?: return prevState
val currentFeeState = confirmationState.feeState as? FeeState.Content
?: return prevState
val updatedFeeState = currentFeeState.copy(fee = newFee)
return prevState.copy(
confirmationState = confirmationState.copy(
feeState = updatedFeeState,
),
)
}
}