implement wallet name suggestion

This commit is contained in:
- 2025-01-11 17:31:18 +01:00
parent 60c46e7289
commit 6296cc349f
7 changed files with 68 additions and 49 deletions

View File

@ -27,6 +27,7 @@ import org.monfluo.wallet.fragment.dialog.NodeSelectionBottomSheetDialog
import org.monfluo.wallet.listener.NodeSelectionDialogListenerAdapter
import org.monfluo.wallet.livedata.combineLiveDatas
import org.monfluo.wallet.model.Wallet
import org.monfluo.wallet.model.WalletManager
import org.monfluo.wallet.util.Constants
import org.monfluo.wallet.util.Helper
import org.monfluo.wallet.util.PreferenceUtils
@ -83,7 +84,7 @@ class OnboardingActivity : WalletOpeningActivity() {
val node = PreferenceUtils.getOrSetDefaultNode(this, DefaultNode.defaultNode())
selectNodeButton.text = getString(R.string.node_button_text, node.name)
walletNameEditText.setText(Constants.DEFAULT_WALLET_NAME)
walletNameEditText.setText(getWalletNameSuggestion())
bindListeners()
bindObservers()
@ -260,6 +261,21 @@ class OnboardingActivity : WalletOpeningActivity() {
)
}
}
private fun getWalletNameSuggestion(): String {
val walletRoot = Helper.getWalletRoot(this)
if (!WalletManager.instance.walletExists(walletRoot.resolve(Constants.DEFAULT_WALLET_NAME))) {
return Constants.DEFAULT_WALLET_NAME
}
for (i in 2 until Int.MAX_VALUE) {
val name = Constants.DEFAULT_WALLET_NAME + i
if (!WalletManager.instance.walletExists(walletRoot.resolve(name))) {
return name
}
}
Timber.e("User managed to create 2^31-3 wallets, giving up on finding a good wallet name")
return Constants.DEFAULT_WALLET_NAME
}
}
internal class OnboardingViewModel : ViewModel() {
@ -347,7 +363,7 @@ internal class OnboardingViewModel : ViewModel() {
}
return
} else {
org.monfluo.wallet.model.WalletManager.instance.createWalletPolyseed(
WalletManager.instance.createWalletPolyseed(
walletFile,
passphrase,
offset,
@ -358,7 +374,7 @@ internal class OnboardingViewModel : ViewModel() {
val tmpWalletFile =
File(activity.applicationInfo.dataDir, walletName + "_tmp")
val tmpWallet = createTempWallet(tmpWalletFile) //we do this to get seed, then recover wallet so we can use seed offset
wallet = org.monfluo.wallet.model.WalletManager.instance.recoveryWallet(
wallet = WalletManager.instance.recoveryWallet(
walletFile,
passphrase,
tmpWallet.getSeed(""),
@ -383,14 +399,14 @@ internal class OnboardingViewModel : ViewModel() {
restoreHeight = restoreHeightText.toLong()
}
if (seedTypeValue == SeedType.POLYSEED) {
wallet = org.monfluo.wallet.model.WalletManager.instance.recoveryWalletPolyseed(
wallet = WalletManager.instance.recoveryWalletPolyseed(
walletFile,
passphrase,
walletSeed,
offset
)
} else if (seedTypeValue == SeedType.LEGACY) {
wallet = org.monfluo.wallet.model.WalletManager.instance.recoveryWallet(
wallet = WalletManager.instance.recoveryWallet(
walletFile,
passphrase,
walletSeed,
@ -440,7 +456,7 @@ internal class OnboardingViewModel : ViewModel() {
}
private fun createTempWallet(tmpWalletFile: File): Wallet {
return org.monfluo.wallet.model.WalletManager.instance.createWallet(
return WalletManager.instance.createWallet(
tmpWalletFile,
"",
Constants.MNEMONIC_LANGUAGE,

View File

@ -2,8 +2,8 @@ package org.monfluo.wallet
import android.content.Intent
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import org.monfluo.wallet.fragment.dialog.PasswordBottomSheetDialog
import org.monfluo.wallet.model.WalletManager
import org.monfluo.wallet.util.Constants
import org.monfluo.wallet.util.Helper
import org.monfluo.wallet.util.PreferenceUtils
@ -17,7 +17,7 @@ class StartActivity : WalletOpeningActivity() {
setVisible(false)
val isMultiWalletMode = PreferenceUtils.isMultiWalletMode(this)
val walletPaths = org.monfluo.wallet.model.WalletManager.instance.findWallets(Helper.getWalletRoot(this).absolutePath)
val walletPaths = WalletManager.instance.findWallets(Helper.getWalletRoot(this).absolutePath)
if (walletPaths.isEmpty()) {
Timber.d("No wallets found, launching onboarding activity")
val onboardingActivityIntent = Intent(this, OnboardingActivity::class.java)

View File

@ -7,6 +7,7 @@ import android.widget.Button
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.monfluo.wallet.fragment.dialog.PasswordBottomSheetDialog
import org.monfluo.wallet.model.WalletManager
import org.monfluo.wallet.util.Helper
import org.monfluo.wallet.util.acitivity.WalletOpeningActivity
@ -23,7 +24,7 @@ class WalletActivity : WalletOpeningActivity() {
createWalletButton = findViewById(R.id.create_or_import_wallet)
walletRecyclerView = findViewById(R.id.wallet_list_recyclerview)
val walletPaths = org.monfluo.wallet.model.WalletManager.instance.findWallets(Helper.getWalletRoot(this).absolutePath)
val walletPaths = WalletManager.instance.findWallets(Helper.getWalletRoot(this).absolutePath)
adapter = WalletAdapter(walletPaths, object : WalletAdapter.AccountAdapterListener {
override fun onWalletSelected(walletPath: String) {
val passwordDialog = PasswordBottomSheetDialog(walletPath, false, object : PasswordBottomSheetDialog.Listener {

View File

@ -10,6 +10,7 @@ import android.widget.ImageButton
import android.widget.Toast
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.monfluo.wallet.R
import org.monfluo.wallet.model.WalletManager
import org.monfluo.wallet.util.Helper.getClipBoardText
class PasswordBottomSheetDialog(
@ -62,7 +63,7 @@ class PasswordBottomSheetDialog(
}
private fun checkPassword(walletPassword: String): Boolean {
return org.monfluo.wallet.model.WalletManager.instance.verifyWalletPasswordOnly(
return WalletManager.instance.verifyWalletPasswordOnly(
"$walletPath.keys",
walletPassword
)

View File

@ -206,7 +206,7 @@ class Wallet(private val handle: Long, val info: WalletInfo, private var account
external fun store(path: String?): Boolean
fun close(): Boolean {
disposePendingTransaction()
return org.monfluo.wallet.model.WalletManager.instance.closeJ(this)
return WalletManager.instance.closeJ(this)
}
external fun getFilename(): String
@ -469,7 +469,7 @@ class Wallet(private val handle: Long, val info: WalletInfo, private var account
external fun isPaymentIdValid(payment_id: String): Boolean
fun isAddressValid(address: String): Boolean {
return org.monfluo.wallet.model.WalletManager.instance.networkType.value.let {
return WalletManager.instance.networkType.value.let {
isAddressValid(
address,
it

View File

@ -22,13 +22,13 @@ import java.util.Calendar
import java.util.Locale
class WalletManager {
val networkType = org.monfluo.wallet.model.NetworkType.NetworkType_Mainnet
val networkType = NetworkType.NetworkType_Mainnet
fun createWallet(aFile: File, password: String, language: String, height: Long): org.monfluo.wallet.model.Wallet {
fun createWallet(aFile: File, password: String, language: String, height: Long): Wallet {
val walletHandle = createWalletJ(aFile.absolutePath, password, language, networkType.value)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(aFile, password)
WalletInfo(aFile, password)
)
if (wallet.status.isOk) {
// (Re-)Estimate restore height based on what we know
@ -47,7 +47,7 @@ class WalletManager {
return wallet
}
external fun findWallets(path: String): List<String> // this does not work - some error in boost
external fun findWallets(path: String): List<String>
private external fun createWalletJ(
path: String,
password: String,
@ -60,7 +60,7 @@ class WalletManager {
password: String,
passphrase: String,
language: String
): org.monfluo.wallet.model.Wallet {
): Wallet {
val walletHandle = createWalletPolyseedJ(
aFile.absolutePath,
password,
@ -68,9 +68,9 @@ class WalletManager {
language,
networkType.value
)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(aFile, password)
WalletInfo(aFile, password)
)
if (wallet.status.isOk) {
wallet.setPassword(password) // this rewrites the keys file (which contains the restore height)
@ -87,11 +87,11 @@ class WalletManager {
): Long
//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
fun openWallet(path: String, password: String): org.monfluo.wallet.model.Wallet {
fun openWallet(path: String, password: String): Wallet {
val walletHandle = openWalletJ(path, password, networkType.value)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(File(path), password)
WalletInfo(File(path), password)
)
return wallet
}
@ -101,15 +101,15 @@ class WalletManager {
aFile: File, password: String,
mnemonic: String, offset: String,
restoreHeight: Long
): org.monfluo.wallet.model.Wallet {
): Wallet {
val walletHandle = recoveryWalletJ(
aFile.absolutePath, password,
mnemonic, offset,
networkType.value, restoreHeight
)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(aFile, password)
WalletInfo(aFile, password)
)
return wallet
}
@ -123,15 +123,15 @@ class WalletManager {
fun recoveryWalletPolyseed(
aFile: File, password: String,
mnemonic: String, offset: String
): org.monfluo.wallet.model.Wallet {
): Wallet {
val walletHandle = recoveryWalletPolyseedJ(
aFile.absolutePath, password,
mnemonic, offset,
networkType.value
)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(aFile, password)
WalletInfo(aFile, password)
)
return wallet
}
@ -145,15 +145,15 @@ class WalletManager {
fun createWalletWithKeys(
aFile: File, password: String, language: String, restoreHeight: Long,
addressString: String, viewKeyString: String, spendKeyString: String
): org.monfluo.wallet.model.Wallet {
): Wallet {
val walletHandle = createWalletFromKeysJ(
aFile.absolutePath, password,
language, networkType.value, restoreHeight,
addressString, viewKeyString, spendKeyString
)
val wallet = org.monfluo.wallet.model.Wallet(
val wallet = Wallet(
walletHandle,
org.monfluo.wallet.model.WalletInfo(aFile, password)
WalletInfo(aFile, password)
)
return wallet
}
@ -176,7 +176,7 @@ class WalletManager {
subaddressLookahead: String
): Long
external fun closeJ(wallet: org.monfluo.wallet.model.Wallet?): Boolean
external fun closeJ(wallet: Wallet?): Boolean
fun walletExists(aFile: File): Boolean {
return walletExists(aFile.absolutePath)
@ -214,7 +214,7 @@ class WalletManager {
external fun resolveOpenAlias(address: String?, dnssec_valid: Boolean): String?
external fun setProxyJ(address: String?): Boolean
inner class WalletInfo(wallet: File) : Comparable<org.monfluo.wallet.model.WalletManager.WalletInfo> {
inner class WalletInfo(wallet: File) : Comparable<WalletManager.WalletInfo> {
private val path: File
private val name: String
@ -223,7 +223,7 @@ class WalletManager {
name = wallet.name
}
override fun compareTo(other: org.monfluo.wallet.model.WalletManager.WalletInfo): Int {
override fun compareTo(other: WalletManager.WalletInfo): Int {
return name.lowercase(Locale.getDefault())
.compareTo(other.name.lowercase(Locale.getDefault()))
}
@ -238,16 +238,16 @@ class WalletManager {
var LOGLEVEL_TRACE = 3
var LOGLEVEL_MAX = 4
val instance: org.monfluo.wallet.model.WalletManager
get() = synchronized(org.monfluo.wallet.model.WalletManager::class.java) {
return@synchronized org.monfluo.wallet.model.WalletManager()
val instance: WalletManager
get() = synchronized(WalletManager::class.java) {
return@synchronized WalletManager()
}
fun addressPrefix(networkType: org.monfluo.wallet.model.NetworkType): String {
fun addressPrefix(networkType: NetworkType): String {
return when (networkType) {
org.monfluo.wallet.model.NetworkType.NetworkType_Testnet -> "9A-"
org.monfluo.wallet.model.NetworkType.NetworkType_Mainnet -> "4-"
org.monfluo.wallet.model.NetworkType.NetworkType_Stagenet -> "5-"
NetworkType.NetworkType_Testnet -> "9A-"
NetworkType.NetworkType_Mainnet -> "4-"
NetworkType.NetworkType_Stagenet -> "5-"
}
}

View File

@ -14,6 +14,7 @@ import org.monfluo.wallet.model.PendingTransaction
import org.monfluo.wallet.model.Wallet
import org.monfluo.wallet.model.Wallet.Companion.NEW_ACCOUNT_NAME
import org.monfluo.wallet.model.WalletListener
import org.monfluo.wallet.model.WalletManager
import org.monfluo.wallet.util.TransactionDestination
import timber.log.Timber
import java.util.concurrent.ArrayBlockingQueue
@ -161,9 +162,9 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
daemonTrusted: Boolean,
proxy: String
) {
org.monfluo.wallet.model.WalletManager.instance.setProxyJ(proxy)
org.monfluo.wallet.model.WalletManager.instance.setDaemonAddressJ(daemonAddress)
val wallet = org.monfluo.wallet.model.WalletManager.instance.openWallet(walletName, walletPassword)
WalletManager.instance.setProxyJ(proxy)
WalletManager.instance.setDaemonAddressJ(daemonAddress)
val wallet = WalletManager.instance.openWallet(walletName, walletPassword)
Timber.i("Initializing wallet with daemon address = $daemonAddress, daemon username = $daemonUsername, daemon password = ${"*".repeat(daemonPassword.length)}, proxy = $proxy")
wallet.initJ(daemonAddress, 0, daemonUsername, daemonPassword, proxy)
wallet.setTrustedDaemon(daemonTrusted)
@ -191,8 +192,8 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
daemonTrusted: Boolean,
proxy: String
) {
org.monfluo.wallet.model.WalletManager.instance.setProxyJ(proxy)
org.monfluo.wallet.model.WalletManager.instance.setDaemonAddressJ(daemonAddress)
WalletManager.instance.setProxyJ(proxy)
WalletManager.instance.setDaemonAddressJ(daemonAddress)
walletRef.get()?.let { wallet ->
Timber.i("Re-initializing wallet with daemon address = $daemonAddress, daemon username = $daemonUsername, daemon password = ${"*".repeat(daemonPassword.length)}, proxy = $proxy")
wallet.initJ(daemonAddress, 0, daemonUsername, daemonPassword, proxy)
@ -205,7 +206,7 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
}
private fun handleFetchDaemonHeight() {
val newHeight = org.monfluo.wallet.model.WalletManager.instance.getBlockchainHeight()
val newHeight = WalletManager.instance.getBlockchainHeight()
if (newHeight > 0) {
daemonHeight.set(newHeight)
} else {
@ -267,7 +268,7 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
}
private fun handleSetProxy(value: String) {
val success = org.monfluo.wallet.model.WalletManager.instance.setProxyJ(value)
val success = WalletManager.instance.setProxyJ(value)
// we assume that if setting proxy for daemon was successful,
// then setting proxy for wallet must have been successful as well
walletRef.get()?.setProxy(value)