From 15b5d45d3532914ba66bf59ddde21533634d14a8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 May 2022 16:33:42 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/build.gradle | 3 +- domain/build.gradle | 3 +- .../domain/common/extensions/CardSdk.kt | 46 +++++++++++- .../addCustomToken/redux/AddCustomTokenHub.kt | 21 +++--- .../redux/AddCustomTokenState.kt | 73 +++++++------------ 5 files changed, 81 insertions(+), 65 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 550a83ec13..d69b335737 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,7 +93,8 @@ dependencies { implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:develop-77' + implementation 'com.tangem:blockchain:develop-78' +// implementation 'com.tangem:blockchain:0.0.1' implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142' implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142' diff --git a/domain/build.gradle b/domain/build.gradle index b156723a15..8dd3f9a54c 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -60,7 +60,8 @@ dependencies { implementation implementation(project(path: ':common')) // Tangem sdk's - implementation 'com.tangem:blockchain:develop-77' + implementation 'com.tangem:blockchain:develop-78' +// implementation 'com.tangem:blockchain:0.0.1' implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142' implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142' diff --git a/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt b/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt index ca37d132ba..ea805497c6 100644 --- a/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt +++ b/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt @@ -1,12 +1,50 @@ package com.tangem.domain.common.extensions +import com.tangem.blockchain.common.Blockchain +import com.tangem.common.card.Card +import com.tangem.common.card.EllipticCurve import com.tangem.common.card.FirmwareVersion +import com.tangem.domain.common.TapWorkarounds.isTestCard /** [REDACTED_AUTHOR] */ -val FirmwareVersion.Companion.SolanaAvailable - get() = FirmwareVersion(4, 12) - val FirmwareVersion.Companion.SolanaTokensAvailable - get() = FirmwareVersion(4, 52) \ No newline at end of file + get() = FirmwareVersion(4, 52) + +fun Card.supportedBlockchains(): List { + val supportedBlockchains = when { + firmwareVersion < FirmwareVersion.MultiWalletAvailable -> { + Blockchain.fromCurve(EllipticCurve.Secp256k1) + } + else -> { + Blockchain.fromCurve(EllipticCurve.Secp256k1) + + Blockchain.fromCurve(EllipticCurve.Ed25519) + } + } + val filtered = supportedBlockchains.filter { isTestCard == it.isTestnet() } + return filtered +} + +fun Card.supportedTokens(): List { + val tokensSupportedByBlockchain = supportedBlockchains().filter { it.canHandleTokens() }.toMutableList() + val tokensSupportedByCard = when { + firmwareVersion >= FirmwareVersion.SolanaTokensAvailable -> tokensSupportedByBlockchain + else -> { + tokensSupportedByBlockchain.apply { + remove(Blockchain.Solana) + remove(Blockchain.SolanaTestnet) + } + } + } + val filtered = tokensSupportedByCard.filter { isTestCard == it.isTestnet() } + return filtered +} + +fun Card.canHandleBlockchain(blockchain: Blockchain): Boolean { + return this.supportedBlockchains().contains(blockchain) +} + +fun Card.canHandleToken(blockchain: Blockchain): Boolean { + return this.supportedTokens().contains(blockchain) +} \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt index 73db7237db..82aadfae67 100644 --- a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt +++ b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt @@ -13,6 +13,7 @@ import com.tangem.domain.DomainDialog import com.tangem.domain.DomainWrapped import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.fromNetworkId +import com.tangem.domain.common.extensions.supportedTokens import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.common.form.* import com.tangem.domain.features.addCustomToken.* @@ -141,16 +142,11 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT } } - //TODO: Solana token - /** - * This feature is only needed until Solana coins are added. - * While they are not there - this function excludes the Solana blockchain if the user has - * filled in at least one field of the token. - */ private suspend fun changeBlockchainNetworkList() { val state = hubState val networkBlockchainList = Network.getField().itemList - val newNetworkBlockchainList: List = state.getNetworks(state.getCustomTokenType()) + val card = requireNotNull(globalState.scanResponse?.card) + val newNetworkBlockchainList: List = state.getNetworks(card, state.getCustomTokenType()) val listsIdentical = newNetworkBlockchainList.toSet() == networkBlockchainList.toSet() if (listsIdentical) return @@ -537,9 +533,7 @@ private class AddCustomTokenReducer( } is OnCreate -> { val card = requireNotNull(globalState.scanResponse?.card) - val supportedTokenNetworkIds = AddCustomTokenState.getSupportedTokensBlockchain().map { - it.toNetworkId() - } + val supportedTokenNetworkIds = card.supportedTokens().map { it.toNetworkId() } val tangemTechServiceManager = AddCustomTokenService( tangemTechService = globalState.networkServices.tangemTechService, supportedTokenNetworkIds = supportedTokenNetworkIds @@ -550,7 +544,7 @@ private class AddCustomTokenReducer( DerivationStyle.LEGACY -> derivationPathState.copy(isVisible = true) null, DerivationStyle.NEW -> derivationPathState.copy(isVisible = false) } - val form = Form(AddCustomTokenState.createFormFields(CustomTokenType.Blockchain)) + val form = Form(AddCustomTokenState.createFormFields(card, CustomTokenType.Blockchain)) state.copy( cardDerivationStyle = card.derivationStyle, form = form, @@ -558,7 +552,10 @@ private class AddCustomTokenReducer( screenState = state.screenState.copy(derivationPath = derivationPathState) ) } - is OnDestroy -> state.reset() + is OnDestroy -> { + val card = requireNotNull(globalState.scanResponse?.card) + state.reset(card) + } is UpdateForm -> { updateFormState(action.state) } diff --git a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt index 8d9714ce91..2a5f43a3fd 100644 --- a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt +++ b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt @@ -2,17 +2,17 @@ package com.tangem.domain.features.addCustomToken.redux import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationStyle -import com.tangem.common.card.FirmwareVersion +import com.tangem.common.card.Card import com.tangem.common.json.MoshiJsonConverter import com.tangem.domain.AddCustomTokenError import com.tangem.domain.DomainWrapped -import com.tangem.domain.common.extensions.SolanaAvailable -import com.tangem.domain.common.extensions.SolanaTokensAvailable +import com.tangem.domain.common.TapWorkarounds.isTestCard +import com.tangem.domain.common.extensions.supportedBlockchains +import com.tangem.domain.common.extensions.supportedTokens import com.tangem.domain.common.form.* import com.tangem.domain.features.addCustomToken.* import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.* import com.tangem.domain.redux.DomainState -import com.tangem.domain.redux.domainStore import com.tangem.domain.redux.state.StringActionStateConverter import org.rekotlin.Action import org.rekotlin.StateType @@ -109,12 +109,12 @@ data class AddCustomTokenState( null } - fun reset(): AddCustomTokenState { + fun reset(card: Card): AddCustomTokenState { return this.copy( appSavedCurrencies = null, onTokenAddCallback = null, cardDerivationStyle = null, - form = Form(createFormFields(CustomTokenType.Blockchain)), + form = Form(createFormFields(card, CustomTokenType.Blockchain)), formErrors = emptyMap(), tokenId = null, warnings = emptySet(), @@ -135,8 +135,8 @@ data class AddCustomTokenState( .getConvertedData() } - fun getNetworks(type: CustomTokenType): List { - return getNetworksList(type) + fun getNetworks(card: Card, type: CustomTokenType): List { + return getNetworksList(card, type) } companion object { @@ -154,66 +154,45 @@ data class AddCustomTokenState( else -> derivationNetwork }.derivationPath(derivationStyle) - internal fun createFormFields(type: CustomTokenType): List> { + internal fun createFormFields(card: Card, type: CustomTokenType): List> { return listOf( TokenField(ContractAddress), - TokenBlockchainField(Network, getNetworksList(type)), + TokenBlockchainField(Network, getNetworksList(card, type)), TokenField(Name), TokenField(Symbol), TokenField(Decimals), - TokenDerivationPathField(DerivationPath, getSupportedDerivations()), + TokenDerivationPathField(DerivationPath, getSupportedDerivations(card)), ) } - /** - * Serves to determine the tokens that can be received from the TangemTech service - */ - internal fun getSupportedTokensBlockchain(): List { - return Blockchain.values() - .filter { !it.isTestnet() } - .filter { it.canHandleTokens() } - } - /** * Serves to determine the networks (blockchains & tokens) that can be selected by Form.Networks. * Blockchain.Unknown - is the default selection */ - private fun getNetworksList(type: CustomTokenType): List { + private fun getNetworksList(card: Card, type: CustomTokenType): List { val evmBlockchains = Blockchain.values() .filter { it.isEvm() } - .filter { !it.isTestnet() } + .filter { card.isTestCard == it.isTestnet() } val additionalBlockchains = listOf( - Blockchain.Binance, - Blockchain.Solana, + Blockchain.Binance, Blockchain.BinanceTestnet, + Blockchain.Solana, Blockchain.SolanaTestnet, ) - val networks = (evmBlockchains + additionalBlockchains).toMutableList() - - //life hack - val fwCardVersion = domainStore.state.globalState.scanResponse?.card?.firmwareVersion - ?: FirmwareVersion(0, 0) - - val solanaUnsupportedByCard = fwCardVersion < FirmwareVersion.SolanaAvailable - val solanaTokensUnsupportedByCard = fwCardVersion < FirmwareVersion.SolanaTokensAvailable - if (solanaUnsupportedByCard || solanaTokensUnsupportedByCard) networks.remove(Blockchain.Solana) - - if (type == CustomTokenType.Token) networks.removeAll(getUnsupportedTokensBlockchain()) + val supportedByCard = when (type) { + CustomTokenType.Blockchain -> card.supportedBlockchains() + CustomTokenType.Token -> card.supportedTokens() + } + val typedNetworksList = (evmBlockchains + additionalBlockchains) + .filter { supportedByCard.contains(it) } + .toMutableList() val default = Blockchain.Unknown - networks.add(0, default) + typedNetworksList.add(0, default) - return networks + return typedNetworksList } - private fun getUnsupportedTokensBlockchain(): List { - return Blockchain.values() - .filter { !it.isTestnet() } - .filter { !it.canHandleTokens() } - .toMutableList() - } - - private fun createFormValidators(): Map> { return mapOf( ContractAddress to TokenContractAddressValidator(), @@ -224,9 +203,9 @@ data class AddCustomTokenState( ) } - private fun getSupportedDerivations(): List { + private fun getSupportedDerivations(card: Card): List { val evmBlockchains = Blockchain.values().filter { - !it.isTestnet() && it.getChainId() != null + card.isTestCard == it.isTestnet() && it.getChainId() != null } return listOf(Blockchain.Unknown) + evmBlockchains }