diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt index a27e52d22e..daf1ce408b 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt @@ -3,6 +3,7 @@ package com.tangem.tap.domain.userWalletList.implementation import com.tangem.common.* import com.tangem.domain.wallets.legacy.UserWalletsListError import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey @@ -56,8 +57,8 @@ internal class BiometricUserWalletsListManager( override val walletsCount: Int get() = state.value.userWallets.size - override suspend fun unlock(throwIfNotAllWalletsUnlocked: Boolean): CompletionResult { - return unlockWithBiometryInternal() + override suspend fun unlock(type: UnlockType): CompletionResult { + return unlockAndSetSelectedUserWallet(type) .mapFailure { error -> Timber.e(error, "Unable to unlock user wallets") if (error is UserWalletsListError) { @@ -66,16 +67,8 @@ internal class BiometricUserWalletsListManager( UserWalletsListError.UnableToUnlockUserWallets(error) } } - .map { - val userWallets = state.value.userWallets - - if (throwIfNotAllWalletsUnlocked && userWallets.any(UserWallet::isLocked)) { - Timber.e("Some user wallets remain locked") - throw UserWalletsListError.NotAllUserWalletsUnlocked - } - - val selectedUserWallet = selectedUserWalletSync - if (selectedUserWallet == null) { + .map { selectedUserWallet -> + if (selectedUserWallet == null || selectedUserWallet.isLocked) { Timber.e("Unable to find selected user wallet") throw UserWalletsListError.NoUserWalletSelected } else { @@ -186,99 +179,116 @@ internal class BiometricUserWalletsListManager( changeSelectedUserWallet: Boolean, canOverridePublicInfo: Boolean, ): CompletionResult { - return saveEncryptionKeyIfNotNull(userWallet) - .flatMap { sensitiveInformationRepository.save(userWallet, encryptionKey = it) } - .flatMap { publicInformationRepository.save(userWallet, canOverridePublicInfo) } - .map { - if (changeSelectedUserWallet) { - selectedUserWalletRepository.set(userWallet.walletId) - } - } - .flatMap { loadModels() } - .doOnSuccess { - state.update { prevState -> - prevState.copy( - selectedUserWalletId = if (changeSelectedUserWallet) { - userWallet.walletId - } else { - prevState.selectedUserWalletId - }, - isLocked = prevState.userWallets.any { it.isLocked }, - ) - } - } - } - - private suspend fun unlockWithBiometryInternal(): CompletionResult { - return keysRepository.getAll() - .map { keys -> - state.update { prevState -> - prevState.copy( - encryptionKeys = (keys + prevState.encryptionKeys).distinctBy { it.walletId }, - ) - } - } - .flatMap { loadModels() } - .map { - state.update { prevState -> - val hasLockedUserWallets = prevState.userWallets.any { it.isLocked } - prevState.copy(isLocked = hasLockedUserWallets) - } - } - } - - private suspend fun saveEncryptionKeyIfNotNull(userWallet: UserWallet): CompletionResult { val encryptionKey = userWallet.scanResponse.card.encryptionKey ?.let { UserWalletEncryptionKey(userWallet.walletId, it) } + ?: return CompletionResult.Success(Unit) // No encryption key, no need to save - return if (encryptionKey != null) { - keysRepository.save(encryptionKey) - .doOnSuccess { - state.update { prevState -> - prevState.copy( - encryptionKeys = prevState.encryptionKeys - .plus(encryptionKey) - .distinctBy { it.walletId }, - ) - } + return keysRepository.save(encryptionKey) + .flatMap { sensitiveInformationRepository.save(userWallet, encryptionKey = encryptionKey.encryptionKey) } + .flatMap { publicInformationRepository.save(userWallet, canOverridePublicInfo) } + .flatMap { + loadUserWallets( + encryptionKeys = state.value.encryptionKeys + .plus(encryptionKey) + .distinctBy(UserWalletEncryptionKey::walletId), + ) + } + .doOnSuccess { loadedState -> + if (changeSelectedUserWallet) { + selectedUserWalletRepository.set(userWallet.walletId) + + state.value = loadedState.copy( + selectedUserWalletId = userWallet.walletId, + ) + } else { + state.value = loadedState } - .map { encryptionKey.encryptionKey } - } else { - CompletionResult.Success(data = null) - } + } + .map { /* Type erasing */ } } - private suspend fun loadModels(): CompletionResult { - return getSavedUserWallets() - .map { userWallets -> - if (userWallets.isNotEmpty()) { - state.update { prevState -> - val wallets = (userWallets + prevState.userWallets).distinctBy { it.walletId } + private suspend fun unlockAndSetSelectedUserWallet(type: UnlockType): CompletionResult { + return keysRepository.getAll() + .flatMap { encryptionKeys -> + loadUserWallets( + encryptionKeys = state.value.encryptionKeys + .plus(encryptionKeys) + .distinctBy(UserWalletEncryptionKey::walletId), + ) + } + .map { loadedState -> + when (type) { + UnlockType.ALL -> { + if (loadedState.isLocked) { + Timber.e("Some user wallets remain locked") - prevState.copy( - userWallets = wallets, - selectedUserWalletId = findOrSetSelectedWalletId(prevState.selectedUserWalletId, wallets), + state.value = loadedState + + throw UserWalletsListError.NotAllUserWalletsUnlocked + } else { + val selectedWallet = findOrSetSelectedWallet( + state.value.selectedUserWalletId, + loadedState.userWallets, + ) + + state.value = loadedState.copy( + selectedUserWalletId = selectedWallet?.walletId, + ) + + selectedWallet + } + } + UnlockType.ANY -> { + val selectedWallet = findOrSetSelectedWallet( + state.value.selectedUserWalletId, + loadedState.userWallets, ) + + state.value = loadedState.copy( + selectedUserWalletId = selectedWallet?.walletId, + ) + + selectedWallet + } + UnlockType.ALL_WITHOUT_SELECT -> { + state.value = loadedState + + findSelectedUserWallet() } } } } - private suspend fun getSavedUserWallets(): CompletionResult> { + private suspend fun loadUserWallets(encryptionKeys: List): CompletionResult { return publicInformationRepository.getAll() .map { it.toUserWallets() } .flatMap { userWallets -> - sensitiveInformationRepository.getAll(state.value.encryptionKeys) + sensitiveInformationRepository.getAll(encryptionKeys) .map { walletIdToSensitiveInformation -> userWallets.updateWith(walletIdToSensitiveInformation) } } + .map { userWallets -> + val prevState = state.value + + if (userWallets.isNotEmpty()) { + val newUserWallets = (userWallets + prevState.userWallets) + .distinctBy(UserWallet::walletId) + + prevState.copy( + userWallets = newUserWallets, + isLocked = newUserWallets.any(UserWallet::isLocked), + ) + } else { + prevState + } + } } - private fun findOrSetSelectedWalletId( + private fun findOrSetSelectedWallet( prevSelectedWalletId: UserWalletId?, userWallets: List, - ): UserWalletId? { + ): UserWallet? { val selectedWalletId = prevSelectedWalletId ?: selectedUserWalletRepository.get() var possibleSelectedUserWallet = findSelectedUserWallet(userWallets, selectedWalletId) @@ -290,7 +300,7 @@ internal class BiometricUserWalletsListManager( } } - return possibleSelectedUserWallet?.walletId + return possibleSelectedUserWallet } private fun changeSelectedUserWalletIdIfNeeded(walletsIdsToRemove: List) { diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt index 6fccee5d59..e0e160a524 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt @@ -100,10 +100,10 @@ internal class GeneralUserWalletsListManager( return implementation.value.get(userWalletId) } - override suspend fun unlock(throwIfNotAllWalletsUnlocked: Boolean): CompletionResult { + override suspend fun unlock(type: UserWalletsListManager.Lockable.UnlockType): CompletionResult { val implementation = implementation.value return if (implementation is UserWalletsListManager.Lockable) { - implementation.unlock() + implementation.unlock(type) } else { error("RuntimeUserWalletsListManager is not lockable") } diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DelegatedKeystoreManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DelegatedKeystoreManager.kt index f61d6df0d0..7e7a781189 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DelegatedKeystoreManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DelegatedKeystoreManager.kt @@ -14,7 +14,7 @@ internal class DelegatedKeystoreManager( override suspend fun get( masterKeyConfig: KeystoreManager.MasterKeyConfig, - keyAliases: Collection, + keyAliases: Set, ): Map { return keystoreManagerProvider().get(masterKeyConfig, keyAliases) } diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt index d04e0122b7..6f7c82d446 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt @@ -89,7 +89,6 @@ internal class BiometricUserWalletsKeysRepository( .doOnFailure { error -> when (error) { is TangemSdkError.KeystoreInvalidated -> { - // If the biometric cryptography key was invalidated, then delete all encryption keys getUserWalletsIds().forEach { userWalletId -> deleteEncryptionKey(userWalletId) } @@ -120,7 +119,7 @@ internal class BiometricUserWalletsKeysRepository( } private fun deleteEncryptionKey(userWalletId: UserWalletId) { - return authenticatedStorage.delete(StorageKey.UserWalletEncryptionKey(userWalletId).name) + authenticatedStorage.delete(StorageKey.UserWalletEncryptionKey(userWalletId).name) } private suspend fun getUserWalletsIds(): List { diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt index 5e03eed1a5..ca7d00d461 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt @@ -14,6 +14,7 @@ import com.tangem.core.navigation.NavigationAction import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.userwallets.UserWalletBuilder +import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.legacy.unlockIfLockable import com.tangem.tap.* import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter @@ -86,7 +87,7 @@ internal class WelcomeMiddleware { """.trimIndent(), ) - userWalletsListManager.unlockIfLockable() + userWalletsListManager.unlockIfLockable(type = UnlockType.ANY) .doOnFailure { error -> Timber.e(error, "Unable to unlock user wallets with biometrics") store.dispatchWithMain(WelcomeAction.ProceedWithBiometrics.Error(error)) diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt index 7211f73a66..8a63233bed 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt @@ -105,16 +105,42 @@ interface UserWalletsListManager { /** * Receive saved [UserWallet]s, populate [userWallets] flow with it and set [isLocked] as false. * - * @param throwIfNotAllWalletsUnlocked Indicates that the function must throw - * [UserWalletsListError.NotAllUserWalletsUnlocked] if not all user wallets are unlocked. + * @param type Defines the behavior of the operation. * * @return [CompletionResult] of operation, with selected [UserWallet] * or null if there is no selected [UserWallet] */ - suspend fun unlock(throwIfNotAllWalletsUnlocked: Boolean = false): CompletionResult + suspend fun unlock(type: UnlockType): CompletionResult /** Remove [UserWallet]s from [userWallets] and set [isLocked] as true */ fun lock() + + /** + * Defines the behavior of the [unlock] operation. + * */ + enum class UnlockType { + /** + * Ensures that all stored [UserWallet]s are unlocked, + * or throws [UserWalletsListError.NotAllUserWalletsUnlocked]. + * + * In this type [selectedUserWallet] is either a previously selected [UserWallet] or the first stored + * [UserWallet]. + * */ + ALL, + + /** + * Ensures that at least one stored [UserWallet] is unlocked, + * or throws [UserWalletsListError.NoUserWalletSelected]. + * + * In this type [selectedUserWallet] is the first stored and unlocked [UserWallet]. + * */ + ANY, + + /** + * Same as [ALL] type, but this type can not change [selectedUserWallet] while unlocking. + * */ + ALL_WITHOUT_SELECT, + } } // For provider diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt index aa65450d99..0003a1300d 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt @@ -1,6 +1,7 @@ package com.tangem.domain.wallets.legacy import com.tangem.common.CompletionResult +import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UserWallet import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @@ -43,8 +44,8 @@ val UserWalletsListManager.isLockedSync: Boolean * * @see UserWalletsListManager.Lockable.unlock * */ -suspend fun UserWalletsListManager.unlockIfLockable(): CompletionResult { - return asLockable()?.unlock() ?: CompletionResult.Failure(UserWalletsListError.UnableToUnlockUserWallets()) +suspend fun UserWalletsListManager.unlockIfLockable(type: UnlockType = UnlockType.ANY): CompletionResult { + return asLockable()?.unlock(type) ?: CompletionResult.Failure(UserWalletsListError.UnableToUnlockUserWallets()) } /** diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt index ae2ace600a..2b9c40ae27 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.firstOrNull class GetUserWalletUseCase(private val walletsStateHolder: WalletsStateHolder) { - suspend operator fun invoke(userWalletId: UserWalletId): Either = either { + suspend operator fun invoke(userWalletId: UserWalletId): Either = either { val userWalletsListManager = ensureUserWalletListManagerNotNull( walletsStateHolder = walletsStateHolder, raise = GetUserWalletError::DataError, diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt index 5ae878661a..9b6bdf4997 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt @@ -5,6 +5,7 @@ import arrow.core.raise.either import arrow.core.raise.ensureNotNull import com.tangem.common.doOnFailure import com.tangem.domain.wallets.legacy.UserWalletsListError +import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.legacy.WalletsStateHolder import com.tangem.domain.wallets.legacy.asLockable import com.tangem.domain.wallets.models.UnlockWalletsError @@ -18,27 +19,26 @@ import com.tangem.domain.wallets.models.UnlockWalletsError */ class UnlockWalletsUseCase(private val walletsStateHolder: WalletsStateHolder) { - suspend operator fun invoke(throwIfNotAllWalletsUnlocked: Boolean = false): Either = - either { - val userWalletsListManager = ensureNotNull( - value = walletsStateHolder.userWalletsListManager?.asLockable(), - raise = { - UnlockWalletsError.DataError( - cause = IllegalStateException("The lockable user wallets list manager could not be found"), - ) - }, - ) + suspend operator fun invoke(type: UnlockType = UnlockType.ANY): Either = either { + val userWalletsListManager = ensureNotNull( + value = walletsStateHolder.userWalletsListManager?.asLockable(), + raise = { + UnlockWalletsError.DataError( + cause = IllegalStateException("The lockable user wallets list manager could not be found"), + ) + }, + ) - userWalletsListManager.unlock(throwIfNotAllWalletsUnlocked) - .doOnFailure { error -> - val e = when (error) { - is UserWalletsListError.NoUserWalletSelected -> UnlockWalletsError.NoUserWalletSelected - is UserWalletsListError.NotAllUserWalletsUnlocked -> - UnlockWalletsError.NotAllUserWalletsUnlocked - else -> UnlockWalletsError.UnableToUnlockWallets - } - - raise(e) + userWalletsListManager.unlock(type) + .doOnFailure { error -> + val e = when (error) { + is UserWalletsListError.NoUserWalletSelected -> UnlockWalletsError.NoUserWalletSelected + is UserWalletsListError.NotAllUserWalletsUnlocked -> + UnlockWalletsError.NotAllUserWalletsUnlocked + else -> UnlockWalletsError.UnableToUnlockWallets } - } + + raise(e) + } + } } \ No newline at end of file diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt index 30ea8ec4cd..e3c5321be7 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt @@ -14,6 +14,7 @@ internal class ExchangeStatusConverter : Converter - if (balance.value.minus(spendAmount.value) > fee.multiply(percentsToFeeIncrease)) { + val balanceToCheck = when (fromTokenStatus.currency) { + is CryptoCurrency.Token -> { + balance.value + } + is CryptoCurrency.Coin -> { + // need to check balance minus amount only if amount to swap in native token + balance.value.minus(spendAmount.value) + } + } + if (balanceToCheck > fee.multiply(percentsToFeeIncrease)) { SwapFeeState.Enough } else { val nativeToken = getNativeToken(fromTokenStatus.currency.network.backendId) @@ -1510,9 +1519,9 @@ internal class SwapInteractorImpl @Inject constructor( } else { val token = currenciesRepository .getMultiCurrencyWalletCurrenciesSync(userWalletId) + .filterIsInstance() .find { - it is CryptoCurrency.Token && - it.contractAddress.equals(feePaidCurrency.contractAddress, ignoreCase = true) && + it.contractAddress.equals(feePaidCurrency.contractAddress, ignoreCase = true) && it.network.derivationPath == fromTokenStatus.currency.network.derivationPath } SwapFeeState.NotEnough( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletState.kt index 0792d8f25a..81c9017dee 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletState.kt @@ -32,19 +32,13 @@ internal sealed interface WalletState : WalletStateHolder { data class Locked( override val walletCardState: WalletCardState, + override val bottomSheetConfig: TangemBottomSheetConfig?, val onUnlockNotificationClick: () -> Unit, - val isBottomSheetShow: Boolean = false, - val onBottomSheetDismiss: () -> Unit = {}, - val onUnlockClick: () -> Unit, - val onScanClick: () -> Unit, ) : MultiCurrency(), WalletStateHolder by LockedWalletStateHolder( walletCardState, + bottomSheetConfig, onUnlockNotificationClick, - isBottomSheetShow, - onBottomSheetDismiss, - onUnlockClick, - onScanClick, ) { override val tokensListState = WalletTokensListState.ContentState.Locked @@ -70,21 +64,15 @@ internal sealed interface WalletState : WalletStateHolder { data class Locked( override val walletCardState: WalletCardState, override val buttons: PersistentList, + override val bottomSheetConfig: TangemBottomSheetConfig?, val onUnlockNotificationClick: () -> Unit, - val isBottomSheetShow: Boolean = false, - val onBottomSheetDismiss: () -> Unit = {}, - val onUnlockClick: () -> Unit, - val onScanClick: () -> Unit, val onExploreClick: () -> Unit, ) : SingleCurrency(), TxHistoryStateHolder by LockedTxHistoryStateHolder(onExploreClick), WalletStateHolder by LockedWalletStateHolder( walletCardState, + bottomSheetConfig, onUnlockNotificationClick, - isBottomSheetShow, - onBottomSheetDismiss, - onUnlockClick, - onScanClick, ) { override val marketPriceBlockState: MarketPriceBlockState? = null @@ -108,20 +96,14 @@ internal sealed interface WalletState : WalletStateHolder { data class Locked( override val walletCardState: WalletCardState, val onUnlockNotificationClick: () -> Unit, - val isBottomSheetShow: Boolean = false, - val onBottomSheetDismiss: () -> Unit = {}, - val onUnlockClick: () -> Unit, - val onScanClick: () -> Unit, + override val bottomSheetConfig: TangemBottomSheetConfig?, val onExploreClick: () -> Unit, ) : Visa(), TxHistoryStateHolder by LockedTxHistoryStateHolder(onExploreClick), WalletStateHolder by LockedWalletStateHolder( walletCardState, + bottomSheetConfig, onUnlockNotificationClick, - isBottomSheetShow, - onBottomSheetDismiss, - onUnlockClick, - onScanClick, ) { override val balancesAndLimitBlockState: BalancesAndLimitsBlockState? = null diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/holder/LockedWalletStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/holder/LockedWalletStateHolder.kt index 6c361d5da7..96bef56446 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/holder/LockedWalletStateHolder.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/holder/LockedWalletStateHolder.kt @@ -1,7 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.model.holder import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification import com.tangem.feature.wallet.presentation.wallet.state.model.WalletPullToRefreshConfig @@ -18,11 +17,8 @@ internal interface WalletStateHolder { internal class LockedWalletStateHolder( override val walletCardState: WalletCardState, + override val bottomSheetConfig: TangemBottomSheetConfig?, onUnlockNotificationClick: () -> Unit, - isBottomSheetShow: Boolean, - onBottomSheetDismiss: () -> Unit, - onUnlockClick: () -> Unit, - onScanClick: () -> Unit, ) : WalletStateHolder { override val pullToRefreshConfig: WalletPullToRefreshConfig @@ -31,13 +27,4 @@ internal class LockedWalletStateHolder( override val warnings: ImmutableList = persistentListOf( WalletNotification.UnlockWallets(onUnlockNotificationClick), ) - - override val bottomSheetConfig = TangemBottomSheetConfig( - isShow = isBottomSheetShow, - onDismissRequest = onBottomSheetDismiss, - content = WalletBottomSheetConfig.UnlockWallets( - onUnlockClick = onUnlockClick, - onScanClick = onScanClick, - ), - ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/CloseBottomSheetTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/CloseBottomSheetTransformer.kt index 81106b0db4..02dd3d93aa 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/CloseBottomSheetTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/CloseBottomSheetTransformer.kt @@ -7,18 +7,28 @@ internal class CloseBottomSheetTransformer(userWalletId: UserWalletId) : WalletS override fun transform(prevState: WalletState): WalletState { return when (prevState) { - is WalletState.MultiCurrency.Content -> { - prevState.copy(bottomSheetConfig = prevState.bottomSheetConfig?.copy(isShow = false)) - } - is WalletState.MultiCurrency.Locked -> prevState.copy(isBottomSheetShow = false) - is WalletState.SingleCurrency.Content -> { - prevState.copy(bottomSheetConfig = prevState.bottomSheetConfig?.copy(isShow = false)) - } - is WalletState.SingleCurrency.Locked -> prevState.copy(isBottomSheetShow = false) - is WalletState.Visa.Content -> prevState.copy( - bottomSheetConfig = prevState.bottomSheetConfig?.copy(isShow = false), + is WalletState.MultiCurrency.Content -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), + ) + is WalletState.MultiCurrency.Locked -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), + ) + is WalletState.SingleCurrency.Content -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), + ) + is WalletState.SingleCurrency.Locked -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), + ) + is WalletState.Visa.Content -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), + ) + is WalletState.Visa.Locked -> prevState.copy( + bottomSheetConfig = updateConfig(prevState), ) - is WalletState.Visa.Locked -> prevState.copy(isBottomSheetShow = false) } } + + private fun updateConfig(prevState: WalletState) = prevState.bottomSheetConfig?.copy( + isShow = false, + ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt index 7b94f4d770..73065cb197 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt @@ -13,7 +13,6 @@ import kotlinx.collections.immutable.toImmutableList internal class InitializeWalletsTransformer( private val selectedWalletIndex: Int, - private val selectedWallet: UserWallet, private val wallets: List, private val clickIntents: WalletClickIntents, ) : WalletScreenStateTransformer { @@ -23,7 +22,7 @@ internal class InitializeWalletsTransformer( override fun transform(prevState: WalletScreenState): WalletScreenState { return prevState.copy( onBackClick = clickIntents::onBackClick, - topBarConfig = createTopBarConfig(userWallet = selectedWallet), + topBarConfig = createTopBarConfig(), selectedWalletIndex = selectedWalletIndex, wallets = wallets .map { userWallet -> @@ -38,13 +37,9 @@ internal class InitializeWalletsTransformer( ) } - private fun createTopBarConfig(userWallet: UserWallet): WalletTopBarConfig { + private fun createTopBarConfig(): WalletTopBarConfig { return WalletTopBarConfig( - onDetailsClick = if (userWallet.isLocked) { - clickIntents::onOpenUnlockWalletsBottomSheetClick - } else { - clickIntents::onDetailsClick - }, + onDetailsClick = clickIntents::onDetailsClick, ) } @@ -53,27 +48,24 @@ internal class InitializeWalletsTransformer( multiCurrencyCreator = { WalletState.MultiCurrency.Locked( walletCardState = userWallet.toLockedWalletCardState(), + bottomSheetConfig = null, onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, - onUnlockClick = clickIntents::onUnlockWalletClick, - onScanClick = clickIntents::onScanToUnlockWalletClick, ) }, singleCurrencyCreator = { WalletState.SingleCurrency.Locked( walletCardState = userWallet.toLockedWalletCardState(), + bottomSheetConfig = null, buttons = createDisabledButtons(), onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, - onUnlockClick = clickIntents::onUnlockWalletClick, - onScanClick = clickIntents::onScanToUnlockWalletClick, onExploreClick = clickIntents::onExploreClick, ) }, visaWalletCreator = { WalletState.Visa.Locked( walletCardState = userWallet.toLockedWalletCardState(), + bottomSheetConfig = null, onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, - onUnlockClick = clickIntents::onUnlockWalletClick, - onScanClick = clickIntents::onScanToUnlockWalletClick, onExploreClick = clickIntents::onExploreClick, ) }, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/OpenBottomSheetTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/OpenBottomSheetTransformer.kt index 141f4a57d0..69417c564c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/OpenBottomSheetTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/OpenBottomSheetTransformer.kt @@ -13,41 +13,30 @@ internal class OpenBottomSheetTransformer( override fun transform(prevState: WalletState): WalletState { return when (prevState) { - is WalletState.MultiCurrency.Content -> { - prevState.copy( - bottomSheetConfig = TangemBottomSheetConfig( - isShow = true, - onDismissRequest = onDismissBottomSheet, - content = content, - ), - ) - } - is WalletState.MultiCurrency.Locked -> { - prevState.copy(isBottomSheetShow = true, onBottomSheetDismiss = onDismissBottomSheet) - } - is WalletState.SingleCurrency.Content -> { - prevState.copy( - bottomSheetConfig = TangemBottomSheetConfig( - isShow = true, - onDismissRequest = onDismissBottomSheet, - content = content, - ), - ) - } - is WalletState.SingleCurrency.Locked -> { - prevState.copy(isBottomSheetShow = true, onBottomSheetDismiss = onDismissBottomSheet) - } + is WalletState.MultiCurrency.Content -> prevState.copy( + bottomSheetConfig = updateConfig(), + ) + is WalletState.MultiCurrency.Locked -> prevState.copy( + bottomSheetConfig = updateConfig(), + ) + is WalletState.SingleCurrency.Content -> prevState.copy( + bottomSheetConfig = updateConfig(), + ) + is WalletState.SingleCurrency.Locked -> prevState.copy( + bottomSheetConfig = updateConfig(), + ) is WalletState.Visa.Content -> prevState.copy( - bottomSheetConfig = TangemBottomSheetConfig( - isShow = true, - onDismissRequest = onDismissBottomSheet, - content = content, - ), + bottomSheetConfig = updateConfig(), ) is WalletState.Visa.Locked -> prevState.copy( - isBottomSheetShow = true, - onBottomSheetDismiss = onDismissBottomSheet, + bottomSheetConfig = updateConfig(), ) } } + + private fun updateConfig() = TangemBottomSheetConfig( + isShow = true, + onDismissRequest = onDismissBottomSheet, + content = content, + ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt index f22dedbc22..be16388c83 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt @@ -4,7 +4,6 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTopBarConfig import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletLoadingStateFactory import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents import kotlinx.collections.immutable.toImmutableList @@ -19,7 +18,6 @@ internal class UnlockWalletTransformer( override fun transform(prevState: WalletScreenState): WalletScreenState { return prevState.copy( - topBarConfig = prevState.topBarConfig.toUnlockedState(), wallets = prevState.wallets .map { state -> val unlockedWallet = getUnlockedWallet(state.walletCardState.id) @@ -29,10 +27,6 @@ internal class UnlockWalletTransformer( ) } - private fun WalletTopBarConfig.toUnlockedState(): WalletTopBarConfig { - return copy(onDetailsClick = clickIntents::onDetailsClick) - } - private fun getUnlockedWallet(walletId: UserWalletId): UserWallet? { return unlockedWallets.firstOrNull { it.walletId == walletId } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt index 16876a9396..0e76d03e34 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt @@ -8,7 +8,7 @@ import com.tangem.domain.tokens.model.TokenActionsState import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.state.model.TokenActionButtonConfig -import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletCurrencyActionsClickIntentsImplementor +import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletCurrencyActionsClickIntents import com.tangem.utils.converter.Converter import com.tangem.utils.isNullOrZero import kotlinx.collections.immutable.ImmutableList @@ -16,7 +16,7 @@ import kotlinx.collections.immutable.toImmutableList internal class MultiWalletCurrencyActionsConverter( private val userWallet: UserWallet, - private val clickIntents: WalletCurrencyActionsClickIntentsImplementor, + private val clickIntents: WalletCurrencyActionsClickIntents, ) : Converter> { override fun convert(value: TokenActionsState): ImmutableList { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index 467f87f0fa..dab3f9be92 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -199,7 +199,6 @@ internal class WalletViewModel @Inject constructor( stateHolder.update( transformer = InitializeWalletsTransformer( selectedWalletIndex = action.selectedWalletIndex, - selectedWallet = action.selectedWallet, wallets = action.wallets, clickIntents = clickIntents, ), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletClickIntents.kt index c27ff4424e..3cf99441ab 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletClickIntents.kt @@ -26,7 +26,7 @@ import javax.inject.Inject @ViewModelScoped internal class WalletClickIntents @Inject constructor( private val walletCardClickIntentsImplementor: WalletCardClickIntentsImplementor, - private val warningsClickIntentsImplementer: WalletWarningsClickIntentsImplementer, + private val warningsClickIntentsImplementer: WalletWarningsClickIntentsImplementor, private val currencyActionsClickIntentsImplementor: WalletCurrencyActionsClickIntentsImplementor, private val contentClickIntentsImplementor: WalletContentClickIntentsImplementor, private val visaWalletIntentsImplementor: VisaWalletIntentsImplementor, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt index 3ebb1b4830..a91eec17a0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels.intents +import arrow.core.getOrElse import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase @@ -9,17 +10,19 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.TokenActionsState import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.wallets.models.UserWallet -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase +import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.wallet.presentation.wallet.analytics.PortfolioEvent import com.tangem.feature.wallet.presentation.wallet.domain.unwrap import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.model.ActionsBottomSheetConfig +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCurrencyActionsConverter import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.scopes.ViewModelScoped import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject internal interface WalletContentClickIntents { @@ -43,8 +46,9 @@ internal interface WalletContentClickIntents { @ViewModelScoped internal class WalletContentClickIntentsImplementor @Inject constructor( private val stateHolder: WalletStateController, - private val currencyActionsClickIntentsImplementor: WalletCurrencyActionsClickIntentsImplementor, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, + private val currencyActionsClickIntents: WalletCurrencyActionsClickIntentsImplementor, + private val walletWarningsClickIntents: WalletWarningsClickIntentsImplementor, + private val getUserWalletUseCase: GetUserWalletUseCase, private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase, private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase, private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase, @@ -55,7 +59,33 @@ internal class WalletContentClickIntentsImplementor @Inject constructor( override fun onBackClick() = router.popBackStack() - override fun onDetailsClick() = router.openDetailsScreen() + override fun onDetailsClick() { + viewModelScope.launch(dispatchers.main) { + val userWalletId = stateHolder.getSelectedWalletId() + val userWallet = getUserWalletUseCase(userWalletId).getOrElse { + Timber.e( + """ + Unable to get user wallet + |- ID: $userWalletId + |- Exception: $it + """.trimIndent(), + ) + + return@launch + } + + if (userWallet.isLocked) { + stateHolder.showBottomSheet( + WalletBottomSheetConfig.UnlockWallets( + onUnlockClick = walletWarningsClickIntents::onUnlockWalletClick, + onScanClick = walletWarningsClickIntents::onScanToUnlockWalletClick, + ), + ) + } else { + router.openDetailsScreen() + } + } + } override fun onManageTokensClick() { analyticsEventHandler.send(PortfolioEvent.ButtonManageTokens) @@ -74,9 +104,20 @@ internal class WalletContentClickIntentsImplementor @Inject constructor( } override fun onTokenItemLongClick(cryptoCurrencyStatus: CryptoCurrencyStatus) { - val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return - viewModelScope.launch(dispatchers.main) { + val userWalletId = stateHolder.getSelectedWalletId() + val userWallet = getUserWalletUseCase(userWalletId).getOrElse { + Timber.e( + """ + Unable to get user wallet + |- ID: $userWalletId + |- Exception: $it + """.trimIndent(), + ) + + return@launch + } + getCryptoCurrencyActionsUseCase(userWallet = userWallet, cryptoCurrencyStatus = cryptoCurrencyStatus) .take(count = 1) .collectLatest { @@ -90,7 +131,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor( ActionsBottomSheetConfig( actions = MultiWalletCurrencyActionsConverter( userWallet = userWallet, - clickIntents = currencyActionsClickIntentsImplementor, + clickIntents = currencyActionsClickIntents, ).convert(tokenActionsState), ), userWallet.walletId, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt index 5f6133df1b..f16f13dda2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels.intents +import arrow.core.getOrElse import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.ui.extensions.resourceReference @@ -12,17 +13,19 @@ import com.tangem.domain.settings.RemindToRateAppLaterUseCase import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase import com.tangem.domain.tokens.FetchTokenListUseCase import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UnlockWalletsError -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletClickHandler import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletError -import com.tangem.feature.wallet.presentation.wallet.domain.unwrap import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender @@ -57,17 +60,17 @@ internal interface WalletWarningsClickIntents { @Suppress("LongParameterList") @ViewModelScoped -internal class WalletWarningsClickIntentsImplementer @Inject constructor( +internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val stateHolder: WalletStateController, private val walletEventSender: WalletEventSender, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val unlockWalletsUseCase: UnlockWalletsUseCase, private val derivePublicKeysUseCase: DerivePublicKeysUseCase, - private val scanCardToUnlockWalletClickHandler: ScanCardToUnlockWalletClickHandler, private val fetchTokenListUseCase: FetchTokenListUseCase, private val setCardWasScannedUseCase: SetCardWasScannedUseCase, private val neverToSuggestRateAppUseCase: NeverToSuggestRateAppUseCase, private val remindToRateAppLaterUseCase: RemindToRateAppLaterUseCase, + private val getUserWalletUseCase: GetUserWalletUseCase, + private val scanCardToUnlockWalletClickHandler: ScanCardToUnlockWalletClickHandler, + private val unlockWalletsUseCase: UnlockWalletsUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val reduxStateHolder: ReduxStateHolder, private val dispatchers: CoroutineDispatcherProvider, @@ -82,31 +85,33 @@ internal class WalletWarningsClickIntentsImplementer @Inject constructor( } private fun prepareOnboardingProcess() { - getSelectedWalletSyncUseCase.unwrap()?.let { - reduxStateHolder.dispatch( - LegacyAction.StartOnboardingProcess( - scanResponse = it.scanResponse, - canSkipBackup = false, - ), - ) + viewModelScope.launch(dispatchers.main) { + getSelectedUserWallet()?.let { + reduxStateHolder.dispatch( + LegacyAction.StartOnboardingProcess( + scanResponse = it.scanResponse, + canSkipBackup = false, + ), + ) + } } } override fun onCloseAlreadySignedHashesWarningClick() { - val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return - viewModelScope.launch(dispatchers.main) { + val userWallet = getSelectedUserWallet() ?: return@launch + setCardWasScannedUseCase(cardId = userWallet.cardId) } } override fun onGenerateMissedAddressesClick(missedAddressCurrencies: List) { - val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return - analyticsEventHandler.send(Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main)) analyticsEventHandler.send(MainScreen.NoticeScanYourCardTapped) viewModelScope.launch(dispatchers.main) { + val userWallet = getSelectedUserWallet() ?: return@launch + derivePublicKeysUseCase( userWalletId = userWallet.walletId, currencies = missedAddressCurrencies, @@ -119,18 +124,19 @@ internal class WalletWarningsClickIntentsImplementer @Inject constructor( override fun onOpenUnlockWalletsBottomSheetClick() { analyticsEventHandler.send(MainScreen.WalletUnlockTapped) - val config = requireNotNull(stateHolder.getSelectedWallet().bottomSheetConfig) { - "Impossible to open unlock wallet bottom sheet if it's null" - } - - stateHolder.showBottomSheet(config.content) + stateHolder.showBottomSheet( + WalletBottomSheetConfig.UnlockWallets( + onUnlockClick = this::onUnlockWalletClick, + onScanClick = this::onScanToUnlockWalletClick, + ), + ) } override fun onUnlockWalletClick() { analyticsEventHandler.send(MainScreen.UnlockAllWithBiometrics) viewModelScope.launch(dispatchers.main) { - unlockWalletsUseCase(throwIfNotAllWalletsUnlocked = true) + unlockWalletsUseCase(type = UnlockType.ALL_WITHOUT_SELECT) .onRight { stateHolder.update(CloseBottomSheetTransformer(stateHolder.getSelectedWalletId())) } .onLeft(::handleUnlockWalletsError) } @@ -204,4 +210,19 @@ internal class WalletWarningsClickIntentsImplementer @Inject constructor( shouldShowSwapPromoWalletUseCase.neverToShow() } } + + private suspend fun getSelectedUserWallet(): UserWallet? { + val userWalletId = stateHolder.getSelectedWalletId() + return getUserWalletUseCase(userWalletId).getOrElse { + Timber.e( + """ + Unable to get user wallet + |- ID: $userWalletId + |- Exception: $it + """.trimIndent(), + ) + + null + } + } } \ No newline at end of file diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 49cdba9902..7e5893d613 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -85,9 +85,9 @@ web3j = "4.10.1" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_5.8-529" +tangemBlockchainSdk = "release-app_5.8-533" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "release-app_5.8-335" +tangemCardSdk = "release-app_5.8-336" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ # endregion Tangem