Delete wallet hotfix (#1663)

* Delete wallet hotfix

* Documentation update

* Navigation hotfix

* Documentation update

* Changelog update

* Wallet restore navigation update

* Wallet deletion navigation navigation update

---------

Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
Milan 2024-11-11 09:16:03 +01:00 committed by GitHub
parent 078f7b88df
commit 72e3eca548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 59 additions and 49 deletions

View File

@ -11,7 +11,9 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
### Fixed
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- The application now correctly navigates to the homepage after deleting the current wallet and creating a new or
recovering an older one
## [1.2.1 (760)] - 2024-10-22

View File

@ -15,6 +15,8 @@ directly impact users rather than highlighting other key architectural updates.*
### Fixed
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- The application now correctly navigates to the homepage after deleting the current wallet and creating a new or
recovering an older one
## [1.2.1 (760)] - 2024-10-22

View File

@ -224,6 +224,10 @@ internal fun MainActivity.Navigation() {
goBack = {
setDeleteWalletAuthentication(false)
navController.popBackStackJustOnce(DELETE_WALLET)
},
onConfirm = {
setDeleteWalletAuthentication(false)
navController.popBackStackJustOnce(DELETE_WALLET)
}
)
}

View File

@ -1,9 +1,12 @@
package co.electriccoin.zcash.ui.common.usecase
import cash.z.ecc.android.sdk.SdkSynchronizer
import co.electriccoin.zcash.ui.common.repository.WalletRepository
class GetSynchronizerUseCase(
private val walletRepository: WalletRepository
) {
suspend operator fun invoke() = walletRepository.getSynchronizer()
suspend fun getSdkSynchronizer() = walletRepository.getSynchronizer() as? SdkSynchronizer
}

View File

