WIP: Cleanup
This commit is contained in:
@@ -520,7 +520,7 @@ fun GajuRouter(
|
||||
val status = withContext(Dispatchers.IO) { client.status() }
|
||||
val reportedNetworkId = status["network_id"] as? String
|
||||
|
||||
if ((reportedNetworkId != null && reportedNetworkId != wallet.networkId)) {
|
||||
if ((reportedNetworkId != null) && (reportedNetworkId != wallet.networkId)) {
|
||||
val allWallets = walletRepo.listWallets().mapNotNull { walletRepo.loadWallet(it) }
|
||||
val targetWallet = allWallets.find { it.networkId == reportedNetworkId }
|
||||
|
||||
@@ -556,7 +556,7 @@ fun GajuRouter(
|
||||
val status = withContext(Dispatchers.IO) { client.status() }
|
||||
val reportedNetworkId = status["network_id"] as? String
|
||||
|
||||
if ((reportedNetworkId != null && reportedNetworkId != wallet.networkId)) {
|
||||
if ((reportedNetworkId != null) && (reportedNetworkId != wallet.networkId)) {
|
||||
// Mismatch logic
|
||||
val allWallets = walletRepo.listWallets().mapNotNull { walletRepo.loadWallet(it) }
|
||||
val targetWallet = allWallets.find { it.networkId == reportedNetworkId }
|
||||
@@ -837,7 +837,7 @@ fun GajuRouter(
|
||||
|
||||
// If request specifies an ID, try to find that account
|
||||
val signAccount = if (request.publicId != null && request.publicId != "false") {
|
||||
wallets.flatMap { it.accounts }.find { it.gajuId == request.publicId }
|
||||
wallets.asSequence().flatMap { it.accounts }.find { it.gajuId == request.publicId }
|
||||
} else {
|
||||
activeAccount
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.Context
|
||||
import kotlinx.serialization.json.Json
|
||||
import swiss.qpq.gajumobile.data.models.Account
|
||||
import swiss.qpq.gajumobile.data.models.Wallet
|
||||
import swiss.qpq.gajumobile.security.AccountAirlock
|
||||
import swiss.qpq.gajumobile.security.EncryptionService
|
||||
import swiss.qpq.gajumobile.security.KeyManager
|
||||
import swiss.qpq.gajumaru.core.tools.NodeClient
|
||||
@@ -69,7 +68,6 @@ class WalletRepository(private val context: Context) {
|
||||
}
|
||||
|
||||
val balance = accountInfo["balance"]?.toString() ?: "0"
|
||||
val nonce = (accountInfo["nonce"] as? Number)?.toLong() ?: 0L
|
||||
|
||||
val updatedAccount = account.copy(
|
||||
cachedBalance = CachedBalance(
|
||||
@@ -90,28 +88,6 @@ class WalletRepository(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getStatus(wallet: Wallet): Map<String, Any?>? {
|
||||
val client = NodeClient(wallet.endpoints.map { NodeClient.Endpoint(it.host, it.port, it.useTls) })
|
||||
return try {
|
||||
withContext(Dispatchers.IO) {
|
||||
client.status()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun postTransaction(wallet: Wallet, signedTx: String): Map<String, Any?>? {
|
||||
val client = NodeClient(wallet.endpoints.map { NodeClient.Endpoint(it.host, it.port, it.useTls) })
|
||||
return try {
|
||||
withContext(Dispatchers.IO) {
|
||||
client.postTx(signedTx)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun listWallets(): List<String> {
|
||||
val dir = File(context.filesDir, "wallets")
|
||||
if (!dir.exists()) return emptyList()
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
import javax.crypto.SecretKey;
|
||||
import swiss.qpq.gajumaru.core.crypto.Vault;
|
||||
import swiss.qpq.gajumaru.core.encoding.Mnemonic;
|
||||
import swiss.qpq.gajumaru.core.tools.CryptoUtils;
|
||||
import swiss.qpq.gajumaru.core.tools.TransactionService;
|
||||
@@ -191,22 +190,10 @@ public final class AccountAirlock {
|
||||
try {
|
||||
return Mnemonic.encode(plaintextPrivateKey);
|
||||
} finally {
|
||||
if (plaintextPrivateKey != null) safeMemzero(plaintextPrivateKey);
|
||||
safeMemzero(plaintextPrivateKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to convert a UI String into the internal airlock byte[][] format.
|
||||
*/
|
||||
public static byte[][] stringToPhrase(String phrase) {
|
||||
String[] words = phrase.trim().split("\\s+");
|
||||
byte[][] result = new byte[words.length][];
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
result[i] = words[i].getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to wipe a phrase returned by the airlock.
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,7 @@ import swiss.qpq.gajumobile.ui.components.GajuTextField
|
||||
@Composable
|
||||
fun CreateWalletScreen(
|
||||
onWalletCreated: (name: String, networkId: String) -> Unit,
|
||||
onBack: (() -> Unit)? = null
|
||||
onBack: (() -> Unit)? = null,
|
||||
) {
|
||||
var walletName by remember { mutableStateOf("") }
|
||||
var selectedNetwork by remember { mutableStateOf("groot.mainnet") }
|
||||
|
||||
@@ -2,7 +2,7 @@ package swiss.qpq.gajumobile.ui.screens
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -267,7 +267,7 @@ fun DashboardScreen(
|
||||
androidx.compose.material3.TextButton(
|
||||
onClick = {
|
||||
val url = "https://${currentWallet.networkId}.gajumaru.io/account/${account.gajuId}"
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
context.startActivity(intent)
|
||||
},
|
||||
modifier = Modifier.padding(bottom = 12.dp)
|
||||
|
||||
@@ -72,7 +72,7 @@ fun ManageAccountScreen(
|
||||
Surface(
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
tonalElevation = 8.dp
|
||||
tonalElevation = 8.dp,
|
||||
) {
|
||||
Column(modifier = Modifier.padding(24.dp)) {
|
||||
Text(stringResource(R.string.rename_account_title), style = MaterialTheme.typography.headlineSmall)
|
||||
@@ -84,12 +84,20 @@ fun ManageAccountScreen(
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
||||
TextButton(onClick = { showRenameDialog = false }) { Text(stringResource(R.string.cancel)) }
|
||||
TextButton(
|
||||
onClick = { showRenameDialog = false }
|
||||
) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
TextButton(onClick = {
|
||||
onRename(newName)
|
||||
showRenameDialog = false
|
||||
}) { Text(stringResource(R.string.save_button_caps)) }
|
||||
TextButton(
|
||||
onClick = {
|
||||
onRename(newName)
|
||||
showRenameDialog = false
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.save_button_caps))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@ import swiss.qpq.gajumobile.ui.components.GajuTextField
|
||||
@Composable
|
||||
fun MnemonicRecoveryScreen(
|
||||
onMnemonicConfirmed: (Array<ByteArray>) -> Unit,
|
||||
onBack: () -> Unit
|
||||
onBack: () -> Unit,
|
||||
) {
|
||||
var committedWords by remember { mutableStateOf(listOf<String>()) }
|
||||
var currentDraft by remember { mutableStateOf("") }
|
||||
var isAddingWord by remember { mutableStateOf(true) }
|
||||
var isAddingWord by remember { mutableStateOf(value = true) }
|
||||
|
||||
val allWords = remember { AccountAirlock.getWordList().toList() }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
@@ -61,7 +61,7 @@ fun MnemonicRecoveryScreen(
|
||||
}
|
||||
|
||||
val suggestions = if (currentDraft.length >= 2) {
|
||||
allWords.filter { it.startsWith(currentDraft) }.take(5)
|
||||
allWords.asSequence().filter { it.startsWith(currentDraft) }.take(5).toList()
|
||||
} else emptyList()
|
||||
|
||||
Scaffold(
|
||||
@@ -72,7 +72,7 @@ fun MnemonicRecoveryScreen(
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
tonalElevation = 8.dp
|
||||
tonalElevation = 8.dp,
|
||||
) {
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(8.dp).fillMaxWidth(),
|
||||
@@ -81,7 +81,7 @@ fun MnemonicRecoveryScreen(
|
||||
suggestions.forEach { suggestion ->
|
||||
SuggestionChip(
|
||||
onClick = {
|
||||
committedWords = committedWords + suggestion
|
||||
committedWords += suggestion
|
||||
currentDraft = ""
|
||||
isAddingWord = false
|
||||
},
|
||||
@@ -109,7 +109,7 @@ fun MnemonicRecoveryScreen(
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
GajuButton(
|
||||
text = stringResource(R.string.recover_button_caps),
|
||||
enabled = committedWords.size >= 21 && !isAddingWord,
|
||||
enabled = (committedWords.size >= 21) && !isAddingWord,
|
||||
onClick = {
|
||||
val phrase = committedWords.map { it.toByteArray(Charsets.UTF_8) }.toTypedArray()
|
||||
onMnemonicConfirmed(phrase)
|
||||
@@ -160,12 +160,12 @@ fun MnemonicRecoveryScreen(
|
||||
)
|
||||
}
|
||||
|
||||
if (isAddingWord && committedWords.size < 23) {
|
||||
if ((isAddingWord) && (committedWords.size < 23)) {
|
||||
Box(modifier = Modifier.width(120.dp)) {
|
||||
GajuTextField(
|
||||
value = currentDraft,
|
||||
onValueChange = { currentDraft = it.lowercase() },
|
||||
label = "${committedWords.size + 1}",
|
||||
label = (committedWords.size + 1).toString(),
|
||||
placeholder = "...",
|
||||
modifier = Modifier.focusRequester(focusRequester)
|
||||
)
|
||||
|
||||
@@ -49,11 +49,11 @@ fun MnemonicVerifyScreen(
|
||||
label: String,
|
||||
expectedPhrase: Array<ByteArray>,
|
||||
onVerified: () -> Unit,
|
||||
onBack: () -> Unit
|
||||
onBack: () -> Unit,
|
||||
) {
|
||||
var committedWords by remember { mutableStateOf(listOf<String>()) }
|
||||
var currentDraft by remember { mutableStateOf("") }
|
||||
var isAddingWord by remember { mutableStateOf(true) }
|
||||
var isAddingWord by remember { mutableStateOf(value = true) }
|
||||
var verificationError by remember { mutableStateOf(false) }
|
||||
|
||||
val allWords = remember { AccountAirlock.getWordList().toList() }
|
||||
@@ -64,7 +64,7 @@ fun MnemonicVerifyScreen(
|
||||
}
|
||||
|
||||
val suggestions = if (currentDraft.length >= 2) {
|
||||
allWords.filter { it.startsWith(currentDraft) }.take(5)
|
||||
allWords.asSequence().filter { it.startsWith(currentDraft) }.take(5).toList()
|
||||
} else emptyList()
|
||||
|
||||
Scaffold(
|
||||
@@ -84,7 +84,7 @@ fun MnemonicVerifyScreen(
|
||||
suggestions.forEach { suggestion ->
|
||||
SuggestionChip(
|
||||
onClick = {
|
||||
committedWords = committedWords + suggestion
|
||||
committedWords += suggestion
|
||||
currentDraft = ""
|
||||
isAddingWord = false
|
||||
verificationError = false
|
||||
@@ -113,7 +113,7 @@ fun MnemonicVerifyScreen(
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
GajuButton(
|
||||
text = stringResource(R.string.verify_button_caps),
|
||||
enabled = committedWords.size == expectedPhrase.size && !isAddingWord,
|
||||
enabled = (committedWords.size == expectedPhrase.size) && !isAddingWord,
|
||||
onClick = {
|
||||
val inputPhrase = committedWords.map { it.toByteArray(Charsets.UTF_8) }
|
||||
var match = true
|
||||
@@ -179,7 +179,7 @@ fun MnemonicVerifyScreen(
|
||||
GajuTextField(
|
||||
value = currentDraft,
|
||||
onValueChange = { currentDraft = it.lowercase() },
|
||||
label = "${committedWords.size + 1}",
|
||||
label = (committedWords.size + 1).toString(),
|
||||
placeholder = "...",
|
||||
modifier = Modifier.focusRequester(focusRequester)
|
||||
)
|
||||
|
||||
@@ -62,7 +62,9 @@ fun SendReviewScreen(
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.clickable { confirmed = !confirmed }.padding(bottom = 24.dp)
|
||||
modifier = Modifier
|
||||
.clickable { confirmed = !confirmed }
|
||||
.padding(bottom = 24.dp),
|
||||
) {
|
||||
Checkbox(checked = confirmed, onCheckedChange = { confirmed = it })
|
||||
Text(
|
||||
|
||||
@@ -19,7 +19,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.AssistChip
|
||||
import androidx.compose.material3.AssistChipDefaults
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -50,12 +49,12 @@ import swiss.qpq.gajumaru.core.formatting.GajuFormat
|
||||
fun SettingsScreen(
|
||||
balanceFormat: GajuFormat.Type,
|
||||
onFormatChange: (GajuFormat.Type) -> Unit,
|
||||
onNavigate: (String) -> Unit
|
||||
onNavigate: (String) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val localeManager = remember { context.getSystemService(LocaleManager::class.java) }
|
||||
val currentLocales = localeManager.applicationLocales
|
||||
val currentLanguage = if (currentLocales.isEmpty) "en" else currentLocales.get(0).language
|
||||
val currentLanguage = if (currentLocales.isEmpty) "en" else currentLocales[0].language
|
||||
|
||||
Scaffold(
|
||||
topBar = { GajuTopBar(onNavigate = onNavigate) },
|
||||
@@ -161,7 +160,7 @@ fun SettingsScreen(
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
var showWipeConfirm by remember { mutableStateOf(false) }
|
||||
var showWipeConfirm by remember { mutableStateOf(value = false) }
|
||||
|
||||
if (showWipeConfirm) {
|
||||
Surface(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package swiss.qpq.gajumobile.ui.screens
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
@@ -68,7 +68,7 @@ fun TransactionSuccessScreen(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
val url = "https://$networkId.gajumaru.io/tx/$txHash"
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
context.startActivity(intent)
|
||||
}
|
||||
.padding(8.dp)
|
||||
|
||||
+1
-1
Submodule gm-java updated: 6714353f8c...381c8f1b9a
Reference in New Issue
Block a user