Skip to content

Commit 6e43b8c

Browse files
committed
feat: Wipe wallet on too many PIN attempts
1 parent 075b6df commit 6e43b8c

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ fun ContentView(
159159
appViewModel.mainScreenEffect.collect {
160160
when (it) {
161161
is MainScreenEffect.NavigateActivityDetail -> navController.navigate(Routes.ActivityItem(it.activityId))
162+
else -> Unit
162163
}
163164
}
164165
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.activity.viewModels
66
import androidx.compose.animation.AnimatedVisibility
77
import androidx.compose.animation.fadeIn
88
import androidx.compose.animation.fadeOut
9+
import androidx.compose.runtime.LaunchedEffect
910
import androidx.compose.runtime.getValue
1011
import androidx.compose.runtime.rememberCoroutineScope
1112
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
@@ -40,6 +41,7 @@ import to.bitkit.viewmodels.ActivityListViewModel
4041
import to.bitkit.viewmodels.AppViewModel
4142
import to.bitkit.viewmodels.BlocktankViewModel
4243
import to.bitkit.viewmodels.CurrencyViewModel
44+
import to.bitkit.viewmodels.MainScreenEffect
4345
import to.bitkit.viewmodels.TransferViewModel
4446
import to.bitkit.viewmodels.WalletViewModel
4547

@@ -210,6 +212,15 @@ class MainActivity : FragmentActivity() {
210212
onResetClick = { walletViewModel.wipeStorage() },
211213
)
212214
}
215+
216+
LaunchedEffect(appViewModel) {
217+
appViewModel.mainScreenEffect.collect {
218+
when (it) {
219+
MainScreenEffect.WipeStorage -> walletViewModel.wipeStorage()
220+
else -> Unit
221+
}
222+
}
223+
}
213224
}
214225

215226
ToastOverlay(

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
66
import androidx.lifecycle.ViewModel
77
import androidx.lifecycle.viewModelScope
88
import dagger.hilt.android.lifecycle.HiltViewModel
9+
import kotlinx.coroutines.CoroutineDispatcher
910
import kotlinx.coroutines.Dispatchers
1011
import kotlinx.coroutines.delay
1112
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -22,8 +23,10 @@ import kotlinx.coroutines.launch
2223
import org.lightningdevkit.ldknode.Event
2324
import org.lightningdevkit.ldknode.PaymentId
2425
import org.lightningdevkit.ldknode.Txid
26+
import to.bitkit.R
2527
import to.bitkit.data.SettingsStore
2628
import to.bitkit.data.keychain.Keychain
29+
import to.bitkit.di.BgDispatcher
2730
import to.bitkit.env.Env
2831
import to.bitkit.ext.WatchResult
2932
import to.bitkit.ext.removeSpaces
@@ -44,6 +47,7 @@ import to.bitkit.ui.components.BottomSheetType
4447
import to.bitkit.ui.screens.wallets.send.SendRoute
4548
import to.bitkit.ui.shared.toast.ToastEventBus
4649
import to.bitkit.utils.Logger
50+
import to.bitkit.utils.ResourceProvider
4751
import uniffi.bitkitcore.Activity
4852
import uniffi.bitkitcore.ActivityFilter
4953
import uniffi.bitkitcore.LightningInvoice
@@ -54,12 +58,14 @@ import javax.inject.Inject
5458

5559
@HiltViewModel
5660
class AppViewModel @Inject constructor(
61+
@BgDispatcher private val bgDispatcher: CoroutineDispatcher,
5762
private val keychain: Keychain,
5863
private val scannerService: ScannerService,
5964
private val lightningService: LightningRepo,
6065
private val coreService: CoreService,
6166
private val ldkNodeEventBus: LdkNodeEventBus,
6267
private val settingsStore: SettingsStore,
68+
private val resourceProvider: ResourceProvider,
6369
) : ViewModel() {
6470
var splashVisible by mutableStateOf(true)
6571
private set
@@ -820,16 +826,18 @@ class AppViewModel @Inject constructor(
820826
return true
821827
}
822828

823-
viewModelScope.launch {
829+
viewModelScope.launch(bgDispatcher) {
824830
val newAttempts = pinAttemptsRemaining.value - 1
825831
keychain.upsertString(Keychain.Key.PIN_ATTEMPTS_REMAINING.name, newAttempts.toString())
826832

827833
if (newAttempts <= 0) {
828-
// TODO: wipeStorage() & return to onboarding
829834
toast(
830-
type = Toast.ToastType.WARNING,
831-
title = "TODO: Wipe App data",
835+
type = Toast.ToastType.SUCCESS,
836+
title = resourceProvider.getString(R.string.security__wiped_title),
837+
description = resourceProvider.getString(R.string.security__wiped_message),
832838
)
839+
delay(250) // small delay for UI feedback
840+
mainScreenEffect(MainScreenEffect.WipeStorage)
833841
}
834842
}
835843
return false
@@ -892,6 +900,7 @@ sealed class SendEffect {
892900

893901
sealed class MainScreenEffect {
894902
data class NavigateActivityDetail(val activityId: String) : MainScreenEffect()
903+
data object WipeStorage : MainScreenEffect()
895904
}
896905

897906
sealed class SendEvent {

0 commit comments

Comments
 (0)