Updated on 2026-08-14

This commit is contained in:
Tangem 2024-03-25 15:34:17 +08:00
parent 3470762a47
commit 1c856e49e0
6 changed files with 68 additions and 49 deletions

View file

@ -78,9 +78,7 @@ object OnboardingHelper {
when {
// When should save user wallets, then save card without navigate to save wallet screen
store.inject(DaggerGraphState::walletsRepository).shouldSaveUserWalletsSync() -> {
proceedWithScanResponse(scanResponse, backupCardsIds)
store.dispatchOnMain(
store.dispatchWithMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
@ -90,9 +88,9 @@ object OnboardingHelper {
val toggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
if (toggles.isGeneralManagerEnabled) {
store.dispatchOnMain(SaveWalletAction.AllowToUseBiometrics)
store.dispatchWithMain(SaveWalletAction.SaveWalletAfterBackup)
} else {
store.dispatchOnMain(SaveWalletAction.Save)
store.dispatchWithMain(SaveWalletAction.Save)
}
}
// When should not save user wallets but device has biometry and save wallet screen has not been shown,

View file

@ -27,4 +27,6 @@ internal sealed interface SaveWalletAction : Action {
}
data object SaveWalletWasShown : SaveWalletAction
data object SaveWalletAfterBackup : SaveWalletAction
}

View file

@ -1,11 +1,8 @@
package com.tangem.tap.features.saveWallet.redux
import com.tangem.common.CompletionResult
import com.tangem.common.*
import com.tangem.common.core.TangemSdkError
import com.tangem.common.doOnFailure
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.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
@ -20,6 +17,7 @@ import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
@ -28,6 +26,7 @@ import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
import org.rekotlin.Store
import timber.log.Timber
internal class SaveWalletMiddleware {
@ -53,6 +52,7 @@ internal class SaveWalletMiddleware {
is SaveWalletAction.EnrollBiometrics.Enroll -> enrollBiometrics()
is SaveWalletAction.SaveWalletWasShown -> saveWalletWasShown()
is SaveWalletAction.Dismiss -> dismiss(state)
is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup(state)
is SaveWalletAction.Save.Success,
is SaveWalletAction.ProvideBackupInfo,
is SaveWalletAction.CloseError,
@ -63,6 +63,30 @@ internal class SaveWalletMiddleware {
}
}
private fun saveWalletAfterBackup(state: SaveWalletState) {
scope.launch {
val backupInfo = state.backupInfo ?: error("Backup info is null")
val userWallet = UserWalletBuilder(backupInfo.scanResponse)
.backupCardsIds(state.backupInfo.backupCardsIds)
.build()
.guard {
Timber.e("User wallet not created")
return@launch
}
userWalletsListManager.save(userWallet, canOverride = true)
.flatMap {
saveAccessCodeIfNeeded(accessCode = backupInfo.accessCode, cardsInWallet = userWallet.cardsInWallet)
}
.doOnFailure { error ->
Timber.e(error, "Unable to save user wallet")
}
.doOnSuccess { mainScope.launch { store.onUserWalletSelected(userWallet) } }
.doOnResult { store.navigateToWallet() }
}
}
private fun enrollBiometrics() {
store.dispatchOnMain(NavigationAction.OpenBiometricsSettings)
}
@ -138,14 +162,7 @@ internal class SaveWalletMiddleware {
}
store.dispatchOnMain(SaveWalletAction.Save.Success)
store.dispatchOnMain(
if (store.state.navigationState.backStack.contains(AppScreen.Wallet)) {
NavigationAction.PopBackTo(AppScreen.Wallet)
} else {
NavigationAction.NavigateTo(AppScreen.Wallet)
},
)
store.navigateToWallet()
}
}.saveIn(saveWalletJobHolder)
}
@ -164,41 +181,22 @@ internal class SaveWalletMiddleware {
}
scope.launch {
val backupInfo = state.backupInfo
val userWalletFromBackup = backupInfo?.scanResponse
?.let(::UserWalletBuilder)
?.backupCardsIds(backupInfo.backupCardsIds)
?.build()
/*
if (userWalletFromBackup != null) {
userWalletsListManager.save(userWalletFromBackup, canOverride = true)
.flatMap { saveAccessCodeIfNeeded(backupInfo.accessCode, userWalletFromBackup.cardsInWallet) }
.doOnFailure {
Timber.e(it, "Unable to save user wallet")
store.dispatchWithMain(SaveWalletAction.Save.Error(it))
}
.doOnSuccess {
handleSavingSuccess(userWalletFromBackup)
}
} else {
/*
* because it will be automatically saved on UserWalletsListManager switch
* */
val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard {
val error = IllegalStateException("No selected user wallet")
Timber.e(error, "Unable to save user wallet")
store.dispatchWithMain(SaveWalletAction.Save.Error(TangemSdkError.ExceptionError(error)))
return@launch
}
handleSavingSuccess(selectedUserWallet)
* because it will be automatically saved on UserWalletsListManager switch
*/
val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard {
val error = IllegalStateException("No selected user wallet")
Timber.e(error, "Unable to save user wallet")
store.dispatchWithMain(SaveWalletAction.Save.Error(TangemSdkError.ExceptionError(error)))
return@launch
}
handleSuccessAllowing(selectedUserWallet)
}.saveIn(saveWalletJobHolder)
}
private suspend fun handleSavingSuccess(userWallet: UserWallet) {
private suspend fun handleSuccessAllowing(userWallet: UserWallet) {
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
preferencesStorage.shouldSaveAccessCodes = true
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
@ -252,4 +250,14 @@ internal class SaveWalletMiddleware {
}
}
}
private suspend fun Store<AppState>.navigateToWallet() {
dispatchWithMain(
if (store.state.navigationState.backStack.contains(AppScreen.Wallet)) {
NavigationAction.PopBackTo(AppScreen.Wallet)
} else {
NavigationAction.NavigateTo(AppScreen.Wallet)
},
)
}
}

View file

@ -47,7 +47,9 @@ internal object SaveWalletReducer {
needEnrollBiometrics = false,
isSaveInProgress = false,
)
is SaveWalletAction.SaveWalletWasShown -> state
is SaveWalletAction.SaveWalletWasShown,
is SaveWalletAction.SaveWalletAfterBackup,
-> state
}
}
}

View file

@ -8,6 +8,12 @@ import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletCl
import kotlinx.collections.immutable.toImmutableList
/**
* Reinitialize wallet transformer
*
* @property prevWalletId reinitialized wallet id
* @property newUserWallet new user wallet
* @property clickIntents click intents
*
[REDACTED_AUTHOR]
*/
internal class ReinitializeWalletTransformer(

View file

@ -214,7 +214,10 @@ internal class WalletsUpdateActionResolver @Inject constructor(
}
/**
* Reinitialize selected wallet. Example, scanning a new card if wallets saving is turned off
* Reinitialize selected wallet.
* Uses when:
* 1. user scanned a new card but wallets saving is turned off;
* 2. user reset Twins.
*
* @property prevWalletId previous selected wallet id
* @property selectedWallet selected wallet