Skip to content

Commit 46d613a

Browse files
committed
fix: wallet restore error handling
1 parent b3c8109 commit 46d613a

File tree

11 files changed

+271
-347
lines changed

11 files changed

+271
-347
lines changed

app/src/main/java/to/bitkit/repositories/BackupsRepo.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ class BackupsRepo @Inject constructor(
313313
Logger.info("Full restore completed", context = TAG)
314314
Result.success(Unit)
315315
} catch (e: Throwable) {
316+
Logger.warn("Full restore error", e = e, context = TAG)
316317
Result.failure(e)
317318
} finally {
318319
isRestoring = false

app/src/main/java/to/bitkit/repositories/WalletRepo.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,6 @@ class WalletRepo @Inject constructor(
179179
}
180180
}
181181

182-
fun setRestoringWalletState(isRestoring: Boolean) {
183-
_walletState.update { it.copy(isRestoringWallet = isRestoring) }
184-
}
185-
186182
suspend fun createWallet(bip39Passphrase: String?): Result<Unit> = withContext(bgDispatcher) {
187183
try {
188184
val mnemonic = generateEntropyMnemonic()
@@ -526,6 +522,5 @@ data class WalletState(
526522
val selectedTags: List<String> = listOf(),
527523
val receiveOnSpendingBalance: Boolean = true,
528524
val walletExists: Boolean = false,
529-
val isRestoringWallet: Boolean = false,
530525
val balanceDetails: BalanceDetails? = null, // TODO KEEP ONLY BalanceState IF POSSIBLE
531526
)

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.DisposableEffect
66
import androidx.compose.runtime.LaunchedEffect
77
import androidx.compose.runtime.collectAsState
88
import androidx.compose.runtime.getValue
9+
import androidx.compose.runtime.mutableIntStateOf
910
import androidx.compose.runtime.mutableStateOf
1011
import androidx.compose.runtime.remember
1112
import androidx.compose.runtime.rememberCoroutineScope
@@ -26,7 +27,6 @@ import androidx.navigation.compose.composable
2627
import androidx.navigation.compose.navigation
2728
import androidx.navigation.compose.rememberNavController
2829
import androidx.navigation.toRoute
29-
import kotlinx.coroutines.CoroutineScope
3030
import kotlinx.coroutines.delay
3131
import kotlinx.coroutines.launch
3232
import kotlinx.serialization.Serializable
@@ -37,8 +37,8 @@ import to.bitkit.ui.components.AuthCheckScreen
3737
import to.bitkit.ui.components.BottomSheetType
3838
import to.bitkit.ui.components.SheetHost
3939
import to.bitkit.ui.onboarding.InitializingWalletView
40-
import to.bitkit.ui.onboarding.WalletInitResult
41-
import to.bitkit.ui.onboarding.WalletInitResultView
40+
import to.bitkit.ui.onboarding.WalletRestoreErrorView
41+
import to.bitkit.ui.onboarding.WalletRestoreSuccessView
4242
import to.bitkit.ui.screens.profile.CreateProfileScreen
4343
import to.bitkit.ui.screens.profile.ProfileIntroScreen
4444
import to.bitkit.ui.screens.scanner.QrScanningScreen
@@ -167,7 +167,6 @@ fun ContentView(
167167
val navController = rememberNavController()
168168
val context = LocalContext.current
169169
val lifecycle = LocalLifecycleOwner.current.lifecycle
170-
val scope = rememberCoroutineScope()
171170

172171
// Effects on app entering fg (ON_START) / bg (ON_STOP)
173172
DisposableEffect(lifecycle) {
@@ -251,24 +250,28 @@ fun ContentView(
251250
}
252251

253252
val restoreState = walletViewModel.restoreState
254-
val isRestoringBackups = walletViewModel.restoreState == RestoreState.RestoringBackups
253+
var restoreRetryCount by remember { mutableIntStateOf(0) }
254+
255255
if (walletIsInitializing) {
256256
// TODO ADAPT THIS LOGIC TO WORK WITH LightningNodeService
257257
if (nodeLifecycleState is NodeLifecycleState.ErrorStarting) {
258-
WalletInitResultView(
259-
result = WalletInitResult.Failed(nodeLifecycleState.cause),
260-
onButtonClick = {
261-
scope.launch {
262-
try {
263-
walletViewModel.setInitNodeLifecycleState()
264-
walletViewModel.start()
265-
} catch (e: Exception) {
266-
Logger.error("Failed to start wallet on retry", e)
258+
WalletRestoreErrorView(
259+
retryCount = restoreRetryCount,
260+
onRetry = {
261+
restoreRetryCount++
262+
walletViewModel.setInitNodeLifecycleState()
263+
walletViewModel.start()
264+
},
265+
onProceedWithoutRestore = {
266+
walletViewModel.proceedWithoutRestore(
267+
onDone = {
268+
walletIsInitializing = false
267269
}
268-
}
269-
}
270+
)
271+
},
270272
)
271273
} else {
274+
// wallet is being created or restored
272275
InitializingWalletView(
273276
shouldFinish = walletInitShouldFinish,
274277
onComplete = {
@@ -277,26 +280,13 @@ fun ContentView(
277280
if (nodeLifecycleState == NodeLifecycleState.Running) {
278281
walletIsInitializing = false
279282
}
280-
}
283+
},
284+
isRestoring = restoreState.isRestoring(),
281285
)
282286
}
283-
} else if (walletViewModel.isRestoringWallet || isRestoringBackups) {
284-
InitializingWalletView(
285-
shouldFinish = false,
286-
onComplete = { /* Loading state, no completion */ },
287-
isRestoringBackups = isRestoringBackups
288-
)
289287
} else if (restoreState is RestoreState.BackupRestoreCompleted) {
290-
val result = restoreState.result
291-
WalletInitResultView(
292-
result = result,
293-
onButtonClick = {
294-
when (result) {
295-
is WalletInitResult.Restored -> walletViewModel.onBackupRestoreSuccess()
296-
is WalletInitResult.Failed -> walletViewModel.onBackupRestoreRetry()
297-
}
298-
},
299-
onProceedWithoutRestore = { walletViewModel.proceedWithoutRestore() }
288+
WalletRestoreSuccessView(
289+
onContinue = { walletViewModel.onRestoreContinue() },
300290
)
301291
} else {
302292
val balance by walletViewModel.balanceState.collectAsStateWithLifecycle()
@@ -388,7 +378,6 @@ fun ContentView(
388378
settingsViewModel = settingsViewModel,
389379
currencyViewModel = currencyViewModel,
390380
transferViewModel = transferViewModel,
391-
scope = scope,
392381
)
393382
}
394383
}
@@ -404,8 +393,9 @@ private fun RootNavHost(
404393
settingsViewModel: SettingsViewModel,
405394
currencyViewModel: CurrencyViewModel,
406395
transferViewModel: TransferViewModel,
407-
scope: CoroutineScope,
408396
) {
397+
val scope = rememberCoroutineScope()
398+
409399
NavHost(navController, startDestination = Routes.Home) {
410400
home(walletViewModel, appViewModel, activityListViewModel, settingsViewModel, navController)
411401
settings(navController, settingsViewModel)
@@ -740,7 +730,7 @@ private fun NavGraphBuilder.shop(
740730
)
741731
}
742732
composableWithDefaultTransitions<Routes.ShopWebView> {
743-
ShopWebViewScreen (
733+
ShopWebViewScreen(
744734
onClose = { navController.navigateToHome() },
745735
onBack = { navController.popBackStack() },
746736
page = it.toRoute<Routes.ShopWebView>().page,

app/src/main/java/to/bitkit/ui/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class MainActivity : FragmentActivity() {
164164
try {
165165
appViewModel.resetIsAuthenticatedState()
166166
walletViewModel.setInitNodeLifecycleState()
167-
walletViewModel.setRestoringWalletState(isRestoringWallet = true)
167+
walletViewModel.setRestoringWalletState()
168168
walletViewModel.restoreWallet(mnemonic, passphrase)
169169
} catch (e: Throwable) {
170170
appViewModel.toast(e)

app/src/main/java/to/bitkit/ui/onboarding/InitializingWalletView.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,23 @@ import to.bitkit.ui.theme.Colors
4343
import to.bitkit.ui.utils.withAccent
4444
import kotlin.math.roundToInt
4545

46+
const val LOADING_MS = 2000
47+
const val RESTORING_MS = 8000
48+
4649
@SuppressLint("UnusedBoxWithConstraintsScope")
4750
@Composable
4851
fun InitializingWalletView(
4952
shouldFinish: Boolean,
5053
onComplete: () -> Unit,
51-
isRestoringBackups: Boolean = false,
54+
isRestoring: Boolean = false,
5255
) {
5356
BoxWithConstraints(
5457
modifier = Modifier.fillMaxSize(),
5558
contentAlignment = Alignment.Center,
5659
) {
5760
val percentage = remember { Animatable(0f) }
5861

59-
val animationDuration = if (isRestoringBackups) 8000 else 2000
62+
val animationDuration = if (isRestoring) RESTORING_MS else LOADING_MS
6063

6164
// Progress to 100%
6265
LaunchedEffect(animationDuration) {

app/src/main/java/to/bitkit/ui/onboarding/WalletInitResultView.kt

Lines changed: 0 additions & 167 deletions
This file was deleted.

0 commit comments

Comments
 (0)