Skip to content

Commit

Permalink
fixeds for 12 words mnemonic
Browse files Browse the repository at this point in the history
  • Loading branch information
polstianka committed Dec 6, 2024
1 parent 732e016 commit 66ad891
Show file tree
Hide file tree
Showing 19 changed files with 532 additions and 376 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.tonapps.wallet.data.account.source

import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import com.tonapps.blockchain.MnemonicHelper
import com.tonapps.blockchain.ton.extensions.getPrivateKey
import com.tonapps.blockchain.ton.extensions.hex
import com.tonapps.extensions.getByteArray
import com.tonapps.extensions.putByteArray
import com.tonapps.security.Security
import com.tonapps.security.clear
Expand Down Expand Up @@ -36,8 +35,8 @@ internal class VaultSource(context: Context) {
}

fun addMnemonic(mnemonic: List<String>): PublicKeyEd25519 {
val seed = Mnemonic.toSeed(mnemonic)
val privateKey = PrivateKeyEd25519(seed)
val privateKey = MnemonicHelper.privateKey(mnemonic)
val seed = privateKey.key.toByteArray()
val publicKey = privateKey.publicKey()

prefs.edit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class DAppsRepository(
}

private suspend fun refreshLocalPushes(accountId: String) {
if (true) {
return
}
val local = getPushes(accountId)
if (!local.isEmpty) {
setAppNotifications(local)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import android.content.res.Configuration
import android.os.Build
import android.os.StrictMode
import android.util.Log
import android.webkit.CookieManager
import androidx.camera.camera2.Camera2Config
import androidx.camera.core.CameraXConfig
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.DownsampleMode
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.core.ImageTranscoderType
import com.facebook.imagepipeline.core.MemoryChunkType
import com.tonapps.blockchain.MnemonicHelper
import com.tonapps.blockchain.ton.contract.BaseWalletContract
import com.tonapps.blockchain.ton.extensions.toWalletAddress
import com.tonapps.extensions.setLocales
import com.tonapps.icu.CurrencyFormatter
import com.tonapps.tonkeeper.koin.koinModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import androidx.lifecycle.lifecycleScope
import com.tonapps.uikit.color.textSecondaryColor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.ton.mnemonic.Mnemonic
Expand All @@ -39,6 +41,7 @@ class WordEditText @JvmOverloads constructor(
get() = findViewTreeLifecycleOwner()?.lifecycleScope

private val inputDrawable = InputDrawable(context)
private var checkValueJob: Job? = null

init {
background = inputDrawable
Expand All @@ -63,15 +66,16 @@ class WordEditText @JvmOverloads constructor(
setStartDrawable(IndexDrawable(context, tag))
}

private fun checkValue() {
fun checkValue() {
checkValueJob?.cancel()
val value = text.toString()
if (value.isEmpty()) {
inputDrawable.error = false
return
}
scope?.launch {
if (!isValidWord(value)) {
inputDrawable.error = true
}
checkValueJob = scope?.launch {
delay(120)
inputDrawable.error = !isValidWord(value)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class InitModelState(private val savedStateHandle: SavedStateHandle) {
private const val LEDGER_CONNECT_DATA = "ledger_connect_data"
private const val ENABLE_PUSH_KEY = "enable_push"
private const val KEYSTONE_KEY = "keystone"
private const val WORDS_COUNT_KEY = "words_count"
}

val labelFlow = savedStateHandle.getStateFlow(LABEL_KEY, Wallet.Label("", "", Color.TRANSPARENT))
Expand All @@ -60,6 +61,10 @@ class InitModelState(private val savedStateHandle: SavedStateHandle) {
get() = savedStateHandle[PASSCODE_KEY]
set(value) = savedStateHandle.set(PASSCODE_KEY, value)

var wordsCount: Int
get() = savedStateHandle[WORDS_COUNT_KEY] ?: 24
set(value) = savedStateHandle.set(WORDS_COUNT_KEY, value)

var label: Wallet.Label?
get() = savedStateHandle[LABEL_KEY]
set(value) = savedStateHandle.set(LABEL_KEY, value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import android.graphics.Color
import android.util.Log
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tonapps.blockchain.MnemonicHelper
import com.tonapps.blockchain.ton.AndroidSecureRandom
import com.tonapps.blockchain.ton.EntropyHelper
import com.tonapps.blockchain.ton.TonMnemonic
Expand Down Expand Up @@ -127,6 +129,12 @@ class InitViewModel(
private val requestSetPinCode: Boolean
get() = (type == InitArgs.Type.New || type == InitArgs.Type.Import || type == InitArgs.Type.Testnet) && !isPinSet.get()

var wordsCount: Int
get() = savedState.wordsCount
set(value) {
savedState.wordsCount = value
}

init {
savedState.publicKey = args.publicKey?.let {
InitModelState.PublicKey(publicKey = it)
Expand Down Expand Up @@ -220,16 +228,23 @@ class InitViewModel(
}
}

suspend fun setMnemonic(words: List<String>) {
savedState.mnemonic = words
resolveWallets(words)
suspend fun setMnemonic(words: List<String>): Boolean {
if (resolveWallets(words)) {
savedState.mnemonic = words
return true
}
return false
}

private suspend fun resolveWallets(mnemonic: List<String>) = withContext(Dispatchers.IO) {
val seed = Mnemonic.toSeed(mnemonic)
val privateKey = PrivateKeyEd25519(seed)
val publicKey = privateKey.publicKey()
resolveWallets(InitModelState.PublicKey(publicKey = publicKey))
private suspend fun resolveWallets(mnemonic: List<String>): Boolean = withContext(Dispatchers.IO) {
try {
val privateKey = MnemonicHelper.privateKey(mnemonic)
val publicKey = privateKey.publicKey()
resolveWallets(InitModelState.PublicKey(publicKey = publicKey))
true
} catch (e: Throwable) {
false
}
}

private suspend fun resolveWallets(publicKey: InitModelState.PublicKey) = withContext(Dispatchers.IO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.view.updatePadding
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.lifecycleScope
import com.tonapps.blockchain.MnemonicHelper
import com.tonapps.blockchain.ton.TonMnemonic
import com.tonapps.tonkeeper.extensions.toast
import com.tonapps.tonkeeper.ui.component.WordEditText
Expand Down Expand Up @@ -55,8 +56,6 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {

override val secure: Boolean = !BuildConfig.DEBUG

private var wordsCount = WORDS24

private lateinit var scrollView: NestedScrollView
private lateinit var contentView: ColumnLayout
private lateinit var button: Button
Expand All @@ -70,7 +69,7 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {
get() = suggestionsView.visibility == View.VISIBLE && suggestionsView.alpha > 0f

private val wordInputs: List<WordEditText> by lazy {
contentView.getViews().filterIsInstance<WordEditText>()
contentView.findViewById<ColumnLayout>(R.id.inputs).getViews().filterIsInstance<WordEditText>()
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -125,41 +124,41 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {
contentView.updatePadding(top = it)
}

scrollView.doKeyboardAnimation { offset, progress, isShowing ->
scrollView.doKeyboardAnimation { offset, progress, _ ->
scrollView.updatePadding(bottom = offset)
suggestionsView.translationY = -offset.toFloat()
suggestionsView.alpha = progress
}

setWordsCount(initViewModel.wordsCount)
}

private fun isLastIndex(index: Int): Boolean {
return wordsCount - 1 == index
return initViewModel.wordsCount - 1 == index
}

private fun setWordsCount(count: Int) {
if (wordsCount == count || count != WORDS24 && count != WORDS12) {
if (initViewModel.wordsCount == count || count != WORDS24 && count != WORDS12) {
return
}
if (count == WORDS24) {
words24View.setBackgroundResource(uikit.R.drawable.bg_content_tint_16)
words12View.background = null
wordsCount = count
titleView.desciption = getString(Localization.import_wallet_description)
initViewModel.wordsCount = count
wordInputs[11].imeOptions = EditorInfo.IME_ACTION_NEXT
} else {
words12View.setBackgroundResource(uikit.R.drawable.bg_content_tint_16)
words24View.background = null
titleView.desciption = getString(Localization.import_wallet_description).replace("24", "12")
wordInputs[23].imeOptions = EditorInfo.IME_ACTION_NEXT
}
wordsCount = count
initViewModel.wordsCount = count
wordInputs[count - 1].imeOptions = EditorInfo.IME_ACTION_DONE
updateVisibleInputs()
}

private fun updateVisibleInputs() {
wordInputs.forEachIndexed { index, wordInput ->
wordInput.visibility = if (index < wordsCount) View.VISIBLE else View.GONE
wordInput.visibility = if (index < initViewModel.wordsCount) View.VISIBLE else View.GONE
}
postOnAnimation { checkWords() }
}
Expand All @@ -178,28 +177,27 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {
if (!word.isNullOrBlank()) {
withContext(Dispatchers.Main) {
inputView.setText(word)
inputView.checkValue()
suggestionsView.visibility = View.GONE
}
}
}
}

private fun next() {
lifecycleScope.launch {
setLoading()
val words = getMnemonic()
if (words.isEmpty() || (wordsCount == WORDS24 && !Mnemonic.isValid(words))) {
if (TonMnemonic.isValidTONKeychain(words)) {
navigation?.toast(Localization.multi_account_secret_wrong)
} else {
if (TonMnemonic.isValidTONKeychain(words)) {
navigation?.toast(Localization.multi_account_secret_wrong)
} else {
try {
initViewModel.setMnemonic(words)
} catch (e: Throwable) {
navigation?.toast(Localization.incorrect_phrase)
}
return@launch
}
setLoading()
try {
initViewModel.setMnemonic(words)
} catch (e: Throwable) {
setDefault()
}
setDefault()
}
}

Expand Down Expand Up @@ -292,7 +290,7 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {

if (nextFocusInput != null && nextFocusInput.visibility == View.VISIBLE) {
nextFocusInput.requestFocus()
if (index > (wordsCount - 4)) {
if (index > (initViewModel.wordsCount - 4)) {
scrollView.scrollDown(true)
} else {
scrollView.scrollView(
Expand Down Expand Up @@ -320,7 +318,7 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {
if (delay > 0) {
delay(delay)
}
button.isEnabled = getMnemonic().size == wordsCount
button.isEnabled = getMnemonic().size == initViewModel.wordsCount
}
}

Expand All @@ -329,7 +327,7 @@ class WordsScreen: BaseFragment(R.layout.fragment_init_words) {
.map { it.text?.toString() }
.filter { TonMnemonic.isValid(it) }
.filterNotNull()
.take(wordsCount)
.take(initViewModel.wordsCount)

if (words.size == wordInputs.count { it.visibility == View.VISIBLE }) {
words
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tonapps.tonkeeper.ui.screen.swap

import android.net.Uri
import android.util.Log
import com.tonapps.wallet.data.core.entity.SignRequestEntity
import org.json.JSONArray
import uikit.widget.webview.bridge.JsBridge
Expand Down
Loading

0 comments on commit 66ad891

Please sign in to comment.