diff --git a/wallet/AndroidManifest.xml b/wallet/AndroidManifest.xml
index 1f563bbc7..910ed26b0 100644
--- a/wallet/AndroidManifest.xml
+++ b/wallet/AndroidManifest.xml
@@ -97,6 +97,11 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wallet/res/values/strings-extra.xml b/wallet/res/values/strings-extra.xml
index ada20a60f..0fb6b3e71 100644
--- a/wallet/res/values/strings-extra.xml
+++ b/wallet/res/values/strings-extra.xml
@@ -122,7 +122,7 @@
Dash address copied to clipboard
Show
\"%s\" is not a recovery phrase word
- Recovery phrase must have 12 words
+ Recovery phrase must have 12 or 24 words
Bad recovery phrase
Wallet could not be restored:\n\n%s\n\nBad recovery phrase?
@@ -473,4 +473,10 @@
Prices weren\'t retrieved. Fiat values may be incorrect.
Prices are at least 30 minutes old. Fiat values may be incorrect.
Prices have fluctuated more than 50% since the last update.
+ Select Security Level
+ You can secure your wallet with a 12 or 24 word recovery phrase.
+ Secure
+ 12 word recovery phrase
+ Very secure
+ 24 word recovery phrase
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/service/WalletFactory.kt b/wallet/src/de/schildbach/wallet/service/WalletFactory.kt
index 7ae887fc8..4e957393a 100644
--- a/wallet/src/de/schildbach/wallet/service/WalletFactory.kt
+++ b/wallet/src/de/schildbach/wallet/service/WalletFactory.kt
@@ -30,6 +30,7 @@ import org.bitcoinj.core.AddressFormatException
import org.bitcoinj.core.DumpedPrivateKey
import org.bitcoinj.core.ECKey
import org.bitcoinj.core.NetworkParameters
+import org.bitcoinj.crypto.LinuxSecureRandom
import org.bitcoinj.script.Script
import org.bitcoinj.wallet.DeterministicKeyChain
import org.bitcoinj.wallet.DeterministicSeed
@@ -49,13 +50,14 @@ import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
+import java.security.SecureRandom
import java.text.ParseException
import java.util.LinkedList
import javax.inject.Inject
interface WalletFactory {
// Onboarding
- fun create(params: NetworkParameters): Wallet
+ fun create(params: NetworkParameters, seedWordCount: Int): Wallet
fun restoreFromSeed(params: NetworkParameters, recoveryPhrase: List): Wallet
@Throws(IOException::class)
fun restoreFromFile(params: NetworkParameters, backupUri: Uri, password: String): Pair
@@ -99,8 +101,18 @@ class DashWalletFactory @Inject constructor(
}
}
- override fun create(params: NetworkParameters): Wallet {
- val wallet = WalletEx.createDeterministic(params, Script.ScriptType.P2PKH)
+ override fun create(params: NetworkParameters, seedWordCount: Int): Wallet {
+ //val wallet = WalletEx.createDeterministic(params, Script.ScriptType.P2PKH)
+ val bits = when (seedWordCount) {
+ 12 -> DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS
+ 24 -> DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS * 2
+ else -> error("only 12 or 24 words are supported when creating a wallet")
+ }
+ val wallet = WalletEx.fromSeed(
+ params,
+ DeterministicSeed(SecureRandom(), bits, ""),
+ Script.ScriptType.P2PKH
+ )
addMissingExtensions(wallet)
checkWalletValid(wallet, params)
return wallet
diff --git a/wallet/src/de/schildbach/wallet/ui/OnboardingActivity.kt b/wallet/src/de/schildbach/wallet/ui/OnboardingActivity.kt
index e52bf1dd9..2f447378c 100644
--- a/wallet/src/de/schildbach/wallet/ui/OnboardingActivity.kt
+++ b/wallet/src/de/schildbach/wallet/ui/OnboardingActivity.kt
@@ -26,6 +26,7 @@ import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.appcompat.app.AppCompatActivity
@@ -37,6 +38,7 @@ import de.schildbach.wallet.ui.main.MainActivity
import de.schildbach.wallet.security.PinRetryController
import de.schildbach.wallet_test.BuildConfig
import de.schildbach.wallet.security.SecurityGuard
+import de.schildbach.wallet.ui.onboarding.SelectSecurityLevelActivity
import de.schildbach.wallet_test.R
import de.schildbach.wallet_test.databinding.ActivityOnboardingBinding
import de.schildbach.wallet_test.databinding.ActivityOnboardingPermLockBinding
@@ -113,6 +115,16 @@ class OnboardingActivity : RestoreFromFileActivity() {
@Inject
lateinit var pinRetryController: PinRetryController
+ private val selectWordCountLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == RESULT_OK) {
+ val onboardingInvite = intent.getParcelableExtra(EXTRA_INVITE)
+ viewModel.createNewWallet(
+ onboardingInvite,
+ result.data!!.extras!!.getInt(SelectSecurityLevelActivity.EXTRA_WORD_COUNT)
+ )
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -245,8 +257,9 @@ class OnboardingActivity : RestoreFromFileActivity() {
private fun initView() {
binding.createNewWallet.setOnClickListener {
- val onboardingInvite = intent.getParcelableExtra(EXTRA_INVITE)
- viewModel.createNewWallet(onboardingInvite)
+ selectWordCountLauncher.launch(
+ Intent(this, SelectSecurityLevelActivity::class.java)
+ )
}
binding.recoveryWallet.setOnClickListener {
viewModel.logEvent(AnalyticsConstants.Onboarding.RECOVERY)
diff --git a/wallet/src/de/schildbach/wallet/ui/OnboardingViewModel.kt b/wallet/src/de/schildbach/wallet/ui/OnboardingViewModel.kt
index 5f0a17e56..b0fe72d13 100644
--- a/wallet/src/de/schildbach/wallet/ui/OnboardingViewModel.kt
+++ b/wallet/src/de/schildbach/wallet/ui/OnboardingViewModel.kt
@@ -54,10 +54,10 @@ class OnboardingViewModel @Inject constructor(
internal val finishUnecryptedWalletUpgradeAction = SingleLiveEvent()
internal val startActivityAction = SingleLiveEvent()
- fun createNewWallet(onboardingInvite: InvitationLinkData?) {
+ fun createNewWallet(onboardingInvite: InvitationLinkData?, seedWordCount: Int) {
analytics.logEvent(AnalyticsConstants.Onboarding.NEW_WALLET, mapOf())
walletApplication.initEnvironmentIfNeeded()
- val wallet = walletFactory.create(Constants.NETWORK_PARAMETERS)
+ val wallet = walletFactory.create(Constants.NETWORK_PARAMETERS, seedWordCount)
log.info("successfully created new wallet")
walletApplication.setWallet(wallet)
configuration.armBackupSeedReminder()
diff --git a/wallet/src/de/schildbach/wallet/ui/onboarding/SelectSecurityLevelActivity.kt b/wallet/src/de/schildbach/wallet/ui/onboarding/SelectSecurityLevelActivity.kt
new file mode 100644
index 000000000..295494ec5
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/onboarding/SelectSecurityLevelActivity.kt
@@ -0,0 +1,52 @@
+package de.schildbach.wallet.ui.onboarding
+
+import android.content.Intent
+import android.os.Bundle
+import de.schildbach.wallet_test.databinding.ActivityPhrasewordcountBinding
+import org.dash.wallet.common.SecureActivity
+
+class SelectSecurityLevelActivity : SecureActivity() {
+ private lateinit var binding: ActivityPhrasewordcountBinding
+ private var selectedWordCount: Int = 12
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityPhrasewordcountBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.titleBar.setOnClickListener {
+ setResult(RESULT_CANCELED)
+ finish()
+ }
+
+ binding.twelveWordsOption.setOnClickListener {
+ setMode(12)
+ }
+
+ binding.twentyFourWordsOption.setOnClickListener {
+ setMode(24)
+ }
+
+ binding.continueBtn.setOnClickListener {
+ setResult(RESULT_OK, Intent().apply { putExtra(EXTRA_WORD_COUNT, selectedWordCount) })
+ finish()
+ }
+ setMode(12)
+ }
+
+ private fun setMode(wordCount: Int) {
+ if (wordCount == 12) {
+ binding.twelveWordsOption.isSelected = true
+ binding.twentyFourWordsOption.isSelected = false
+ selectedWordCount = 12
+ } else {
+ binding.twelveWordsOption.isSelected = false
+ binding.twentyFourWordsOption.isSelected = true
+ selectedWordCount = 24
+ }
+ }
+
+ companion object {
+ const val EXTRA_WORD_COUNT = "extra_word_count"
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/util/MnemonicCodeExt.kt b/wallet/src/de/schildbach/wallet/util/MnemonicCodeExt.kt
index d654af69d..89c56287d 100644
--- a/wallet/src/de/schildbach/wallet/util/MnemonicCodeExt.kt
+++ b/wallet/src/de/schildbach/wallet/util/MnemonicCodeExt.kt
@@ -60,8 +60,8 @@ class MnemonicCodeExt(wordstream: InputStream, wordListDigest: String?) : Mnemon
@Throws(MnemonicException::class)
fun check(context: Context, words: List) {
- if (words.size != 12) {
- throw MnemonicException.MnemonicLengthException("Word list size must be 12")
+ if (words.size != 12 && words.size != 24) {
+ throw MnemonicException.MnemonicLengthException("Word list size must be 12 or 24")
}
try {
check(words)