Updated on 2026-08-14
This commit is contained in:
parent
53926e0843
commit
4d8930951c
6 changed files with 122 additions and 43 deletions
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.domain
|
||||
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
@ViewModelScoped
|
||||
class HasSingleWalletSignedHashesUseCase @Inject constructor(
|
||||
private val cardRepository: CardRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
operator fun invoke(userWallet: UserWallet, network: Network): Flow<Boolean> {
|
||||
return cardRepository.wasCardScanned(cardId = userWallet.cardId)
|
||||
.map { wasCardScanned ->
|
||||
if (wasCardScanned || !userWallet.isCorrectCardType()) return@map false
|
||||
|
||||
if (!userWallet.scanResponse.cardTypesResolver.hasWalletSignedHashes()) {
|
||||
cardRepository.setCardWasScanned(cardId = userWallet.cardId)
|
||||
return@map false
|
||||
}
|
||||
|
||||
return@map walletManagersFacade.validateSignatureCount(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = network,
|
||||
signedHashes = userWallet.scanResponse.card.wallets.firstOrNull()?.totalSignedHashes ?: 0,
|
||||
)
|
||||
.fold(
|
||||
ifLeft = { true },
|
||||
ifRight = {
|
||||
cardRepository.setCardWasScanned(cardId = userWallet.cardId)
|
||||
false
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun UserWallet.isCorrectCardType(): Boolean {
|
||||
return with(scanResponse.cardTypesResolver) {
|
||||
!DemoConfig().isDemoCardId(cardId) && isReleaseFirmwareType() && !isMultiwalletAllowed() && !isTangemTwins()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,30 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.viewmodels
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.card.WasCardScannedUseCase
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.tokens.GetMissedAddressesCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.tokens.error.GetCurrenciesError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.HasSingleWalletSignedHashesUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
/**
|
||||
* Wallet notifications list factory
|
||||
*
|
||||
* @property isDemoCardUseCase use case that checks if card is demo
|
||||
* @property isReadyToShowRateAppUseCase use case that checks if card is user already rate app
|
||||
* @property wasCardScannedUseCase use case that checks if card was scanned
|
||||
* @property isNeedToBackupUseCase use case that checks if wallet need backup cards
|
||||
* @property clickIntents screen click intents
|
||||
*
|
||||
|
|
@ -32,38 +33,50 @@ import kotlinx.coroutines.flow.conflate
|
|||
internal class WalletNotificationsListFactory(
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||
private val wasCardScannedUseCase: WasCardScannedUseCase,
|
||||
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||
private val getMissedAddressCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
||||
private val hasSingleWalletSignedHashesUseCase: HasSingleWalletSignedHashesUseCase,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) {
|
||||
|
||||
private var readyForRateAppNotification = false
|
||||
|
||||
fun create(
|
||||
selectedWalletId: UserWalletId,
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
selectedWallet: UserWallet,
|
||||
cryptoCurrencyList: List<CryptoCurrencyStatus>,
|
||||
): Flow<ImmutableList<WalletNotification>> {
|
||||
val cardTypesResolver = selectedWallet.scanResponse.cardTypesResolver
|
||||
return combine(
|
||||
flow = wasCardScannedUseCase(cardTypesResolver.getCardId()).conflate(),
|
||||
flow = hasSingleWalletSignedHashesFlow(selectedWallet, cryptoCurrencyList),
|
||||
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
||||
flow3 = isNeedToBackupUseCase(selectedWalletId).conflate(),
|
||||
flow4 = getMissedAddressCryptoCurrenciesUseCase(selectedWalletId).conflate(),
|
||||
) { wasCardScanned, isReadyToShowRating, isNeedToBackup, maybeMissedAddressCurrencies ->
|
||||
flow3 = isNeedToBackupUseCase(selectedWallet.walletId).conflate(),
|
||||
flow4 = getMissedAddressCryptoCurrenciesUseCase(selectedWallet.walletId).conflate(),
|
||||
) { hasSignedHashes, isReadyToShowRating, isNeedToBackup, maybeMissedAddressCurrencies ->
|
||||
readyForRateAppNotification = true
|
||||
buildList {
|
||||
addCriticalNotifications(cardTypesResolver)
|
||||
|
||||
addInformationalNotifications(cardTypesResolver, maybeMissedAddressCurrencies)
|
||||
|
||||
addWarningNotifications(cardTypesResolver, cryptoCurrencyList, wasCardScanned, isNeedToBackup)
|
||||
addWarningNotifications(cardTypesResolver, cryptoCurrencyList, hasSignedHashes, isNeedToBackup)
|
||||
|
||||
addRateTheAppNotification(isReadyToShowRating)
|
||||
}.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasSingleWalletSignedHashesFlow(
|
||||
selectedWallet: UserWallet,
|
||||
cryptoCurrencyList: List<CryptoCurrencyStatus>,
|
||||
): Flow<Boolean> {
|
||||
return if (selectedWallet.scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
|
||||
flowOf(value = false)
|
||||
} else {
|
||||
val network = requireNotNull(cryptoCurrencyList.firstOrNull()?.currency?.network)
|
||||
hasSingleWalletSignedHashesUseCase(userWallet = selectedWallet, network = network).conflate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
||||
addIf(
|
||||
element = WalletNotification.Critical.DevCard,
|
||||
|
|
@ -97,7 +110,7 @@ internal class WalletNotificationsListFactory(
|
|||
private fun MutableList<WalletNotification>.addWarningNotifications(
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
cryptoCurrencyList: List<CryptoCurrencyStatus>,
|
||||
wasCardScanned: Boolean,
|
||||
hasSignedHashes: Boolean,
|
||||
isNeedToBackup: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
|
|
@ -112,7 +125,6 @@ internal class WalletNotificationsListFactory(
|
|||
condition = cardTypesResolver.isTestCard(),
|
||||
)
|
||||
|
||||
val isDemo = isDemoCardUseCase(cardId = cardTypesResolver.getCardId())
|
||||
if (cardTypesResolver.isMultiwalletAllowed()) {
|
||||
addIf(
|
||||
element = WalletNotification.Warning.SomeNetworksUnreachable,
|
||||
|
|
@ -130,11 +142,7 @@ internal class WalletNotificationsListFactory(
|
|||
element = WalletNotification.Warning.NumberOfSignedHashesIncorrect(
|
||||
onCloseClick = clickIntents::onSignedHashesNotificationCloseClick,
|
||||
),
|
||||
condition = checkSignedHashes(
|
||||
cardTypesResolver = cardTypesResolver,
|
||||
isDemo = isDemo,
|
||||
wasCardScanned = wasCardScanned,
|
||||
),
|
||||
condition = hasSignedHashes,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -195,18 +203,6 @@ internal class WalletNotificationsListFactory(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning is being shown for single wallet cards only
|
||||
*/
|
||||
private fun checkSignedHashes(
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
isDemo: Boolean,
|
||||
wasCardScanned: Boolean,
|
||||
): Boolean {
|
||||
return cardTypesResolver.isReleaseFirmwareType() && !cardTypesResolver.isTangemTwins() &&
|
||||
cardTypesResolver.hasWalletSignedHashes() && !isDemo && !wasCardScanned
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val MAX_REMAINING_SIGNATURES_COUNT = 10
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
|
|||
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
|
||||
import com.tangem.domain.card.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.card.SetCardWasScannedUseCase
|
||||
import com.tangem.domain.card.WasCardScannedUseCase
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
|
|
@ -60,6 +59,7 @@ import com.tangem.feature.wallet.impl.R
|
|||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.PortfolioEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.HasSingleWalletSignedHashesUseCase
|
||||
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.state.*
|
||||
|
|
@ -127,7 +127,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val scanCardToUnlockWalletUseCase: ScanCardToUnlockWalletClickHandler,
|
||||
wasCardScannedUseCase: WasCardScannedUseCase,
|
||||
hasSingleWalletSignedHashesUseCase: HasSingleWalletSignedHashesUseCase,
|
||||
isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||
isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||
getMissedAddressesCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
||||
|
|
@ -140,11 +140,11 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
||||
|
||||
private val notificationsListFactory = WalletNotificationsListFactory(
|
||||
wasCardScannedUseCase = wasCardScannedUseCase,
|
||||
isReadyToShowRateAppUseCase = isReadyToShowRateAppUseCase,
|
||||
isDemoCardUseCase = isDemoCardUseCase,
|
||||
isReadyToShowRateAppUseCase = isReadyToShowRateAppUseCase,
|
||||
isNeedToBackupUseCase = isNeedToBackupUseCase,
|
||||
getMissedAddressCryptoCurrenciesUseCase = getMissedAddressesCryptoCurrenciesUseCase,
|
||||
hasSingleWalletSignedHashesUseCase = hasSingleWalletSignedHashesUseCase,
|
||||
clickIntents = this,
|
||||
)
|
||||
|
||||
|
|
@ -1316,8 +1316,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
private fun updateNotifications(index: Int, tokenList: TokenList? = null) {
|
||||
notificationsListFactory.create(
|
||||
selectedWalletId = getWallet(index).walletId,
|
||||
cardTypesResolver = getCardTypeResolver(index = index),
|
||||
selectedWallet = getWallet(index),
|
||||
cryptoCurrencyList = if (tokenList != null) {
|
||||
when (tokenList) {
|
||||
is TokenList.GroupedByNetwork -> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue