mirror of
https://github.com/mollyim/monero-wallet-sdk.git
synced 2024-12-25 07:29:23 -05:00
demo: add recover from mnemonic dialog
This commit is contained in:
parent
8febbd1543
commit
4cf0059739
@ -12,7 +12,9 @@ import im.molly.monero.demo.data.RemoteNodeRepository
|
|||||||
import im.molly.monero.demo.data.WalletRepository
|
import im.molly.monero.demo.data.WalletRepository
|
||||||
import im.molly.monero.demo.data.model.DefaultMoneroNetwork
|
import im.molly.monero.demo.data.model.DefaultMoneroNetwork
|
||||||
import im.molly.monero.demo.data.model.RemoteNode
|
import im.molly.monero.demo.data.model.RemoteNode
|
||||||
|
import im.molly.monero.mnemonics.MoneroMnemonic
|
||||||
import im.molly.monero.util.parseHex
|
import im.molly.monero.util.parseHex
|
||||||
|
import im.molly.monero.util.toHex
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
|
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
|
||||||
@ -82,6 +84,16 @@ class AddWalletViewModel(
|
|||||||
this.secretSpendKeyHex = value
|
this.secretSpendKeyHex = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun recoverFromMnemonic(words: String): Boolean {
|
||||||
|
MoneroMnemonic.recoverEntropy(words)?.use { mnemonicCode ->
|
||||||
|
val secretKey = SecretKey(mnemonicCode.entropy)
|
||||||
|
secretSpendKeyHex = secretKey.bytes.toHex()
|
||||||
|
secretKey.destroy()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fun updateCreationDate(value: String) {
|
fun updateCreationDate(value: String) {
|
||||||
this.creationDate = value
|
this.creationDate = value
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package im.molly.monero.demo.ui
|
package im.molly.monero.demo.ui
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
@ -8,6 +9,7 @@ import androidx.compose.material3.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -84,6 +86,8 @@ fun AddWalletSecondStepRoute(
|
|||||||
onNavigateToHome: () -> Unit,
|
onNavigateToHome: () -> Unit,
|
||||||
viewModel: AddWalletViewModel = viewModel(),
|
viewModel: AddWalletViewModel = viewModel(),
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
val remoteNodes by viewModel.currentRemoteNodes.collectAsStateWithLifecycle()
|
val remoteNodes by viewModel.currentRemoteNodes.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
SecondStepScreen(
|
SecondStepScreen(
|
||||||
@ -109,6 +113,12 @@ fun AddWalletSecondStepRoute(
|
|||||||
onWalletNameChanged = { name -> viewModel.updateWalletName(name) },
|
onWalletNameChanged = { name -> viewModel.updateWalletName(name) },
|
||||||
onNetworkChanged = { network -> viewModel.toggleSelectedNetwork(network) },
|
onNetworkChanged = { network -> viewModel.toggleSelectedNetwork(network) },
|
||||||
onSecretSpendKeyHexChanged = { value -> viewModel.updateSecretSpendKeyHex(value) },
|
onSecretSpendKeyHexChanged = { value -> viewModel.updateSecretSpendKeyHex(value) },
|
||||||
|
onRecoverFromMnemonic = { words ->
|
||||||
|
val success = viewModel.recoverFromMnemonic(words)
|
||||||
|
if (!success) {
|
||||||
|
Toast.makeText(context, "Invalid seed", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
},
|
||||||
onCreationDateChanged = { value -> viewModel.updateCreationDate(value) },
|
onCreationDateChanged = { value -> viewModel.updateCreationDate(value) },
|
||||||
onRestoreHeightChanged = { value -> viewModel.updateRestoreHeight(value) },
|
onRestoreHeightChanged = { value -> viewModel.updateRestoreHeight(value) },
|
||||||
remoteNodes = remoteNodes,
|
remoteNodes = remoteNodes,
|
||||||
@ -134,12 +144,14 @@ private fun SecondStepScreen(
|
|||||||
onWalletNameChanged: (String) -> Unit = {},
|
onWalletNameChanged: (String) -> Unit = {},
|
||||||
onNetworkChanged: (MoneroNetwork) -> Unit = {},
|
onNetworkChanged: (MoneroNetwork) -> Unit = {},
|
||||||
onSecretSpendKeyHexChanged: (String) -> Unit = {},
|
onSecretSpendKeyHexChanged: (String) -> Unit = {},
|
||||||
|
onRecoverFromMnemonic: (String) -> Unit = {},
|
||||||
onCreationDateChanged: (String) -> Unit = {},
|
onCreationDateChanged: (String) -> Unit = {},
|
||||||
onRestoreHeightChanged: (String) -> Unit = {},
|
onRestoreHeightChanged: (String) -> Unit = {},
|
||||||
remoteNodes: List<RemoteNode>,
|
remoteNodes: List<RemoteNode>,
|
||||||
selectedRemoteNodeIds: MutableMap<Long?, Boolean> = mutableMapOf(),
|
selectedRemoteNodeIds: MutableMap<Long?, Boolean> = mutableMapOf(),
|
||||||
) {
|
) {
|
||||||
var showOffLineConfirmationDialog by remember { mutableStateOf(false) }
|
var showOffLineConfirmationDialog by remember { mutableStateOf(false) }
|
||||||
|
var showMnemonicDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
Scaffold(topBar = {
|
Scaffold(topBar = {
|
||||||
Toolbar(
|
Toolbar(
|
||||||
@ -205,6 +217,13 @@ private fun SecondStepScreen(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(start = 16.dp, end = 16.dp),
|
.padding(start = 16.dp, end = 16.dp),
|
||||||
)
|
)
|
||||||
|
TextButton(
|
||||||
|
onClick = { showMnemonicDialog = true },
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp),
|
||||||
|
) {
|
||||||
|
Text("Recover from 25-word mnemonic")
|
||||||
|
}
|
||||||
Text(
|
Text(
|
||||||
text = "Synchronization",
|
text = "Synchronization",
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
@ -257,6 +276,37 @@ private fun SecondStepScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showMnemonicDialog) {
|
||||||
|
var words by remember { mutableStateOf("") }
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { showMnemonicDialog = false },
|
||||||
|
title = { Text("Enter your recovery phrase") },
|
||||||
|
text = {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = words,
|
||||||
|
onValueChange = { words = it },
|
||||||
|
singleLine = true,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
onRecoverFromMnemonic(words)
|
||||||
|
showMnemonicDialog = false
|
||||||
|
},
|
||||||
|
enabled = words.isNotEmpty(),
|
||||||
|
) {
|
||||||
|
Text("Confirm")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = { showMnemonicDialog = false }) {
|
||||||
|
Text("Cancel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (showOffLineConfirmationDialog) {
|
if (showOffLineConfirmationDialog) {
|
||||||
AlertDialog(onDismissRequest = { showOffLineConfirmationDialog = false }, title = {
|
AlertDialog(onDismissRequest = { showOffLineConfirmationDialog = false }, title = {
|
||||||
Text("No remote nodes selected")
|
Text("No remote nodes selected")
|
||||||
|
Loading…
Reference in New Issue
Block a user