Updated on 2026-08-14

This commit is contained in:
Tangem 2023-06-30 09:26:53 +08:00
parent 65ff4a4b49
commit 9112d2bab8
55 changed files with 492 additions and 389 deletions

View file

@ -1,13 +1,14 @@
package com.tangem.tap.features.demo
import com.tangem.common.extensions.guard
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.common.demo.DemoConfig
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.launch
@ -28,9 +29,14 @@ internal class DemoOnboardingNoteMiddleware : DemoMiddleware {
noteState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(scanResponse).guard {
return false
}
val walletManager = wmFactory
.makePrimaryWalletManager(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.guard {
return false
}
store.dispatch(OnboardingNoteAction.SetWalletManager(walletManager))
walletManager
}

View file

@ -2,7 +2,6 @@ package com.tangem.tap.features.details.redux
import com.tangem.blockchain.common.Wallet
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.entities.FiatCurrency
import org.rekotlin.Action
@ -26,7 +25,7 @@ sealed class DetailsAction : Action {
object ScanCard : DetailsAction()
data class PrepareCardSettingsData(val card: CardDTO, val cardTypesResolver: CardTypesResolver) : DetailsAction()
data class PrepareCardSettingsData(val card: CardDTO) : DetailsAction()
object ResetCardSettingsData : DetailsAction()
sealed class AccessCodeRecovery : DetailsAction() {

View file

@ -8,7 +8,6 @@ import com.tangem.common.extensions.guard
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
@ -33,13 +32,8 @@ import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.foregroundActivityObserver
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.tangemSdkManager
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.walletStoresManager
import com.tangem.wallet.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -92,10 +86,7 @@ class DetailsMiddleware {
if (isSameWallet) {
store.dispatchOnMain(
DetailsAction.PrepareCardSettingsData(
scanResponse.card,
scanResponse.cardTypesResolver,
),
DetailsAction.PrepareCardSettingsData(card = scanResponse.card),
)
} else {
store.dispatchDialogShow(
@ -328,7 +319,12 @@ class DetailsMiddleware {
enableAccessCodesSaving: Boolean,
): CompletionResult<Unit> {
val userWallet = userWalletsListManager.selectedUserWalletSync
?: scanResponse?.let { UserWalletBuilder(it).build() }
?: scanResponse?.let {
UserWalletBuilder(
scanResponse = it,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
).build()
}
?: return CompletionResult.Failure(
error = TangemSdkError.ExceptionError(IllegalStateException("scanResponse is null")),
)

View file

@ -1,15 +1,15 @@
package com.tangem.tap.features.details.redux
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.card.CardTypeResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.extensions.signedHashesCount
import com.tangem.tap.preferencesStorage
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import org.rekotlin.Action
import java.util.*
import java.util.EnumSet
object DetailsReducer {
fun reduce(action: Action, state: AppState): DetailsState = internalReduce(action, state)
@ -23,11 +23,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
handlePrepareScreen(action)
}
is DetailsAction.PrepareCardSettingsData -> {
handlePrepareCardSettingsScreen(
card = action.card,
cardTypesResolver = action.cardTypesResolver,
state = detailsState,
)
handlePrepareCardSettingsScreen(card = action.card, state = detailsState)
}
is DetailsAction.ResetCardSettingsData -> detailsState.copy(cardSettingsState = null)
is DetailsAction.ResetToFactory -> {
@ -60,17 +56,14 @@ private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsSta
)
}
private fun handlePrepareCardSettingsScreen(
card: CardDTO,
cardTypesResolver: CardTypesResolver,
state: DetailsState,
): DetailsState {
private fun handlePrepareCardSettingsScreen(card: CardDTO, state: DetailsState): DetailsState {
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
val cardSettingsState = CardSettingsState(
cardInfo = card.toCardInfo(cardTypesResolver),
manageSecurityState = prepareSecurityOptions(card, cardTypesResolver),
cardInfo = card.toCardInfo(cardTypeResolver),
manageSecurityState = prepareSecurityOptions(card, cardTypeResolver),
card = card,
resetCardAllowed = isResetToFactoryAllowedByCard(card, cardTypesResolver),
accessCodeRecovery = if (cardTypesResolver.isWallet2()) {
resetCardAllowed = isResetToFactoryAllowedByCard(card, cardTypeResolver),
accessCodeRecovery = if (cardTypeResolver.isWallet2()) {
val enabled = card.userSettings?.isUserCodeRecoveryAllowed ?: false
AccessCodeRecoveryState(
enabledOnCard = enabled,
@ -83,7 +76,7 @@ private fun handlePrepareCardSettingsScreen(
return state.copy(cardSettingsState = cardSettingsState)
}
private fun prepareSecurityOptions(card: CardDTO, cardTypesResolver: CardTypesResolver): ManageSecurityState {
private fun prepareSecurityOptions(card: CardDTO, cardTypeResolver: CardTypeResolver): ManageSecurityState {
val securityOption = when {
card.isAccessCodeSet -> {
SecurityOption.AccessCode
@ -98,14 +91,15 @@ private fun prepareSecurityOptions(card: CardDTO, cardTypesResolver: CardTypesRe
}
}
val allowedSecurityOptions = when {
cardTypesResolver.isStart2Coin() || cardTypesResolver.isTangemNote() -> {
cardTypeResolver.isStart2Coin() || cardTypeResolver.isTangemNote() -> {
EnumSet.of(SecurityOption.LongTap)
}
card.settings.isBackupAllowed -> {
EnumSet.of(securityOption)
}
else ->
prepareAllowedSecurityOptions(cardTypesResolver = cardTypesResolver, currentSecurityOption = securityOption)
else -> {
prepareAllowedSecurityOptions(cardTypeResolver = cardTypeResolver, currentSecurityOption = securityOption)
}
}
return ManageSecurityState(
currentOption = securityOption,
@ -114,9 +108,9 @@ private fun prepareSecurityOptions(card: CardDTO, cardTypesResolver: CardTypesRe
)
}
private fun isResetToFactoryAllowedByCard(card: CardDTO, cardTypesResolver: CardTypesResolver): Boolean {
private fun isResetToFactoryAllowedByCard(card: CardDTO, cardTypeResolver: CardTypeResolver): Boolean {
val hasPermanentWallet = card.wallets.any { it.settings.isPermanent }
val isNotAllowed = hasPermanentWallet || cardTypesResolver.isStart2Coin()
val isNotAllowed = hasPermanentWallet || cardTypeResolver.isStart2Coin()
return !isNotAllowed
}
@ -140,12 +134,10 @@ private fun handleSecurityAction(action: DetailsAction.ManageSecurity, state: De
// Setting options to show only LongTap from now on for non-twins
val manageSecurityState = state.cardSettingsState?.manageSecurityState?.copy(
currentOption = state.cardSettingsState.manageSecurityState.selectedOption,
allowedOptions = state.scanResponse?.cardTypesResolver?.let {
prepareAllowedSecurityOptions(
cardTypesResolver = it,
currentSecurityOption = state.cardSettingsState.manageSecurityState.selectedOption,
)
} ?: EnumSet.of(SecurityOption.LongTap),
allowedOptions = prepareAllowedSecurityOptions(
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
currentSecurityOption = state.cardSettingsState.manageSecurityState.selectedOption,
),
)
state.copy(
cardSettingsState = state.cardSettingsState?.copy(
@ -229,12 +221,12 @@ private fun handleAccessCodeRecoveryAction(
}
private fun prepareAllowedSecurityOptions(
cardTypesResolver: CardTypesResolver,
cardTypeResolver: CardTypeResolver,
currentSecurityOption: SecurityOption?,
): EnumSet<SecurityOption> {
val allowedSecurityOptions = EnumSet.of(SecurityOption.LongTap)
if (cardTypesResolver.isTangemTwins()) {
if (cardTypeResolver.isTangemTwins()) {
allowedSecurityOptions.add(SecurityOption.PassCode)
}
if (currentSecurityOption == SecurityOption.AccessCode) {
@ -246,9 +238,8 @@ private fun prepareAllowedSecurityOptions(
return allowedSecurityOptions
}
@Suppress("MagicNumber")
private fun CardDTO.toCardInfo(cardTypesResolver: CardTypesResolver): CardInfo {
val cardId = this.cardId.chunked(4).joinToString(separator = " ")
private fun CardDTO.toCardInfo(cardTypeResolver: CardTypeResolver): CardInfo {
val cardId = this.cardId.chunked(size = 4).joinToString(separator = " ")
val issuer = this.issuer.name
val signedHashes = this.signedHashesCount()
@ -256,7 +247,7 @@ private fun CardDTO.toCardInfo(cardTypesResolver: CardTypesResolver): CardInfo {
cardId = cardId,
issuer = issuer,
signedHashes = signedHashes,
isTwin = cardTypesResolver.isTangemTwins(),
isTwin = cardTypeResolver.isTangemTwins(),
hasBackup = backupStatus?.isActive == true,
)
}

View file

@ -8,7 +8,6 @@ import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toNetworkId
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.dispatchOnMain
@ -404,7 +403,8 @@ class WalletConnectMiddleware {
private fun handleScanResponse(scanResponse: ScanResponse, session: WalletConnectSession, blockchain: Blockchain) {
val card = scanResponse.card
if (!scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
if (!cardTypeResolver.isMultiwalletAllowed()) {
store.dispatchOnMain(WalletConnectAction.UnsupportedCard)
return
}

View file

@ -3,7 +3,6 @@ package com.tangem.tap.features.details.ui.details
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.analytics.events.Settings
import com.tangem.tap.common.feedback.FeedbackEmail
import com.tangem.tap.common.feedback.SupportInfo
@ -16,6 +15,7 @@ import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.home.LocaleRegionProvider
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.wallet.BuildConfig
import org.rekotlin.Store
@ -26,11 +26,11 @@ class DetailsViewModel(private val store: Store<AppState>) {
@Suppress("ComplexMethod")
fun updateState(state: DetailsState): DetailsScreenState {
val cardTypesResolver = state.scanResponse?.cardTypesResolver
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
val settings = SettingsElement.values().mapNotNull {
when (it) {
SettingsElement.WalletConnect -> {
if (cardTypesResolver?.isMultiwalletAllowed() == true) it else null
if (cardTypeResolver.isMultiwalletAllowed()) it else null
}
SettingsElement.SendFeedback -> it
SettingsElement.LinkMoreCards -> if (state.createBackupAllowed) it else null
@ -38,8 +38,8 @@ class DetailsViewModel(private val store: Store<AppState>) {
if (state.privacyPolicyUrl != null) it else null
}
SettingsElement.AppSettings -> if (state.appSettingsState.isBiometricsAvailable) it else null
SettingsElement.AppCurrency -> if (cardTypesResolver?.isMultiwalletAllowed() != true) it else null
SettingsElement.ReferralProgram -> if (cardTypesResolver?.isTangemWallet() == true) it else null
SettingsElement.AppCurrency -> if (!cardTypeResolver.isMultiwalletAllowed()) it else null
SettingsElement.ReferralProgram -> if (cardTypeResolver.isTangemWallet()) it else null
SettingsElement.TesterMenu -> if (BuildConfig.TESTER_MENU_ENABLED) it else null
else -> it
}

View file

@ -27,6 +27,7 @@ import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.home.redux.HomeMiddleware.BUY_WALLET_URL
import com.tangem.tap.features.send.redux.states.ButtonState
import com.tangem.tap.features.signin.redux.SignInAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
@ -101,10 +102,15 @@ private fun readCard(analyticsEvent: AnalyticsEvent?) = scope.launch {
}
private fun proceedWithScanResponse(scanResponse: ScanResponse) = scope.launch {
val userWallet = UserWalletBuilder(scanResponse).build().guard {
Timber.e("User wallet not created")
return@launch
}
val userWallet = UserWalletBuilder(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.build()
.guard {
Timber.e("User wallet not created")
return@launch
}
userWalletsListManager.save(userWallet)
.doOnFailure { error ->

View file

@ -4,10 +4,11 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.card.CardTypeResolver
import com.tangem.domain.common.util.twinsIsTwinned
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.*
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.extensions.removeContext
@ -16,11 +17,7 @@ import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
@ -29,11 +26,11 @@ import timber.log.Timber
[REDACTED_AUTHOR]
*/
object OnboardingHelper {
fun isOnboardingCase(response: ScanResponse): Boolean {
fun isOnboardingCase(response: ScanResponse, cardTypeResolver: CardTypeResolver): Boolean {
val cardInfoStorage = preferencesStorage.usedCardsPrefStorage
val cardId = response.card.cardId
return when {
response.cardTypesResolver.isTangemTwins() -> {
cardTypeResolver.isTangemTwins() -> {
if (!response.twinsIsTwinned()) {
true
} else {
@ -41,7 +38,7 @@ object OnboardingHelper {
}
}
response.cardTypesResolver.isWallet2() -> {
cardTypeResolver.isWallet2() -> {
val emptyWallets = response.card.wallets.isEmpty()
val activationInProgress = cardInfoStorage.isActivationInProgress(cardId)
val backupNotActive = response.card.backupStatus?.isActive != true
@ -73,7 +70,10 @@ object OnboardingHelper {
accessCode: String? = null,
backupCardsIds: List<String>? = null,
) {
Analytics.setContext(scanResponse)
Analytics.setContext(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
when {
// When should save user wallets, then save card without navigate to save wallet screen
preferencesStorage.shouldSaveUserWallets -> scope.launch {
@ -119,7 +119,10 @@ object OnboardingHelper {
}
private suspend fun proceedWithScanResponse(scanResponse: ScanResponse, backupCardsIds: List<String>?) {
val userWallet = UserWalletBuilder(scanResponse)
val userWallet = UserWalletBuilder(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.backupCardsIds(backupCardsIds?.toSet())
.build()
.guard {

View file

@ -7,13 +7,7 @@ import com.tangem.domain.common.extensions.withMainContext
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.extensions.getAddressData
import com.tangem.tap.common.extensions.getTopUpUrl
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
@ -29,6 +23,7 @@ import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
@ -123,7 +118,10 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
noteState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(scanResponse).guard {
val walletManager = wmFactory.makePrimaryWalletManager(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
).guard {
val message = "Loading cancelled. Cause: wallet manager didn't created"
val customError = TapError.CustomError(message)
store.dispatchErrorNotification(customError)

View file

@ -3,9 +3,8 @@ package com.tangem.tap.features.onboarding.products.otherCards.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.CompletionResult
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppState
@ -13,10 +12,7 @@ import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.wallet.models.toCurrencies
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.tap.userTokensRepository
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
@ -90,9 +86,10 @@ private fun handleOtherCardsAction(action: Action) {
onboardingManager.activationStarted(updatedCard.cardId)
store.state.globalState.topUpController?.registerEmptyWallet(updatedResponse)
val primaryBlockchain = updatedResponse.cardTypesResolver.getBlockchain()
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
val primaryBlockchain = cardTypeResolver.getBlockchain()
val blockchainNetworks = if (primaryBlockchain != Blockchain.Unknown) {
val primaryToken = updatedResponse.cardTypesResolver.getPrimaryToken()
val primaryToken = cardTypeResolver.getPrimaryToken()
val blockchainNetwork =
BlockchainNetwork(
blockchain = primaryBlockchain,

View file

@ -29,6 +29,7 @@ import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
@ -221,7 +222,10 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
twinCardsState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(getScanResponse()).guard {
val walletManager = wmFactory.makePrimaryWalletManager(
scanResponse = getScanResponse(),
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
).guard {
val message = "Loading cancelled. Cause: wallet manager didn't created"
val customError = TapError.CustomError(message)
store.dispatchErrorNotification(customError)

View file

@ -1,8 +1,9 @@
package com.tangem.tap.features.onboarding.products.twins.redux
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.getTwinCardNumber
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import org.rekotlin.Action
object TwinCardsReducer {
@ -17,7 +18,8 @@ private fun internalReduce(action: Action, state: AppState): TwinCardsState {
when (action) {
is TwinCardsAction.IfTwinsPrepareState -> {
state = if (action.scanResponse.cardTypesResolver.isTangemTwins()) {
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
state = if (cardTypeResolver.isTangemTwins()) {
val cardNumber = action.scanResponse.card.getTwinCardNumber() ?: return state
TwinCardsState(

View file

@ -7,7 +7,6 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.ifNotNull
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
@ -30,9 +29,9 @@ import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.wallet.models.toCurrencies
import com.tangem.tap.features.wallet.redux.Artwork
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
object OnboardingWalletMiddleware {
@ -43,8 +42,8 @@ private val onboardingWalletMiddleware: Middleware<AppState> = { dispatch, state
{ next ->
{ action ->
when (action) {
is OnboardingWallet2Action -> handleWallet2Action(action, state)
else -> handleWalletAction(action, state, dispatch)
is OnboardingWallet2Action -> handleWallet2Action(action)
else -> handleWalletAction(action)
}
next(action)
}
@ -52,7 +51,7 @@ private val onboardingWalletMiddleware: Middleware<AppState> = { dispatch, state
}
@Suppress("LongMethod", "ComplexMethod")
private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: DispatchFunction) {
private fun handleWalletAction(action: Action) {
if (action !is OnboardingWalletAction) return
val globalState = store.state.globalState
@ -178,7 +177,7 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch:
}
@Suppress("LongMethod", "ComplexMethod")
private fun handleWallet2Action(action: OnboardingWallet2Action, state: () -> AppState?) {
private fun handleWallet2Action(action: OnboardingWallet2Action) {
val globalState = store.state.globalState
val onboardingManager = globalState.onboardingState.onboardingManager
@ -186,7 +185,8 @@ private fun handleWallet2Action(action: OnboardingWallet2Action, state: () -> Ap
when (action) {
is OnboardingWallet2Action.Init -> {
if (scanResponse?.cardTypesResolver?.isWallet2() == true) {
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
if (cardTypeResolver.isWallet2()) {
store.dispatch(OnboardingWallet2Action.SetDependencies(action.maxProgress))
}
}

View file

@ -7,6 +7,7 @@ import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Onboarding
@ -21,12 +22,7 @@ import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
import com.tangem.tap.domain.userWalletList.isLockable
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.foregroundActivityObserver
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
import timber.log.Timber
@ -96,7 +92,10 @@ internal class SaveWalletMiddleware {
scope.launch {
val userWallet = userWalletsListManager.selectedUserWalletSync
?: UserWalletBuilder(scanResponse)
?: UserWalletBuilder(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.backupCardsIds(state.backupInfo?.backupCardsIds)
.build()
?: return@launch

View file

@ -4,7 +4,6 @@ import android.graphics.Bitmap
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.entities.Button
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.common.toggleWidget.WidgetState
@ -50,9 +49,6 @@ data class WalletState(
store.state.twinCardsState
}
val isTangemTwins: Boolean
get() = store.state.globalState.scanResponse?.cardTypesResolver?.isTangemTwins() == true
val isExchangeServiceFeatureOn: Boolean
get() = store.state.globalState.exchangeManager.featureIsSwitchedOn()

View file

@ -19,6 +19,7 @@ import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.userWalletsListManager
@ -82,7 +83,10 @@ class MultiWalletMiddleware {
return
}
val scanResponse = selectedUserWallet.scanResponse
Analytics.addContext(scanResponse)
Analytics.addContext(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
store.dispatch(GlobalAction.Onboarding.Start(scanResponse, canSkipBackup = false))
store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet))
}

View file

@ -5,7 +5,6 @@ import com.tangem.blockchain.common.SignatureCountValidator
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.card.FirmwareVersion
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.dispatchOnMain
@ -107,9 +106,10 @@ class WarningsMiddleware {
}
private fun checkIfWarningNeeded(scanResponse: ScanResponse): WarningMessage? {
if (scanResponse.cardTypesResolver.isTangemTwins() || scanResponse.isDemoCard()) return null
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
if (cardTypeResolver.isTangemTwins() || scanResponse.isDemoCard()) return null
if (scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
if (cardTypeResolver.isMultiwalletAllowed()) {
val isBackupForbidden = with(scanResponse.card.settings) { !(isBackupAllowed || isHDWalletAllowed) }
return if (scanResponse.card.hasSignedHashes() && isBackupForbidden) {
WarningMessagesManager.signedHashesMultiWalletWarning
@ -139,9 +139,8 @@ class WarningsMiddleware {
val card = scanResponse?.card
if (card == null || preferencesStorage.usedCardsPrefStorage.wasScanned(card.cardId)) return
if (scanResponse.cardTypesResolver.isTangemTwins() || scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
return
}
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
if (cardTypeResolver.isTangemTwins() || cardTypeResolver.isMultiwalletAllowed()) return
val validator = store.state.walletState.walletManagers.firstOrNull()
as? SignatureCountValidator

View file

@ -5,7 +5,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.MainScreen
@ -14,6 +13,7 @@ import com.tangem.tap.domain.model.TotalFiatBalance
import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.ui.analytics.WalletAnalyticsEventsMapper
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import com.tangem.tap.walletStoresManager
import dagger.hilt.android.lifecycle.HiltViewModel
@ -54,8 +54,9 @@ internal class WalletViewModel @Inject constructor(
override fun onCreate(owner: LifecycleOwner) {
launch()
val scanResponse = store.state.globalState.scanResponse
val cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver)
if (scanResponse != null) {
val currency = ParamCardCurrencyConverter().convert(scanResponse.cardTypesResolver)
val currency = ParamCardCurrencyConverter().convert(cardTypeResolver)
val signInType = store.state.signInState.type
if (currency != null && signInType != null) {
analyticsEventHandler.send(

View file

@ -22,6 +22,7 @@ import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.domain.userWalletList.unlockIfLockable
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.firstOrNull
@ -162,7 +163,11 @@ internal class WalletSelectorMiddleware {
}
private suspend fun saveUserWalletAndPopBackToWalletScreen(scanResponse: ScanResponse): CompletionResult<Unit> {
val userWallet = UserWalletBuilder(scanResponse).build()
val userWallet = UserWalletBuilder(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.build()
?: return CompletionResult.Failure(TangemSdkError.WalletIsNotCreated())
return userWalletsListManager.save(userWallet)

View file

@ -1,10 +1,11 @@
package com.tangem.tap.features.walletSelector.redux
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.model.TotalFiatBalance
import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import org.rekotlin.Action
internal object WalletSelectorReducer {
@ -99,7 +100,10 @@ internal object WalletSelectorReducer {
)
} else {
UserWalletModel.Type.SingleCurrency(
blockchainName = scanResponse.cardTypesResolver.getBlockchain().fullName,
blockchainName = store.state.daggerGraphState
.get(DaggerGraphState::cardTypeResolver)
.getBlockchain()
.fullName,
)
}
}

View file

@ -20,6 +20,7 @@ import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.domain.userWalletList.unlockIfLockable
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
import com.tangem.tap.features.signin.redux.SignInAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
import timber.log.Timber
@ -79,7 +80,12 @@ internal class WelcomeMiddleware {
private fun proceedWithCard(state: WelcomeState) = scope.launch {
scanCardInternal { scanResponse ->
val userWallet = UserWalletBuilder(scanResponse).build() ?: return@scanCardInternal
val userWallet = UserWalletBuilder(
scanResponse = scanResponse,
cardTypeResolver = store.state.daggerGraphState.get(DaggerGraphState::cardTypeResolver),
)
.build()
?: return@scanCardInternal
userWalletsListManager.save(userWallet, canOverride = true)
.doOnFailure { error ->