From a67518573f3417d0db308df12c5113131edd47ce Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 15 Aug 2023 17:08:46 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../impl/data/DefaultCustomTokenRepository.kt | 6 ++-- .../viewmodels/AddCustomTokenViewModel.kt | 19 +++++++++--- .../impl/data/TangemApiTokensPagingSource.kt | 4 ++- .../viewmodels/TokensListViewModel.kt | 9 +++++- .../domain/common/TangemCardTypesResolver.kt | 3 +- .../tangem/domain/common/TapWorkarounds.kt | 3 -- .../domain/common/extensions/CardSdk.kt | 16 +++++----- .../addCustomToken/redux/AddCustomTokenHub.kt | 29 ++++++++++++++----- .../redux/AddCustomTokenState.kt | 23 ++++++++++----- 9 files changed, 78 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt index 119872604d..b949793a7d 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt @@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.tap.features.customtoken.impl.data.converters.FoundTokenConverter import com.tangem.tap.features.customtoken.impl.domain.CustomTokenRepository import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken @@ -27,8 +28,9 @@ class DefaultCustomTokenRepository( ) : CustomTokenRepository { override suspend fun findToken(address: String, networkId: String?): FoundToken { - val supportedTokenNetworkIds = requireNotNull(reduxStateHolder.scanResponse?.card) - .supportedBlockchains() + val scanResponse = requireNotNull(reduxStateHolder.scanResponse) + val supportedTokenNetworkIds = requireNotNull(scanResponse.card) + .supportedBlockchains(scanResponse.cardTypesResolver) .filter(Blockchain::canHandleTokens) .map(Blockchain::toNetworkId) 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 4aee8f0645..3b5e96c9e9 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 @@ -18,6 +18,7 @@ import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.HDWalletError import com.tangem.domain.AddCustomTokenError import com.tangem.domain.common.extensions.* +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.features.addCustomToken.CustomCurrency import com.tangem.tap.domain.model.WalletDataModel @@ -206,9 +207,11 @@ internal class AddCustomTokenViewModel @Inject constructor( private fun getNetworkSelectorItems(): List { val defaultNetwork = createNetworkSelectorItem(blockchain = Blockchain.Unknown) + val scanResponse = reduxStateHolder.scanResponse return listOf(defaultNetwork) + Blockchain.values() .filter { blockchain -> - reduxStateHolder.scanResponse?.card?.supportedBlockchains()?.contains(blockchain) == true + scanResponse?.card?.supportedBlockchains(scanResponse.cardTypesResolver) + ?.contains(blockchain) == true } .sortedBy(Blockchain::fullName) .map(::createNetworkSelectorItem) @@ -404,7 +407,11 @@ internal class AddCustomTokenViewModel @Inject constructor( val isSupportedToken = if (!isNetworkSelected()) { true } else { - reduxStateHolder.scanResponse?.card?.canHandleToken(networkSelectorValue) ?: false + val scanResponse = reduxStateHolder.scanResponse + scanResponse?.card?.canHandleToken( + blockchain = networkSelectorValue, + cardTypesResolver = scanResponse.cardTypesResolver, + ) ?: false } return buildSet { @@ -438,8 +445,12 @@ internal class AddCustomTokenViewModel @Inject constructor( address = uiState.form.contractAddressInputField.value, blockchain = networkSelectorValue, ) - val isSupportedToken = reduxStateHolder.scanResponse?.card - ?.canHandleToken(networkSelectorValue) + val scanResponse = reduxStateHolder.scanResponse + val isSupportedToken = scanResponse?.card + ?.canHandleToken( + blockchain = networkSelectorValue, + cardTypesResolver = scanResponse.cardTypesResolver, + ) ?: false uiState.copySealed( diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt index 2cae031963..fb04538ee2 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.tap.features.tokens.impl.data.converters.CoinsResponseConverter import com.tangem.tap.features.tokens.impl.domain.models.Token import com.tangem.tap.proxy.AppStateHolder @@ -38,7 +39,8 @@ internal class TangemApiTokensPagingSource( val page = params.key ?: 0 return runCatching(dispatchers.io) { - val supportedBlockchains = reduxStateHolder.scanResponse?.card?.supportedBlockchains() + val scanResponse = reduxStateHolder.scanResponse + val supportedBlockchains = scanResponse?.card?.supportedBlockchains(scanResponse.cardTypesResolver) ?: Blockchain.values().toList() api.getCoins( diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt index a44d631c1c..acc0ef2830 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt @@ -16,6 +16,7 @@ import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation import com.tangem.domain.common.extensions.canHandleToken import com.tangem.domain.common.extensions.fromNetworkId +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.tap.common.extensions.fullNameWithoutTestnet import com.tangem.tap.common.extensions.getGreyedOutIconRes import com.tangem.tap.common.extensions.getNetworkName @@ -349,8 +350,14 @@ internal class TokensListViewModel @Inject constructor( toggledNetwork.changeToggleState() } } else { + val scanResponse = reduxStateHolder.scanResponse val isUnsupportedToken = - !(reduxStateHolder.scanResponse?.card?.canHandleToken(token.blockchain) ?: false) + !( + scanResponse?.card?.canHandleToken( + blockchain = token.blockchain, + cardTypesResolver = scanResponse.cardTypesResolver, + ) ?: false + ) if (isUnsupportedToken) { router.openUnsupportedSoltanaNetworkAlert() diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt index f35b18309f..c3053f87b6 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt @@ -8,7 +8,6 @@ import com.tangem.common.card.WalletData import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.TapWorkarounds.isTestCard -import com.tangem.domain.common.TapWorkarounds.isWallet2 import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ProductType import com.tangem.operations.attestation.Attestation @@ -31,7 +30,7 @@ internal class TangemCardTypesResolver( } override fun isWallet2(): Boolean { - return card.isWallet2 + return card.firmwareVersion >= FirmwareVersion.Ed25519Slip0010Available && card.settings.isKeysImportAllowed } override fun isTangemTwins(): Boolean = productType == ProductType.Twins diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/TapWorkarounds.kt b/domain/legacy/src/main/java/com/tangem/domain/common/TapWorkarounds.kt index cf4a3cc6e5..bd892377ae 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/TapWorkarounds.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/TapWorkarounds.kt @@ -28,9 +28,6 @@ object TapWorkarounds { val CardDTO.canSkipBackup: Boolean get() = this.firmwareVersion < backupRequiredFirmwareVersion - val CardDTO.isWallet2: Boolean - get() = this.firmwareVersion >= FirmwareVersion.Ed25519Slip0010Available && this.settings.isKeysImportAllowed - val CardDTO.useOldStyleDerivation: Boolean get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95" diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt index 9fc609a7b2..1efeec3cf8 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt @@ -3,8 +3,8 @@ package com.tangem.domain.common.extensions import com.tangem.blockchain.common.Blockchain import com.tangem.common.card.EllipticCurve import com.tangem.common.card.FirmwareVersion +import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.common.TapWorkarounds.isTestCard -import com.tangem.domain.common.TapWorkarounds.isWallet2 import com.tangem.domain.models.scan.CardDTO /** @@ -13,7 +13,7 @@ import com.tangem.domain.models.scan.CardDTO val FirmwareVersion.Companion.SolanaTokensAvailable get() = FirmwareVersion(4, 52) -fun CardDTO.supportedBlockchains(): List { +fun CardDTO.supportedBlockchains(cardTypesResolver: CardTypesResolver): List { val supportedBlockchains = if (firmwareVersion < FirmwareVersion.MultiWalletAvailable) { Blockchain.fromCurve(EllipticCurve.Secp256k1) } else { @@ -21,7 +21,7 @@ fun CardDTO.supportedBlockchains(): List { }.toMutableList() // disabled Cardano for wallet 2 for now, should be enabled after key processed // ([REDACTED_JIRA]) - if (this.isWallet2) { + if (cardTypesResolver.isWallet2()) { supportedBlockchains.apply { remove(Blockchain.Cardano) } @@ -31,8 +31,10 @@ fun CardDTO.supportedBlockchains(): List { .filter { it.isSupportedInApp() } } -fun CardDTO.supportedTokens(): List { - val tokensSupportedByBlockchain = supportedBlockchains().filter { it.canHandleTokens() }.toMutableList() +fun CardDTO.supportedTokens(cardTypesResolver: CardTypesResolver): List { + val tokensSupportedByBlockchain = supportedBlockchains(cardTypesResolver) + .filter { it.canHandleTokens() } + .toMutableList() val tokensSupportedByCard = when { firmwareVersion >= FirmwareVersion.SolanaTokensAvailable -> tokensSupportedByBlockchain else -> { @@ -46,6 +48,6 @@ fun CardDTO.supportedTokens(): List { return tokensSupportedByCard.filter { isTestCard == it.isTestnet() } } -fun CardDTO.canHandleToken(blockchain: Blockchain): Boolean { - return this.supportedTokens().contains(blockchain) +fun CardDTO.canHandleToken(blockchain: Blockchain, cardTypesResolver: CardTypesResolver): Boolean { + return this.supportedTokens(cardTypesResolver).contains(blockchain) } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt index 3db713c231..aa12f86b00 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt @@ -13,6 +13,7 @@ import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.common.form.* +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.features.addCustomToken.* import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.* @@ -435,7 +436,13 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT private fun tokenIsSupported(blockchain: Blockchain): Boolean = when (blockchain) { Blockchain.Unknown -> true - else -> globalState.scanResponse?.card?.canHandleToken(blockchain) ?: false + else -> { + val scanResponse = globalState.scanResponse + scanResponse?.card?.canHandleToken( + blockchain = blockchain, + cardTypesResolver = scanResponse.cardTypesResolver, + ) ?: false + } } @Throws @@ -547,8 +554,9 @@ private class AddCustomTokenReducer( state.copy(onTokenAddCallback = action.callback) } is OnCreate -> { - val card = requireNotNull(globalState.scanResponse?.card) - val supportedTokenNetworkIds = card.supportedBlockchains() + val scanResponse = requireNotNull(globalState.scanResponse) + val card = globalState.scanResponse.card + val supportedTokenNetworkIds = card.supportedBlockchains(scanResponse.cardTypesResolver) .filter(Blockchain::canHandleTokens) .map(Blockchain::toNetworkId) @@ -559,15 +567,22 @@ private class AddCustomTokenReducer( ) state.copy( - cardDerivationStyle = globalState.scanResponse?.derivationStyleProvider?.getDerivationStyle(), - form = Form(AddCustomTokenState.createFormFields(card, CustomTokenType.Blockchain)), + cardDerivationStyle = globalState.scanResponse.derivationStyleProvider.getDerivationStyle(), + form = Form( + AddCustomTokenState.createFormFields( + cardTypesResolver = globalState.scanResponse.cardTypesResolver, + card = card, + type = CustomTokenType.Blockchain, + ), + ), tangemTechServiceManager = tangemTechServiceManager, screenState = createInitialScreenState(card.settings.isHDWalletAllowed), ) } is OnDestroy -> { - val card = requireNotNull(globalState.scanResponse?.card) - state.reset(card) + val scanResponse = requireNotNull(globalState.scanResponse) + val card = scanResponse.card + state.reset(scanResponse.cardTypesResolver, card) } is UpdateForm -> { updateFormState(action.state) diff --git a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt index f68eeb7b87..aaa7693875 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt @@ -6,6 +6,7 @@ import com.tangem.common.json.MoshiJsonConverter import com.tangem.datasource.api.tangemTech.models.CoinsResponse import com.tangem.domain.AddCustomTokenError import com.tangem.domain.DomainWrapped +import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.isSupportedInApp @@ -113,12 +114,12 @@ data class AddCustomTokenState( null } - fun reset(card: CardDTO): AddCustomTokenState { + fun reset(cardTypesResolver: CardTypesResolver, card: CardDTO): AddCustomTokenState { return this.copy( appSavedCurrencies = null, onTokenAddCallback = null, cardDerivationStyle = null, - form = Form(createFormFields(card, CustomTokenType.Blockchain)), + form = Form(createFormFields(cardTypesResolver, card, CustomTokenType.Blockchain)), formErrors = emptyMap(), foundToken = null, warnings = emptySet(), @@ -165,10 +166,14 @@ data class AddCustomTokenState( }.derivationPath(derivationStyleToUse) } - internal fun createFormFields(card: CardDTO, type: CustomTokenType): List> { + internal fun createFormFields( + cardTypesResolver: CardTypesResolver, + card: CardDTO, + type: CustomTokenType, + ): List> { return listOf( TokenField(ContractAddress), - TokenBlockchainField(Network, getNetworksList(card, type)), + TokenBlockchainField(Network, getNetworksList(cardTypesResolver, card, type)), TokenField(Name), TokenField(Symbol), TokenField(Decimals), @@ -180,7 +185,11 @@ data class AddCustomTokenState( * Serves to determine the networks (blockchains & tokens) that can be selected by Form.Networks. * Blockchain.Unknown - is the default selection */ - private fun getNetworksList(card: CardDTO, type: CustomTokenType): List { + private fun getNetworksList( + cardTypesResolver: CardTypesResolver, + card: CardDTO, + type: CustomTokenType, + ): List { val evmBlockchains = Blockchain.values() .filter { it.isEvm() } .filter { card.isTestCard == it.isTestnet() } @@ -195,8 +204,8 @@ data class AddCustomTokenState( ) val supportedByCard = when (type) { - CustomTokenType.Blockchain -> card.supportedBlockchains() - CustomTokenType.Token -> card.supportedTokens() + CustomTokenType.Blockchain -> card.supportedBlockchains(cardTypesResolver) + CustomTokenType.Token -> card.supportedTokens(cardTypesResolver) } val typedNetworksList = (evmBlockchains + additionalBlockchains) .filter { supportedByCard.contains(it) }