diff --git a/data/staking/src/main/java/com/tangem/data/staking/PendingTransactionItemConverter.kt b/data/staking/src/main/java/com/tangem/data/staking/PendingTransactionItemConverter.kt index a18b61f591..6169fc2b96 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/PendingTransactionItemConverter.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/PendingTransactionItemConverter.kt @@ -10,8 +10,8 @@ internal object PendingTransactionItemConverter : Converter, + yieldBalance: YieldBalance.Data, pending: List>, ): Pair, List> { - val map = real.associateBy { Triple(it.groupId, it.type, it.amount) }.toMutableMap() + val balances = yieldBalance.balance.items.associateBy { Triple(it.groupId, it.type, it.amount) }.toMutableMap() + val newBalancesId = yieldBalance.getBalancesUniqueId() - val toRemove = mutableListOf() + val transactionsToRemove = mutableListOf() pending.forEach { (pendingTransaction, balanceItem) -> val key = Triple(balanceItem.groupId, balanceItem.type, balanceItem.amount) - if (map.containsKey(key)) { - map[key] = balanceItem - } else { - toRemove.add(pendingTransaction) + val oldBalancesId = pendingTransaction.balancesId + + when { + newBalancesId != oldBalancesId -> { + transactionsToRemove.add(pendingTransaction) + } + balances.containsKey(key) -> { + balances[key] = balanceItem + } + else -> { + val groupId = UUID.randomUUID().toString() + balances[Triple(groupId, BalanceType.STAKED, pendingTransaction.amount)] = BalanceItem( + groupId = groupId, + type = pendingTransaction.type, + amount = pendingTransaction.amount, + rawCurrencyId = pendingTransaction.rawCurrencyId, + validatorAddress = pendingTransaction.validator?.address, + date = null, + pendingActions = emptyList(), + isPending = true, + ) + } } } - return map.values.toList() to toRemove + return balances.values.toList() to transactionsToRemove } } \ 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 c490284116..4bc8b84bda 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 @@ -9,6 +9,7 @@ import com.tangem.core.ui.components.list.RoundedListWithDividersItemData import com.tangem.core.ui.event.StateEvent import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.pullToRefresh.PullToRefreshConfig +import com.tangem.domain.staking.model.PendingTransaction import com.tangem.domain.staking.model.stakekit.PendingAction import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType @@ -98,7 +99,7 @@ internal sealed class StakingStates { val transactionDoneState: TransactionDoneState, val isApprovalNeeded: Boolean, val reduceAmountBy: BigDecimal?, - val balanceState: BalanceState?, + val possiblePendingTransaction: PendingTransaction?, ) : ConfirmationState() data class Empty( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt index 57f98b373b..7edd7024b0 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt @@ -8,10 +8,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.domain.staking.* import com.tangem.domain.staking.model.PendingTransaction import com.tangem.domain.staking.model.SubmitHashData -import com.tangem.domain.staking.model.stakekit.BalanceType -import com.tangem.domain.staking.model.stakekit.PendingAction -import com.tangem.domain.staking.model.stakekit.StakingError -import com.tangem.domain.staking.model.stakekit.Yield +import com.tangem.domain.staking.model.stakekit.* import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.model.stakekit.transaction.ActionParams import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction @@ -35,6 +32,7 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import timber.log.Timber import java.math.BigDecimal +import java.util.UUID @Suppress("LongParameterList") internal class StakingTransactionSender @AssistedInject constructor( @@ -91,12 +89,16 @@ internal class StakingTransactionSender @AssistedInject constructor( sendStakingTransaction( fullTransactionsData = fullTransactionsData, - balanceState = confirmationState.balanceState, + possiblePendingTransaction = composePendingTransaction(confirmationState), onSendSuccess = onSendSuccess, onSendError = onSendError, ) } + private fun composePendingTransaction(confirmationState: StakingStates.ConfirmationState.Data): PendingTransaction { + return confirmationState.possiblePendingTransaction ?: composeStakeTransaction(confirmationState) + } + private suspend fun getStakingTransactions( state: StakingUiState, confirmationState: StakingStates.ConfirmationState.Data, @@ -204,7 +206,7 @@ internal class StakingTransactionSender @AssistedInject constructor( private suspend fun sendStakingTransaction( fullTransactionsData: List, - balanceState: BalanceState?, + possiblePendingTransaction: PendingTransaction, onSendSuccess: (txUrl: String) -> Unit, onSendError: (SendTransactionError?) -> Unit, ) { @@ -218,13 +220,9 @@ internal class StakingTransactionSender @AssistedInject constructor( }, ifRight = { transactionHashes -> submitHash( - transactionIds = fullTransactionsData.map { it.stakeKitTransaction.id }, + transactions = fullTransactionsData.map { it.stakeKitTransaction }, transactionHashes = transactionHashes, - groupId = balanceState?.groupId, - validator = balanceState?.validator, - amount = balanceState?.cryptoDecimal, - balanceType = balanceState?.type, - rawCurrencyId = balanceState?.rawCurrencyId, + pendingTransaction = possiblePendingTransaction, ) val txUrl = getExplorerTransactionUrlUseCase( txHash = transactionHashes.last(), @@ -238,25 +236,18 @@ internal class StakingTransactionSender @AssistedInject constructor( } private suspend fun submitHash( - transactionIds: List, + transactions: List, transactionHashes: List, - groupId: String?, - validator: Yield.Validator?, - amount: BigDecimal?, - balanceType: BalanceType?, - rawCurrencyId: String?, + pendingTransaction: PendingTransaction, ) { - transactionIds + transactions .zip(transactionHashes) - .forEach { (transactionId, transactionHash) -> + .forEach { (transaction, transactionHash) -> submitHashUseCase( SubmitHashData( - transactionId = transactionId, + transactionId = transaction.id, transactionHash = transactionHash, - validator = validator, - amount = amount, - balanceType = balanceType, - rawCurrencyId = rawCurrencyId, + pendingTransaction = pendingTransaction, ), ) .onLeft { error -> @@ -267,20 +258,14 @@ internal class StakingTransactionSender @AssistedInject constructor( ), ) saveUnsubmittedHashUseCase.invoke( - transactionId = transactionId, + transactionId = transaction.id, transactionHash = transactionHash, ) }.onRight { Timber.d("Successful hash submission") - savePendingTransactionUseCase.invoke( - PendingTransaction( - groupId = groupId, - type = balanceType, - amount = amount, - rawCurrencyId = rawCurrencyId, - validator = validator, - ), - ) + if (transaction.type != StakingTransactionType.FREEZE_ENERGY) { + savePendingTransactionUseCase.invoke(pendingTransaction) + } } } } @@ -299,6 +284,19 @@ internal class StakingTransactionSender @AssistedInject constructor( ) } + private fun composeStakeTransaction(confirmationState: StakingStates.ConfirmationState.Data): PendingTransaction { + val state = stateController.value + + return PendingTransaction( + groupId = UUID.randomUUID().toString(), + type = BalanceType.STAKED, + amount = (state.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value ?: BigDecimal.ZERO, + rawCurrencyId = cryptoCurrencyStatus.currency.id.rawCurrencyId, + validator = (confirmationState.validatorState as? ValidatorState.Content)?.chosenValidator, + balancesId = (cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data)?.getBalancesUniqueId() ?: 0, + ) + } + private data class FullTransactionData( val stakeKitTransaction: StakingTransaction, val tangemTransaction: TransactionData.Compiled, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt index 51b7ec69a2..e68d171b89 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/ConfirmationStatePreviewData.kt @@ -93,6 +93,6 @@ internal object ConfirmationStatePreviewData { isApprovalNeeded = false, reduceAmountBy = null, pendingActions = null, - balanceState = null, + possiblePendingTransaction = null, ) } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetBalanceStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetBalanceStateTransformer.kt deleted file mode 100644 index d6fae7cd7f..0000000000 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetBalanceStateTransformer.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.features.staking.impl.presentation.state.transformers - -import com.tangem.features.staking.impl.presentation.state.* -import com.tangem.utils.transformer.Transformer - -internal class SetBalanceStateTransformer( - private val balanceState: BalanceState? = null, -) : Transformer { - - override fun transform(prevState: StakingUiState): StakingUiState { - val possibleConfirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data - ?: return prevState - - return prevState.copy( - confirmationState = possibleConfirmationState.copy(balanceState = balanceState), - ) - } -} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt index c2df5db972..1fcfee71c7 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt @@ -41,7 +41,7 @@ internal class SetConfirmationStateLoadingTransformer( pendingActions = possibleConfirmationState?.pendingActions, isApprovalNeeded = false, reduceAmountBy = null, - balanceState = null, + possiblePendingTransaction = null, ), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index 66b56ea7aa..5bd24b5b92 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -231,7 +231,7 @@ internal class SetInitialDataStateTransformer( pendingActions = null, isApprovalNeeded = isApprovalNeeded, reduceAmountBy = null, - balanceState = null, + possiblePendingTransaction = null, ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetPossiblePendingTransactionTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetPossiblePendingTransactionTransformer.kt new file mode 100644 index 0000000000..a176330f37 --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetPossiblePendingTransactionTransformer.kt @@ -0,0 +1,33 @@ +package com.tangem.features.staking.impl.presentation.state.transformers + +import com.tangem.domain.staking.model.PendingTransaction +import com.tangem.domain.staking.model.stakekit.YieldBalance +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.features.staking.impl.presentation.state.* +import com.tangem.utils.transformer.Transformer + +internal class SetPossiblePendingTransactionTransformer( + private val balanceState: BalanceState, + private val cryptoCurrencyStatus: CryptoCurrencyStatus, +) : Transformer { + + override fun transform(prevState: StakingUiState): StakingUiState { + val possibleConfirmationState = + prevState.confirmationState as? StakingStates.ConfirmationState.Data ?: return prevState + + val balancesId = (cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data)?.getBalancesUniqueId() ?: 0 + + return prevState.copy( + confirmationState = possibleConfirmationState.copy( + possiblePendingTransaction = PendingTransaction( + groupId = balanceState.groupId, + type = balanceState.type, + amount = balanceState.cryptoDecimal, + rawCurrencyId = balanceState.rawCurrencyId, + validator = balanceState.validator, + balancesId = balancesId, + ), + ), + ) + } +} \ No newline at end of file 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 b138f2c300..986ca6b285 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 @@ -219,12 +219,17 @@ internal class StakingViewModel @Inject constructor( when { isInitState() -> { stateController.update(SetConfirmationStateLoadingTransformer(yield, appCurrency)) - stateController.update(SetBalanceStateTransformer(balanceState)) + if (balanceState != null) { + stateController.update(SetPossiblePendingTransactionTransformer(balanceState, cryptoCurrencyStatus)) + } + onRefreshSwipe(isRefreshing = false) } isAssentState() -> { getFee(pendingAction, pendingActions) - stateController.update(SetBalanceStateTransformer(balanceState)) + if (balanceState != null) { + stateController.update(SetPossiblePendingTransactionTransformer(balanceState, cryptoCurrencyStatus)) + } val amountState = value.amountState as? AmountState.Data if (amountState?.amountTextField?.isWarning == true) { stateController.update(