@ -1,11 +1,8 @@
package co.electriccoin.zcash.ui.common.viewmodel
import android.app.Activity
import android.app.Application
import android.content.Intent
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import cash.z.ecc.android.sdk.SdkSynchronizer
import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.WalletCoordinator
import cash.z.ecc.android.sdk.WalletInitMode
@ -21,7 +18,6 @@ import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
import co.electriccoin.zcash.preference.StandardPreferenceProvider
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.BuildConfig
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.common.model.OnboardingState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
@ -30,6 +26,7 @@ import co.electriccoin.zcash.ui.common.repository.BalanceRepository
import co.electriccoin.zcash.ui.common.repository.ExchangeRateRepository
import co.electriccoin.zcash.ui.common.repository.WalletRepository
import co.electriccoin.zcash.ui.common.usecase.DeleteAddressBookUseCase
import co.electriccoin.zcash.ui.common.usecase.GetSynchronizerUseCase
import co.electriccoin.zcash.ui.common.usecase.IsFlexaAvailableUseCase
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
import co.electriccoin.zcash.ui.screen.account.ext.TransactionOverviewExt
@ -48,9 +45,9 @@ import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlin.coroutines.resume
@ -71,7 +68,8 @@ class WalletViewModel(
private val standardPreferenceProvider: StandardPreferenceProvider,
private val getAvailableServers: GetDefaultServersProvider,
private val deleteAddressBookUseCase: DeleteAddressBookUseCase,
private val isFlexaAvailable: IsFlexaAvailableUseCase
private val isFlexaAvailable: IsFlexaAvailableUseCase,
private val getSynchronizer: GetSynchronizerUseCase
) : AndroidViewModel(application) {
val navigationCommand = exchangeRateRepository.navigationCommand
@ -240,40 +238,34 @@ class WalletViewModel(
}
}
fun deleteWalletFlow(activity: Activity): Flow<Boolean> =
callbackFlow {
Twig.info { "Delete wallet: Requested" }
disconnectFlexa()
val synchronizer = synchronizer.value
if (null != synchronizer) {
(synchronizer as SdkSynchronizer).closeFlow().collect {
Twig.info { "Delete wallet: SDK closed" }
fun deleteWallet(
onError: () -> Unit,
onSuccess: () -> Unit
) = viewModelScope.launch(Dispatchers.Main) {
Twig.info { "Delete wallet: Requested" }
disconnectFlexa()
walletCoordinator.deleteSdkDataFlow().collect { isSdkErased ->
Twig.info { "Delete wallet: Erase SDK result: $isSdkErased" }
if (!isSdkErased) {
trySend(false)
}
getSynchronizer.getSdkSynchronizer()?.closeFlow()?.first()
Twig.info { "Delete wallet: SDK closed" }
val isSdkErased = walletCoordinator.deleteSdkDataFlow().first()
Twig.info { "Delete wallet: Erase SDK result: $isSdkErased" }
clearAppStateFlow().collect { isAppErased ->
Twig.info { "Delete wallet: Erase App result: $isAppErased" }
if (!isAppErased) {
trySend(false)
} else {
trySend(true)
activity.run {
finish()
startActivity(Intent(this, MainActivity::class.java))
}
}
}
}
}
}
awaitClose {
// Nothing to close
}
}.flowOn(Dispatchers.Main)
if (!isSdkErased) {
Twig.error { "Wallet deletion failed" }
onError()
return@launch
}
val isAppErased = clearAppStateFlow().first()
Twig.info { "Delete wallet: Erase App result: $isAppErased" }
if (isAppErased) {
Twig.info { "Wallet deleted successfully" }
onSuccess()
} else {
Twig.error { "Wallet deletion failed" }
onError()
}
}
private suspend fun disconnectFlexa() =
suspendCoroutine { cont ->

View File

@ -1,6 +1,7 @@
package co.electriccoin.zcash.ui.screen.deletewallet
import android.app.Activity
import android.content.Intent
import androidx.activity.compose.BackHandler
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
@ -8,7 +9,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.di.koinActivityViewModel
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
@ -17,7 +17,10 @@ import co.electriccoin.zcash.ui.screen.deletewallet.view.DeleteWallet
import kotlinx.coroutines.launch
@Composable
internal fun MainActivity.WrapDeleteWallet(goBack: () -> Unit) {
internal fun MainActivity.WrapDeleteWallet(
goBack: () -> Unit,
onConfirm: () -> Unit,
) {
val walletViewModel = koinActivityViewModel<WalletViewModel>()
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
@ -27,6 +30,7 @@ internal fun MainActivity.WrapDeleteWallet(goBack: () -> Unit) {
goBack = goBack,
topAppBarSubTitleState = walletState,
walletViewModel = walletViewModel,
onConfirm = onConfirm
)
}
@ -34,6 +38,7 @@ internal fun MainActivity.WrapDeleteWallet(goBack: () -> Unit) {
internal fun WrapDeleteWallet(
activity: Activity,
goBack: () -> Unit,
onConfirm: () -> Unit,
topAppBarSubTitleState: TopAppBarSubTitleState,
walletViewModel: WalletViewModel,
) {
@ -49,19 +54,20 @@ internal fun WrapDeleteWallet(
snackbarHostState = snackbarHostState,
onBack = goBack,
onConfirm = {
scope.launch {
walletViewModel.deleteWalletFlow(activity).collect { isWalletDeleted ->
if (isWalletDeleted) {
Twig.info { "Wallet deleted successfully" }
// The app flows move to the Onboarding screens reactively
} else {
Twig.error { "Wallet deletion failed" }
walletViewModel.deleteWallet(
onSuccess = {
onConfirm()
activity.finish()
activity.startActivity(Intent(activity, MainActivity::class.java))
},
onError = {
scope.launch {
snackbarHostState.showSnackbar(
message = activity.getString(R.string.delete_wallet_failed)
)
}
}
}
)
},
topAppBarSubTitleState = topAppBarSubTitleState,
)

View File

@ -53,6 +53,7 @@ fun WrapRestore() {
SeedPhrase(restoreViewModel.userWordList.current.value),
restoreViewModel.userBirthdayHeight.value
)
onboardingViewModel.setIsImporting(false)
}
)
}