From 6cc6bcfa4c02e633394459cb33c5940d0e0e0766 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 19 Nov 2024 14:32:47 +0300 Subject: [PATCH] Updated on 2026-08-14 --- features/onboarding-v2/impl/build.gradle.kts | 2 + .../MultiWalletSeedPhraseComponent.kt | 5 + .../seedphrase/model/MnemonicRepository.kt | 35 ++++++ .../model/MultiWalletSeedPhraseModel.kt | 102 ++++++++++++----- .../child/seedphrase/model/SeedPhraseState.kt | 6 +- .../impl/child/seedphrase/model/Utils.kt | 27 +++++ .../GenerateSeedPhraseUiStateBuilder.kt | 52 +++++++++ .../builder/SeedPhraseCheckUiStateBuilder.kt | 105 ++++++++++++++++++ .../ui/MultiWalletSeedPhraseWords.kt | 54 ++++----- .../impl/model/OnboardingMultiWalletModel.kt | 1 + 10 files changed, 327 insertions(+), 62 deletions(-) create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/Utils.kt create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt diff --git a/features/onboarding-v2/impl/build.gradle.kts b/features/onboarding-v2/impl/build.gradle.kts index fac172d9d1..112c1b01f6 100644 --- a/features/onboarding-v2/impl/build.gradle.kts +++ b/features/onboarding-v2/impl/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { implementation(projects.core.ui) implementation(projects.core.res) implementation(projects.core.decompose) + implementation(projects.core.navigation) /** Domain */ implementation(projects.domain.models) @@ -51,6 +52,7 @@ dependencies { implementation(deps.compose.ui.tooling) implementation(deps.compose.coil) implementation(deps.decompose.ext.compose) + implementation(deps.androidx.activity.compose) /** Other libraries */ implementation(deps.kotlin.immutable.collections) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/MultiWalletSeedPhraseComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/MultiWalletSeedPhraseComponent.kt index 89340f3ab8..505018842e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/MultiWalletSeedPhraseComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/MultiWalletSeedPhraseComponent.kt @@ -1,5 +1,6 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase +import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier @@ -36,6 +37,10 @@ class MultiWalletSeedPhraseComponent( override fun Content(modifier: Modifier) { val state by model.uiState.collectAsStateWithLifecycle() + BackHandler(enabled = true) { + model.onBack() + } + MultiWalletSeedPhrase( modifier = modifier, state = state, diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt new file mode 100644 index 0000000000..6b6ae2b138 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt @@ -0,0 +1,35 @@ +package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model + +import android.content.Context +import com.tangem.crypto.bip39.DefaultMnemonic +import com.tangem.crypto.bip39.EntropyLength +import com.tangem.crypto.bip39.Mnemonic +import com.tangem.crypto.bip39.Wordlist +import com.tangem.sdk.extensions.getWordlist +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + +class MnemonicRepository @Inject constructor( + @ApplicationContext private val context: Context, +) { + private val wordlist = Wordlist.getWordlist(context) + + val words: Set = wordlist.words.toHashSet() + + fun generateMnemonic(type: MnemonicType = MnemonicType.Words12): Mnemonic = DefaultMnemonic( + entropy = when (type) { + MnemonicType.Words12 -> EntropyLength.Bits128Length + MnemonicType.Words24 -> EntropyLength.Bits256Length + }, + wordlist = wordlist, + ) + + fun generateMnemonic(mnemonicString: String): Mnemonic = DefaultMnemonic( + mnemonic = mnemonicString, + wordlist = wordlist, + ) + + enum class MnemonicType { + Words12, Words24, + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt index 5dcc192bb2..c867aaf14c 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt @@ -2,9 +2,11 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.mode import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model +import com.tangem.core.navigation.url.UrlOpener +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder.GenerateSeedPhraseUiStateBuilder +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder.SeedPhraseCheckUiStateBuilder import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update @@ -13,44 +15,92 @@ import javax.inject.Inject @ComponentScoped class MultiWalletSeedPhraseModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, + private val mnemonicRepository: MnemonicRepository, + private val urlOpener: UrlOpener, ) : Model() { private val state = MutableStateFlow(SeedPhraseState()) + private val _uiState = MutableStateFlow(getStartState()) - private val _uiState = MutableStateFlow( - MultiWalletSeedPhraseUM.Start( - onImportSeedPhraseClicked = {}, - onGenerateSeedPhraseClicked = { - openGeneratedSeedPhrase() - }, - onLearnMoreClicked = {}, - ), + private val generateSeedPhraseUiStateBuilder = GenerateSeedPhraseUiStateBuilder( + state = state, + updateUiState = { block -> updateUiStateSpecific(block) }, + onContinue = { openWordsCheck() }, + ) + + private val seedPhraseCheckUiStateBuilder = SeedPhraseCheckUiStateBuilder( + state = state, + currentUiState = { _uiState.value }, + updateUiState = { block -> updateUiStateSpecific(block) }, + importWallet = { }, ) val uiState = _uiState.asStateFlow() fun onBack() { - TODO("Not yet implemented") + when (_uiState.value) { + is MultiWalletSeedPhraseUM.Start -> { + // TODO navigate back + } + is MultiWalletSeedPhraseUM.Import, + is MultiWalletSeedPhraseUM.GenerateSeedPhrase, + -> { + _uiState.value = getStartState() + state.value = SeedPhraseState() + } + is MultiWalletSeedPhraseUM.GeneratedWordsCheck -> { + openGeneratedSeedPhrase() + } + } } - private fun openGeneratedSeedPhrase() { - // TODO state.value.generatedWords - val words = listOf("word, word") - - _uiState.value = MultiWalletSeedPhraseUM.GenerateSeedPhrase( - words24OptionSelected = false, - words = words.mapIndexed { index, s -> - MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem(index, s) - }.toImmutableList(), - onWords24OptionSwitch = { - _uiState.update { - if (it !is MultiWalletSeedPhraseUM.GenerateSeedPhrase) return@update it - it.copy(words24OptionSelected = it.words24OptionSelected.not()) - } - state.update { it.copy(words24Option = it.words24Option.not()) } + private fun getStartState(): MultiWalletSeedPhraseUM { + return MultiWalletSeedPhraseUM.Start( + onImportSeedPhraseClicked = {}, + onGenerateSeedPhraseClicked = { + generateSeedPhrase() + openGeneratedSeedPhrase() }, - onContinueClick = { + onLearnMoreClicked = { + urlOpener.openUrl(seedPhraseLearnMoreUrl()) }, ) } + + private fun openGeneratedSeedPhrase() { + // TODO analytics SeedPhraseEvents.ButtonGenerateSeedPhrase + + val words12 = state.value.generatedWords12 ?: return + val words24 = state.value.generatedWords24 ?: return + + // TODO disallow screenshots + + _uiState.value = generateSeedPhraseUiStateBuilder.getState( + generatedWords12 = words12, + generatedWords24 = words24, + ) + } + + private fun openWordsCheck() { + _uiState.value = seedPhraseCheckUiStateBuilder.getState() + } + + private fun generateSeedPhrase() { + val words12 = mnemonicRepository.generateMnemonic(MnemonicRepository.MnemonicType.Words12) + val words24 = mnemonicRepository.generateMnemonic(MnemonicRepository.MnemonicType.Words24) + + state.update { + it.copy( + generatedWords12 = words12, + generatedWords24 = words24, + ) + } + } + + private inline fun updateUiStateSpecific(block: (T) -> T) { + _uiState.update { + if (it !is T) return@update it + block(it) + } + } } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt index 8b854a461c..796cd1599a 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt @@ -1,6 +1,10 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model +import com.tangem.crypto.bip39.Mnemonic + data class SeedPhraseState( - val generatedWords: List? = null, + val generatedWords12: Mnemonic? = null, + val generatedWords24: Mnemonic? = null, val words24Option: Boolean = false, + val readyToImport: Boolean = false, ) \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/Utils.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/Utils.kt new file mode 100644 index 0000000000..af12fa1b39 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/Utils.kt @@ -0,0 +1,27 @@ +package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model + +import android.net.Uri +import com.tangem.utils.SupportedLanguages +import java.util.Locale + +internal fun seedPhraseLearnMoreUrl(): String { + val language = Locale.getDefault().language + + val languageBy = "by" + if (SupportedLanguages.RUSSIAN.equals(language, true) || + languageBy.equals(language, true) + ) { + SupportedLanguages.RUSSIAN + } else { + SupportedLanguages.ENGLISH + } + + val webUri = Uri.Builder() + .scheme("https") + .authority("tangem.com") + .appendPath(language) + .appendPath("blog/post/seed-phrase-a-risky-solution") + .build() + + return webUri.toString() +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt new file mode 100644 index 0000000000..2d45732a3a --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt @@ -0,0 +1,52 @@ +package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder + +import com.tangem.crypto.bip39.Mnemonic +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.SeedPhraseState +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +class GenerateSeedPhraseUiStateBuilder( + private val state: MutableStateFlow, + private val updateUiState: ( + (MultiWalletSeedPhraseUM.GenerateSeedPhrase) -> MultiWalletSeedPhraseUM.GenerateSeedPhrase, + ) -> Unit, + private val onContinue: () -> Unit, +) { + + fun getState(generatedWords12: Mnemonic, generatedWords24: Mnemonic): MultiWalletSeedPhraseUM.GenerateSeedPhrase { + val words12 = generatedWords12.mnemonicComponents.mapIndexed { index, s -> + MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem(index + 1, s) + }.toImmutableList() + val words24 = generatedWords24.mnemonicComponents.mapIndexed { index, s -> + MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem(index + 1, s) + }.toImmutableList() + + return MultiWalletSeedPhraseUM.GenerateSeedPhrase( + words24OptionSelected = state.value.words24Option, + words = words12, + onWords24OptionSwitch = { switchType(words12, words24) }, + onContinueClick = onContinue, + ) + } + + private fun switchType( + generatedWords12: ImmutableList, + generatedWords24: ImmutableList, + ) { + updateUiState { uiSt -> + state.update { it.copy(words24Option = uiSt.words24OptionSelected.not()) } + + uiSt.copy( + words24OptionSelected = uiSt.words24OptionSelected.not(), + words = if (uiSt.words24OptionSelected) { + generatedWords12 + } else { + generatedWords24 + }, + ) + } + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt new file mode 100644 index 0000000000..eca9aa9570 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt @@ -0,0 +1,105 @@ +package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder + +import androidx.compose.ui.text.input.TextFieldValue +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.SeedPhraseState +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +class SeedPhraseCheckUiStateBuilder( + private val state: MutableStateFlow, + private val currentUiState: () -> MultiWalletSeedPhraseUM, + private val updateUiState: ( + (MultiWalletSeedPhraseUM.GeneratedWordsCheck) -> MultiWalletSeedPhraseUM.GeneratedWordsCheck, + ) -> Unit, + private val importWallet: () -> Unit, +) { + + @Suppress("MagicNumber") + fun getState(): MultiWalletSeedPhraseUM.GeneratedWordsCheck { + val wordFields = List(3) { index -> + val shownIndex = when (index) { + 0 -> 2 + 1 -> 7 + 2 -> 11 + else -> error("") + } + + MultiWalletSeedPhraseUM.GeneratedWordsCheck.WordField( + index = shownIndex, + word = TextFieldValue(""), + error = false, + onChange = { changeField -> + updateUiState { st -> + val newState = st.copy( + wordFields = st.wordFields.map { wordField -> + if (wordField.index == shownIndex) { + wordField.updateField(changeField, shownIndex) + } else { + wordField + } + }.toImmutableList(), + ) + + val allFieldsCorrect = newState.allFieldsCorrect() + state.update { it.copy(readyToImport = allFieldsCorrect) } + + newState.copy( + createWalletButtonEnabled = allFieldsCorrect, + ) + } + }, + ) + }.toImmutableList() + + return MultiWalletSeedPhraseUM.GeneratedWordsCheck( + wordFields = wordFields, + createWalletButtonEnabled = false, + createWalletButtonProgress = false, + onCreateWalletButtonClick = { + val currentState = currentUiState() as? MultiWalletSeedPhraseUM.GeneratedWordsCheck + ?: return@GeneratedWordsCheck + if (currentState.createWalletButtonEnabled) { + importWallet() + } + }, + ) + } + + private fun MultiWalletSeedPhraseUM.GeneratedWordsCheck.WordField.updateField( + newText: TextFieldValue, + shownIndex: Int, + ): MultiWalletSeedPhraseUM.GeneratedWordsCheck.WordField { + val correct = checkWordField(word = newText.text, shownIndex = shownIndex) + + return copy( + word = newText, + error = correct.not(), + ) + } + + private fun MultiWalletSeedPhraseUM.GeneratedWordsCheck.allFieldsCorrect(): Boolean { + return wordFields.all { + checkWordField( + word = it.word.text, + shownIndex = it.index, + ) + } + } + + private fun checkWordField(word: String, shownIndex: Int): Boolean { + val currentState = state.value + + currentState.generatedWords12 ?: return false + currentState.generatedWords24 ?: return false + + val wordList = if (currentState.words24Option) { + currentState.generatedWords24 + } else { + currentState.generatedWords12 + }.mnemonicComponents + + return wordList[shownIndex - 1] == word + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt index bba9e89256..4e651c9944 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt @@ -23,6 +23,7 @@ import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.st import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList @Composable fun MultiWalletSeedPhraseWords(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, modifier: Modifier = Modifier) { @@ -37,19 +38,18 @@ fun MultiWalletSeedPhraseWords(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase SeedPhraseGridBlock( mnemonicGridItems = state.words, modifier = Modifier - .padding(top = 20.dp, bottom = 92.dp), + .weight(1f) + .fillMaxWidth() + .padding(top = 20.dp, bottom = 32.dp), ) - Box(Modifier.weight(1f)) { - PrimaryButton( - modifier = Modifier - .align(Alignment.BottomCenter) - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), - text = stringResource(id = R.string.common_continue), - onClick = state.onContinueClick, - ) - } + PrimaryButton( + modifier = Modifier + .fillMaxWidth() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), + text = stringResource(id = R.string.common_continue), + onClick = state.onContinueClick, + ) } } @@ -61,7 +61,7 @@ private fun SegmentSeedBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, config = persistentListOf(0, 1), initialSelectedItem = if (state.words24OptionSelected.not()) 0 else 1, onClick = { - if (state.words24OptionSelected && it == 1 || state.words24OptionSelected.not() && it == 0) { + if (state.words24OptionSelected && it == 0 || state.words24OptionSelected.not() && it == 1) { state.onWords24OptionSwitch() } }, @@ -160,10 +160,10 @@ private inline fun VerticalGrid( ) { val columnLength = items.size / 2 Row( - modifier = modifier.fillMaxWidth(), + modifier = modifier, horizontalArrangement = Arrangement.SpaceEvenly, ) { - for (index in 0 until 2) { + repeat(2) { index -> Column { for (i in 0 until columnLength) { val item = items[index * columnLength + i] @@ -174,34 +174,18 @@ private inline fun VerticalGrid( } } -@Preview(showBackground = true) +@Preview(showBackground = true, heightDp = 640) @Composable private fun Preview() { TangemThemePreview { MultiWalletSeedPhraseWords( state = MultiWalletSeedPhraseUM.GenerateSeedPhrase( - words = persistentListOf( + words = List(24) { MnemonicGridItem( - index = 0, + index = it + 1, mnemonic = "word1", - ), - MnemonicGridItem( - index = 1, - mnemonic = "word1", - ), - MnemonicGridItem( - index = 2, - mnemonic = "word1", - ), - MnemonicGridItem( - index = 3, - mnemonic = "word1", - ), - MnemonicGridItem( - index = 4, - mnemonic = "word1", - ), - ), + ) + }.toImmutableList(), ), ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt index 5a8c2f5fca..2cb99f6ed2 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt @@ -42,6 +42,7 @@ internal class OnboardingMultiWalletModel @Inject constructor( private fun getInitialStep(): OnboardingMultiWalletState.Step { val card = params.scanResponse.card + // todo check local storage for scan response return when { card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup -> OnboardingMultiWalletState.Step.AddBackupDevice