From 65a2c8e9dba2eda1b9b9797b452a9273837fbf89 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 5 Jun 2023 19:48:11 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../models/AddCustomTokenViewsModels.kt | 32 ++++ .../ui/AddCustomTokenPreviewData.kt | 10 +- .../ui/components/AddCustomTokenForm.kt | 38 ++-- .../viewmodels/AddCustomTokenViewModel.kt | 170 ++++++++++++++---- core/res/src/main/res/values-ru/strings.xml | 2 + core/res/src/main/res/values/strings.xml | 2 + .../domain/common/extensions/Blockchain.kt | 1 + 7 files changed, 180 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt index a43c5a84c4..71c369bcad 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt @@ -67,6 +67,8 @@ internal data class AddCustomTokenChooseTokenBottomSheet( * @property tokenSymbolInputField input field to enter the token symbol * @property decimalsInputField input field to enter the token decimals * @property derivationPathSelectorField selector field to select the derivation path + * @property derivationPathInputField input field for a custom derivation path + * @property showTokenFields if token fields should be shown */ internal data class AddCustomTokenForm( val contractAddressInputField: AddCustomTokenInputField.ContactAddress, @@ -75,6 +77,8 @@ internal data class AddCustomTokenForm( val tokenSymbolInputField: AddCustomTokenInputField.TokenSymbol, val decimalsInputField: AddCustomTokenInputField.Decimals, val derivationPathSelectorField: AddCustomTokenSelectorField.DerivationPath?, + val derivationPathInputField: AddCustomTokenInputField.DerivationPath?, + val showTokenFields: Boolean = false, ) /** Base input field model of add custom token screen */ @@ -174,6 +178,25 @@ internal sealed interface AddCustomTokenInputField { override val placeholder: TextReference, val isEnabled: Boolean, ) : AddCustomTokenInputField + + /** + * Input field model to enter a custom derivation path + * + * @property value current value + * @property onValueChange lambda be invoked when value is been changed + * @property keyboardOptions keyboard options + * @property label label + * @property placeholder placeholder (hint) + * @property showField whether the field should be shown + */ + data class DerivationPath( + override val value: String, + override val onValueChange: (String) -> Unit, + override val keyboardOptions: KeyboardOptions, + override val label: TextReference, + override val placeholder: TextReference, + val showField: Boolean = false, + ) : AddCustomTokenInputField } /** Base selector field model of add custom token screen */ @@ -251,10 +274,15 @@ internal sealed interface AddCustomTokenSelectorField { override val title: TextReference, override val blockchain: Blockchain, val subtitle: TextReference, + val type: DerivationPathSelectorType = DerivationPathSelectorType.BLOCKCHAIN, ) : SelectorItem } } +enum class DerivationPathSelectorType { + DEFAULT, CUSTOM, BLOCKCHAIN +} + /** * Warning model of add custom token screen * @@ -276,6 +304,10 @@ internal sealed class AddCustomTokenWarning(val description: TextReference) { object UnsupportedSolanaToken : AddCustomTokenWarning( description = TextReference.Res(R.string.alert_manage_tokens_unsupported_message), ) + + object WrongDerivationPath : AddCustomTokenWarning( + description = TextReference.Res(R.string.custom_token_invalid_derivation_path), + ) } /** diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt index e463c90ae9..d69f1c08fa 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt @@ -4,14 +4,7 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenFloatingButton -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenForm -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenInputField -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenSelectorField -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenTestBlock -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenWarning -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokensToolbar +import com.tangem.tap.features.customtoken.impl.presentation.models.* import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder import com.tangem.tap.features.details.ui.cardsettings.TextReference import com.tangem.wallet.R @@ -85,6 +78,7 @@ internal object AddCustomTokenPreviewData { onMenuItemClick = {}, isEnabled = true, ), + derivationPathInputField = null, ) } diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt index 6b2e38d732..0051e2e6c4 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt @@ -1,31 +1,11 @@ package com.tangem.tap.features.customtoken.impl.presentation.ui.components -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically +import androidx.compose.animation.* import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Card -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ExposedDropdownMenuBox -import androidx.compose.material.ExposedDropdownMenuDefaults -import androidx.compose.material.LinearProgressIndicator -import androidx.compose.material.MaterialTheme -import androidx.compose.material.OutlinedTextField -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.material.* +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -62,12 +42,13 @@ internal fun AddCustomTokenForm(model: AddCustomTokenForm) { modifier = Modifier.padding(TangemTheme.dimens.spacing16), verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), ) { - InputField(model = model.contractAddressInputField) + if (model.showTokenFields) InputField(model = model.contractAddressInputField) SelectorField(model = model.networkSelectorField) - InputField(model = model.tokenNameInputField) - InputField(model = model.tokenSymbolInputField) - InputField(model = model.decimalsInputField) + if (model.showTokenFields) InputField(model = model.tokenNameInputField) + if (model.showTokenFields) InputField(model = model.tokenSymbolInputField) + if (model.showTokenFields) InputField(model = model.decimalsInputField) model.derivationPathSelectorField?.let { SelectorField(model = it) } + if (model.derivationPathInputField?.showField == true) InputField(model = model.derivationPathInputField) } } } @@ -103,6 +84,7 @@ private fun TextField(model: AddCustomTokenInputField, isError: Boolean) { is AddCustomTokenInputField.Decimals -> model.isEnabled is AddCustomTokenInputField.TokenName -> model.isEnabled is AddCustomTokenInputField.TokenSymbol -> model.isEnabled + is AddCustomTokenInputField.DerivationPath -> true } OutlinedTextField( diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt index 74084af835..1d886914c7 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt @@ -15,6 +15,7 @@ import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.Token import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.crypto.hdWallet.HDWalletError import com.tangem.domain.AddCustomTokenError import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.* @@ -135,18 +136,28 @@ internal class AddCustomTokenViewModel @Inject constructor( tokenSymbolInputField = createTokenSymbolInputField(), decimalsInputField = createDecimalsInputField(), derivationPathSelectorField = createDerivationPathsSelectorField(), + derivationPathInputField = createDerivationPathInputField(), ) } - fun createDerivationPathSelectorItem(blockchain: Blockchain): SelectorItem.TitleWithSubtitle { - return if (blockchain == Blockchain.Unknown) { - SelectorItem.TitleWithSubtitle( + fun createDerivationPathSelectorAdditionalItem( + blockchain: Blockchain, + type: DerivationPathSelectorType = DerivationPathSelectorType.BLOCKCHAIN, + ): SelectorItem.TitleWithSubtitle { + return when (type) { + DerivationPathSelectorType.DEFAULT -> SelectorItem.TitleWithSubtitle( title = TextReference.Res(R.string.custom_token_derivation_path_default), subtitle = TextReference.Res(R.string.custom_token_derivation_path_default), blockchain = Blockchain.Unknown, + type = DerivationPathSelectorType.DEFAULT, ) - } else { - SelectorItem.TitleWithSubtitle( + DerivationPathSelectorType.CUSTOM -> SelectorItem.TitleWithSubtitle( + title = TextReference.Res(R.string.custom_token_custom_derivation), + subtitle = TextReference.Res(R.string.custom_token_custom_derivation), + blockchain = Blockchain.Unknown, + type = DerivationPathSelectorType.CUSTOM, + ) + DerivationPathSelectorType.BLOCKCHAIN -> SelectorItem.TitleWithSubtitle( title = blockchain.derivationPath(DerivationStyle.LEGACY)?.rawPath?.let(TextReference::Str) ?: TextReference.Res(R.string.custom_token_derivation_path_default), subtitle = TextReference.Str(blockchain.fullName), @@ -175,7 +186,7 @@ internal class AddCustomTokenViewModel @Inject constructor( onValueChange = actionsHandler::onContactAddressValueChange, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), label = TextReference.Res(R.string.custom_token_contract_address_input_title), - placeholder = TextReference.Str(value = "0x0000000000000000000000000000000000000000"), + placeholder = TextReference.Str(value = CONTRACT_ADDRESS_PLACEHOLDER), isLoading = false, isError = false, error = null, @@ -196,8 +207,7 @@ internal class AddCustomTokenViewModel @Inject constructor( val defaultNetwork = createNetworkSelectorItem(blockchain = Blockchain.Unknown) return listOf(defaultNetwork) + Blockchain.values() .filter { blockchain -> - (blockchain.isEvm() || blockchain.canHandleTokens()) && - reduxStateHolder.scanResponse?.card?.supportedBlockchains()?.contains(blockchain) == true + reduxStateHolder.scanResponse?.card?.supportedBlockchains()?.contains(blockchain) == true } .sortedBy(Blockchain::fullName) .map(::createNetworkSelectorItem) @@ -231,7 +241,7 @@ internal class AddCustomTokenViewModel @Inject constructor( onValueChange = actionsHandler::onDecimalsValueChange, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Next), label = TextReference.Res(R.string.custom_token_decimals_input_title), - placeholder = TextReference.Str(value = "8"), + placeholder = TextReference.Str(value = DECIMALS_PLACEHOLDER), isEnabled = false, ) } @@ -250,11 +260,31 @@ internal class AddCustomTokenViewModel @Inject constructor( } private fun getDerivationPathsSelectorItems(): List { - val defaultDerivationPath = createDerivationPathSelectorItem(Blockchain.Unknown) - return listOf(defaultDerivationPath) + Blockchain.values() - .filter { blockchain -> blockchain.isEvm() && blockchain.isSupportedInApp() && !blockchain.isTestnet() } + return listOf( + createDerivationPathSelectorAdditionalItem( + blockchain = Blockchain.Unknown, + type = DerivationPathSelectorType.DEFAULT, + ), + createDerivationPathSelectorAdditionalItem( + blockchain = Blockchain.Unknown, + type = DerivationPathSelectorType.CUSTOM, + ), + ) + Blockchain.values() + .filter { blockchain -> blockchain.isSupportedInApp() && !blockchain.isTestnet() } .sortedBy(Blockchain::fullName) - .map(::createDerivationPathSelectorItem) + .map(::createDerivationPathSelectorAdditionalItem) + } + + private fun createDerivationPathInputField(): AddCustomTokenInputField.DerivationPath? { + if (reduxStateHolder.scanResponse?.card?.settings?.isHDWalletAllowed == false) return null + + return AddCustomTokenInputField.DerivationPath( + value = "", + onValueChange = actionsHandler::onDerivationPathValueChange, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + label = TextReference.Res(R.string.custom_token_custom_derivation), + placeholder = TextReference.Str(value = DERIVATION_PATH_PLACEHOLDER), + ) } } @@ -306,25 +336,16 @@ internal class AddCustomTokenViewModel @Inject constructor( Timber.e(it) } - updateDerivationPathSelector() updateWarnings() updateFloatingButton() } } - private fun updateDerivationPathSelector() { - uiState = uiState.copySealed( - form = uiState.form.copy( - derivationPathSelectorField = uiState.form.derivationPathSelectorField?.copy( - isEnabled = uiState.form.networkSelectorField.selectedItem.blockchain.isEvm(), - ), - ), - ) - } - private fun isDerivationPathSelected(): Boolean { return with(uiState.form.derivationPathSelectorField?.selectedItem?.blockchain) { - this != null && this != Blockchain.Unknown + this != null && this != Blockchain.Unknown || + uiState.form.derivationPathSelectorField?.selectedItem?.type == DerivationPathSelectorType.CUSTOM && + !uiState.warnings.contains(AddCustomTokenWarning.WrongDerivationPath) } } @@ -397,6 +418,7 @@ internal class AddCustomTokenViewModel @Inject constructor( } private fun updateFloatingButton() { + uiState = updateStateWithDerivationError(uiState) if (isCustomTokenAlreadyAdded()) { uiState = uiState.copySealed( warnings = uiState.warnings + AddCustomTokenWarning.TokenAlreadyAdded, @@ -405,6 +427,7 @@ internal class AddCustomTokenViewModel @Inject constructor( return } + val isCorrectDerivationInput = !uiState.warnings.contains(AddCustomTokenWarning.WrongDerivationPath) val state = when { isAllTokenFieldsFilled() && isNetworkSelected() -> { val networkSelectorValue = uiState.form.networkSelectorField.selectedItem.blockchain @@ -418,7 +441,8 @@ internal class AddCustomTokenViewModel @Inject constructor( uiState.copySealed( floatingButton = uiState.floatingButton.copy( - isEnabled = error is ContractAddressValidatorResult.Success && isSupportedToken, + isEnabled = error is ContractAddressValidatorResult.Success && + isSupportedToken && isCorrectDerivationInput, ), ) } @@ -430,17 +454,43 @@ internal class AddCustomTokenViewModel @Inject constructor( else -> { uiState.copySealed( floatingButton = uiState.floatingButton.copy( - isEnabled = if (isNetworkSelected()) !isBlockchainAlreadyAdded() else false, + isEnabled = if (isNetworkSelected()) { + !isBlockchainAlreadyAdded() && isCorrectDerivationInput + } else { + false + }, ), ) } } uiState = state.copySealed( - warnings = uiState.warnings - AddCustomTokenWarning.TokenAlreadyAdded, + warnings = state.warnings - AddCustomTokenWarning.TokenAlreadyAdded, ) } + private fun updateStateWithDerivationError(uiState: AddCustomTokenStateHolder): AddCustomTokenStateHolder { + val updatedWarnings = if (isWrongDerivationPathEntered( + derivationPathSelectorType = uiState.form.derivationPathSelectorField?.selectedItem?.type, + derivationPath = getDerivationPath(), + ) + ) { + uiState.warnings + AddCustomTokenWarning.WrongDerivationPath + } else { + uiState.warnings - AddCustomTokenWarning.WrongDerivationPath + } + return uiState.copySealed( + warnings = updatedWarnings, + ) + } + + private fun isWrongDerivationPathEntered( + derivationPathSelectorType: DerivationPathSelectorType?, + derivationPath: DerivationPath?, + ): Boolean { + return derivationPathSelectorType == DerivationPathSelectorType.CUSTOM && derivationPath == null + } + private fun isCustomTokenAlreadyAdded(): Boolean { return when (getCustomTokenType()) { CustomTokenType.TOKEN -> isTokenAlreadyAdded() @@ -520,16 +570,36 @@ internal class AddCustomTokenViewModel @Inject constructor( } private fun getDerivationPath(): DerivationPath? { + return when (uiState.form.derivationPathSelectorField?.selectedItem?.type) { + DerivationPathSelectorType.CUSTOM -> + createDerivationPathOrNull(uiState.form.derivationPathInputField?.value ?: "") + else -> + getDerivationPathForBlockchain(uiState.form.derivationPathSelectorField?.selectedItem?.blockchain) + } + } + + private fun createDerivationPathOrNull(rawPath: String): DerivationPath? { + return try { + DerivationPath(rawPath) + } catch (error: HDWalletError) { + null + } + } + + private fun getDerivationPathForBlockchain(blockchain: Blockchain?): DerivationPath? { + if (blockchain == null) return null + val derivationStyle = if (!isDerivationPathSelected()) { reduxStateHolder.scanResponse?.card?.derivationStyle } else { DerivationStyle.LEGACY } - - return when (val derivationNetwork = uiState.form.derivationPathSelectorField?.selectedItem?.blockchain) { - Blockchain.Unknown -> uiState.form.networkSelectorField.selectedItem.blockchain - else -> derivationNetwork - }?.derivationPath(derivationStyle) + val derivationNetwork = if (blockchain == Blockchain.Unknown) { + uiState.form.networkSelectorField.selectedItem.blockchain + } else { + blockchain + } + return derivationNetwork.derivationPath(derivationStyle) } private inner class ActionsHandler(private val featureRouter: CustomTokenRouter) { @@ -566,7 +636,6 @@ internal class AddCustomTokenViewModel @Inject constructor( is ContractAddressValidatorResult.Error -> { handleContractAddressErrorValidation(type = validatorResult.type) - updateDerivationPathSelector() updateWarnings() updateFloatingButton() } @@ -574,11 +643,13 @@ internal class AddCustomTokenViewModel @Inject constructor( } fun onNetworkSelectorItemClick(index: Int) { + val selectedItem = requireNotNull(uiState.form.networkSelectorField.items.getOrNull(index)) uiState = uiState.copySealed( form = uiState.form.copy( networkSelectorField = uiState.form.networkSelectorField.copy( - selectedItem = requireNotNull(uiState.form.networkSelectorField.items.getOrNull(index)), + selectedItem = selectedItem, ), + showTokenFields = selectedItem.blockchain.canHandleTokens(), ), ) onContactAddressValueChange(uiState.form.contractAddressInputField.value) @@ -612,12 +683,26 @@ internal class AddCustomTokenViewModel @Inject constructor( } fun onDerivationPathSelectorItemClick(index: Int) { - val field = requireNotNull(uiState.form.derivationPathSelectorField) + val derivationSelector = requireNotNull(uiState.form.derivationPathSelectorField) + val selected = requireNotNull(derivationSelector.items.getOrNull(index)) + val derivationInputField = requireNotNull(uiState.form.derivationPathInputField) uiState = uiState.copySealed( form = uiState.form.copy( - derivationPathSelectorField = field.copy( - selectedItem = requireNotNull(field.items.getOrNull(index)), + derivationPathSelectorField = derivationSelector.copy( + selectedItem = selected, ), + derivationPathInputField = derivationInputField.copy( + showField = selected.type == DerivationPathSelectorType.CUSTOM, + ), + ), + ) + updateFloatingButton() + } + + fun onDerivationPathValueChange(enteredValue: String) { + uiState = uiState.copySealed( + form = uiState.form.copy( + derivationPathInputField = uiState.form.derivationPathInputField?.copy(value = enteredValue), ), ) updateFloatingButton() @@ -691,7 +776,11 @@ internal class AddCustomTokenViewModel @Inject constructor( decimalsInputField = decimalsInputField.copy(value = "", isEnabled = false), derivationPathSelectorField = derivationPathSelectorField?.copy( isEnabled = true, - selectedItem = formStateBuilder.createDerivationPathSelectorItem(Blockchain.Unknown), + selectedItem = formStateBuilder + .createDerivationPathSelectorAdditionalItem( + blockchain = Blockchain.Unknown, + type = DerivationPathSelectorType.DEFAULT, + ), ), ), ) @@ -722,5 +811,8 @@ internal class AddCustomTokenViewModel @Inject constructor( TestTokenItem(name = "USDT (invalid - 1/3 of address)", address = "Es9vMFrzaCERmJ"), TestTokenItem(name = "ETH (full)", address = "2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk"), ) + const val DERIVATION_PATH_PLACEHOLDER = "m/44'/0'/0'/0/0" + const val DECIMALS_PLACEHOLDER = "8" + const val CONTRACT_ADDRESS_PLACEHOLDER = "0x0000000000000000000000000000000000000000" } } \ No newline at end of file diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index af94ad33ae..70e4deefde 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -84,9 +84,11 @@ Пожалуйста, выберите сеть Обязательное поле Количество знаков после запятой должно быть корректным числом не больше %d + Своя деривация Знаков после запятой По умолчанию Деривация по BIP44 + Введенный путь деривации некорректен Например, USD Coin Название токена Не выбрано diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 038f2a7fe9..cc6b198c0b 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -82,9 +82,11 @@ Please select the network Required field Decimal number must be a valid integer, no higher than %d + Custom derivation Decimals Default BIP44 coin type + The derivation path you\'ve entered is not valid E.g. USD Coin Name Not selected diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt index aca74ef3ec..5dfdf7c1d3 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt @@ -177,4 +177,5 @@ fun Blockchain.isSupportedInApp(): Boolean { private val excludedBlockchains = listOf( Blockchain.SaltPay, + Blockchain.Unknown, ) \ No newline at end of file