key storage

This commit is contained in:
nrobi144
2026-01-06 06:49:59 +02:00
parent 2079493fc4
commit 4339247815
10 changed files with 840 additions and 6 deletions
@@ -60,6 +60,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -84,6 +85,11 @@ import com.vitorpamplona.amethyst.desktop.ui.FeedScreen
import com.vitorpamplona.amethyst.desktop.ui.LoginScreen
import com.vitorpamplona.amethyst.desktop.ui.NotificationsScreen
import com.vitorpamplona.amethyst.desktop.ui.UserProfileScreen
import com.vitorpamplona.quartz.nip01Core.crypto.SecureKeyStorage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
private val isMacOS = System.getProperty("os.name").lowercase().contains("mac")
@@ -207,10 +213,17 @@ fun App(
) {
var currentScreen by remember { mutableStateOf<DesktopScreen>(DesktopScreen.Feed) }
val relayManager = remember { DesktopRelayConnectionManager() }
val accountManager = remember { AccountManager() }
val secureStorage = remember { SecureKeyStorage() }
val accountManager = remember { AccountManager(secureStorage) }
val accountState by accountManager.accountState.collectAsState()
val scope = remember { CoroutineScope(SupervisorJob() + Dispatchers.Main) }
// Try to load saved account on startup
DisposableEffect(Unit) {
scope.launch {
accountManager.loadSavedAccount()
}
relayManager.addDefaultRelays()
relayManager.connect()
onDispose {
@@ -376,6 +389,8 @@ fun ProfileScreen(
account: AccountState.LoggedIn,
accountManager: AccountManager,
) {
val scope = rememberCoroutineScope()
Column {
Text(
"Profile",
@@ -393,7 +408,7 @@ fun ProfileScreen(
Spacer(Modifier.height(24.dp))
OutlinedButton(
onClick = { accountManager.logout() },
onClick = { scope.launch { accountManager.logout() } },
colors =
androidx.compose.material3.ButtonDefaults.outlinedButtonColors(
contentColor = Color.Red,
@@ -32,6 +32,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -40,6 +41,7 @@ import com.vitorpamplona.amethyst.commons.account.AccountManager
import com.vitorpamplona.amethyst.commons.account.AccountState
import com.vitorpamplona.amethyst.commons.ui.auth.LoginCard
import com.vitorpamplona.amethyst.commons.ui.auth.NewKeyWarningCard
import kotlinx.coroutines.launch
@Composable
fun LoginScreen(
@@ -48,6 +50,7 @@ fun LoginScreen(
) {
var showNewKeyDialog by remember { mutableStateOf(false) }
var generatedAccount by remember { mutableStateOf<AccountState.LoggedIn?>(null) }
val scope = rememberCoroutineScope()
Column(
modifier = Modifier.fillMaxSize().padding(32.dp),
@@ -73,7 +76,11 @@ fun LoginScreen(
LoginCard(
onLogin = { keyInput ->
accountManager.loginWithKey(keyInput).map {
onLoginSuccess()
// Save account to secure storage
scope.launch {
accountManager.saveCurrentAccount()
onLoginSuccess()
}
}
},
onGenerateNew = {
@@ -89,7 +96,11 @@ fun LoginScreen(
nsec = generatedAccount!!.nsec,
onContinue = {
showNewKeyDialog = false
onLoginSuccess()
// Save generated account
scope.launch {
accountManager.saveCurrentAccount()
onLoginSuccess()
}
},
)
}