diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt index 35325434de..0c0c30de42 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -16,6 +16,7 @@ import com.tangem.crypto.bip39.DefaultMnemonic import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.operations.ScanTask @@ -80,7 +81,10 @@ class TangemSdkManager(private val cardSdkConfigRepository: CardSdkConfigReposit suspend fun createProductWallet(scanResponse: ScanResponse): CompletionResult { return runTaskAsync( - CreateProductWalletTask(scanResponse.cardTypesResolver), + CreateProductWalletTask( + cardTypesResolver = scanResponse.cardTypesResolver, + derivationStyleProvider = scanResponse.derivationStyleProvider, + ), scanResponse.card.cardId, Message(resources.getString(R.string.initial_message_create_wallet_body)), ) @@ -92,7 +96,10 @@ class TangemSdkManager(private val cardSdkConfigRepository: CardSdkConfigReposit ): CompletionResult { return when (val seedResult = DefaultMnemonic(mnemonic, tangemSdk.wordlist).generateSeed()) { is CompletionResult.Success -> runTaskAsync( - CreateProductWalletTask(scanResponse.cardTypesResolver, seedResult.data), + CreateProductWalletTask( + cardTypesResolver = scanResponse.cardTypesResolver, + derivationStyleProvider = scanResponse.derivationStyleProvider, + ), scanResponse.card.cardId, Message(resources.getString(R.string.initial_message_create_wallet_body)), ) diff --git a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt b/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt index 81532e5bb9..7bd2f77fe1 100644 --- a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt +++ b/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt @@ -1,11 +1,15 @@ package com.tangem.tap.domain.model.builders import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider -import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.WalletManager +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.common.BlockchainNetwork -import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.wallets.models.UserWallet import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.domain.model.WalletStoreModel @@ -47,7 +51,7 @@ private class BlockchainNetworkWalletStoreBuilderImpl( } override fun build(): WalletStoreModel { - val cardDerivationStyle = userWallet.scanResponse.card.derivationStyle + val cardDerivationStyle = userWallet.scanResponse.derivationStyleProvider.getDerivationStyle() val blockchainWalletData = blockchainNetwork.getBlockchainWalletData(walletManager, cardDerivationStyle) val tokensWalletsData = blockchainNetwork.getTokensWalletsData( walletManager = walletManager, diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt index d23e9fde5c..ede3d71091 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt @@ -13,8 +13,9 @@ import com.tangem.common.extensions.toMapKey import com.tangem.common.map import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.common.CardTypesResolver -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.DerivationStyleProvider import com.tangem.domain.common.TapWorkarounds.isTestCard +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.KeyWalletPublicKey import com.tangem.operations.CommandResponse @@ -56,6 +57,7 @@ private data class CreateWalletResponse( class CreateProductWalletTask( private val cardTypesResolver: CardTypesResolver, + private val derivationStyleProvider: DerivationStyleProvider, private val seed: ByteArray? = null, ) : CardSessionRunnable { @@ -76,7 +78,7 @@ class CreateProductWalletTask( cardTypesResolver.isTangemTwins() -> throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet") - else -> CreateWalletTangemWallet(seed) + else -> CreateWalletTangemWallet(seed, derivationStyleProvider) } commandProcessor.proceed(cardDto, session) { when (it) { @@ -133,6 +135,7 @@ private class CreateWalletTangemNote(private val cardTypesResolver: CardTypesRes private class CreateWalletTangemWallet( private val seed: ByteArray?, + private val derivationStyleProvider: DerivationStyleProvider, ) : ProductCommandProcessor { private var primaryCard: PrimaryCard? = null @@ -242,9 +245,9 @@ private class CreateWalletTangemWallet( val blockchainsForCurve = getBlockchains(response.cardId, card).filter { it.getSupportedCurves().contains(response.wallet.curve) } - val derivationPaths = blockchainsForCurve.mapNotNull { + val derivationPaths = blockchainsForCurve.mapNotNull { blockchain -> isBlockchainsForCurvesExist = true - it.derivationPath(card.derivationStyle) + blockchain.derivationPath(derivationStyleProvider.getDerivationStyle()) } if (derivationPaths.isNotEmpty()) { map[response.wallet.publicKey.toMapKey()] = derivationPaths diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 6774c4e61d..6a184f7f8e 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -14,6 +14,7 @@ import com.tangem.common.tlv.TlvDecoder import com.tangem.crypto.CryptoUtils import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.common.BlockchainNetwork +import com.tangem.domain.common.DerivationStyleProvider import com.tangem.domain.common.TapWorkarounds.isExcluded import com.tangem.domain.common.TapWorkarounds.isNotSupportedInThatRelease import com.tangem.domain.common.TapWorkarounds.isStart2Coin @@ -21,6 +22,7 @@ import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation import com.tangem.domain.common.TwinsHelper import com.tangem.domain.common.extensions.getPrimaryCurve +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ProductType import com.tangem.domain.models.scan.ScanResponse @@ -208,31 +210,22 @@ private class ScanWalletProcessor( ) { val productType = ProductType.Wallet scope.launch { - val derivations = collectDerivations(card) + val scanResponse = ScanResponse( + card = card, + productType = productType, + walletData = session.environment.walletData, + primaryCard = primaryCard, + ) + val derivations = collectDerivations(card, scanResponse.derivationStyleProvider) if (derivations.isEmpty() || !card.settings.isHDWalletAllowed) { - callback( - CompletionResult.Success( - ScanResponse( - card = card, - productType = productType, - walletData = session.environment.walletData, - primaryCard = primaryCard, - ), - ), - ) + callback(CompletionResult.Success(scanResponse)) return@launch } DeriveMultipleWalletPublicKeysTask(derivations).run(session) { result -> when (result) { is CompletionResult.Success -> { - val response = ScanResponse( - card = card, - productType = productType, - walletData = session.environment.walletData, - derivedKeys = result.data.entries, - primaryCard = primaryCard, - ) + val response = scanResponse.copy(derivedKeys = result.data.entries) callback(CompletionResult.Success(response)) } is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) @@ -241,7 +234,10 @@ private class ScanWalletProcessor( } } - private suspend fun getBlockchainsToDerive(card: CardDTO): List { + private suspend fun getBlockchainsToDerive( + card: CardDTO, + derivationStyleProvider: DerivationStyleProvider, + ): List { val userTokensRepository = userTokensRepository ?: return emptyList() val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card) .toMutableList() @@ -249,11 +245,11 @@ private class ScanWalletProcessor( mutableListOf( BlockchainNetwork( blockchain = Blockchain.Bitcoin, - card = card, + derivationStyleProvider = derivationStyleProvider, ), BlockchainNetwork( blockchain = Blockchain.Ethereum, - card = card, + derivationStyleProvider = derivationStyleProvider, ), ) } @@ -263,11 +259,11 @@ private class ScanWalletProcessor( listOf( BlockchainNetwork( blockchain = Blockchain.Ethereum, - card = card, + derivationStyleProvider = derivationStyleProvider, ), BlockchainNetwork( blockchain = Blockchain.EthereumTestnet, - card = card, + derivationStyleProvider = derivationStyleProvider, ), ), ) @@ -277,7 +273,7 @@ private class ScanWalletProcessor( additionalBlockchainsToDerive.map { BlockchainNetwork( blockchain = it, - card = card, + derivationStyleProvider = derivationStyleProvider, ) }, ) @@ -293,7 +289,7 @@ private class ScanWalletProcessor( ).map { BlockchainNetwork( blockchain = it, - card = card, + derivationStyleProvider = derivationStyleProvider, ) }, ) @@ -301,8 +297,11 @@ private class ScanWalletProcessor( return blockchainsToDerive.distinct() } - private suspend fun collectDerivations(card: CardDTO): Map> { - val blockchains = getBlockchainsToDerive(card) + private suspend fun collectDerivations( + card: CardDTO, + derivationStyleProvider: DerivationStyleProvider, + ): Map> { + val blockchains = getBlockchainsToDerive(card, derivationStyleProvider) val derivations = mutableMapOf>() blockchains.forEach { blockchain -> diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt index 07e8b8ccf6..96408e1315 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt @@ -1,9 +1,11 @@ package com.tangem.tap.domain.walletCurrencies.implementation -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.* import com.tangem.domain.common.BlockchainNetwork -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.DerivationStyleProvider +import com.tangem.domain.common.extensions.derivationPath +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.wallets.legacy.WalletManagersRepository import com.tangem.domain.wallets.models.UserWallet @@ -61,7 +63,9 @@ internal class DefaultWalletCurrenciesManager( } val card = userWallet.scanResponse.card - val currenciesToAddWithMissingBlockchains = currenciesToAdd.addMissingBlockchainsIfNeeded(card) + val currenciesToAddWithMissingBlockchains = currenciesToAdd.addMissingBlockchainsIfNeeded( + userWallet.scanResponse.derivationStyleProvider, + ) listeners.forEach { it.willCurrenciesAdd(userWallet, currenciesToAddWithMissingBlockchains) } updateWalletStores( @@ -167,13 +171,15 @@ internal class DefaultWalletCurrenciesManager( return networks } - private fun List.addMissingBlockchainsIfNeeded(card: CardDTO): List { + private fun List.addMissingBlockchainsIfNeeded( + derivationStyleProvider: DerivationStyleProvider, + ): List { if (this.isEmpty()) return this val currencies = this.asSequence() return currencies .groupBy { currency -> - findBlockchainCurrency(currency, currencies, card.derivationStyle) + findBlockchainCurrency(currency, currencies, derivationStyleProvider.getDerivationStyle()) } .mapValues { (blockchainCurrency, blockchainCurrencies) -> findBlockchainTokens(blockchainCurrency, blockchainCurrencies) diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt index a92ac13e11..40cf0892b5 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt @@ -7,8 +7,9 @@ import com.tangem.common.extensions.guard import com.tangem.common.extensions.toMapKey import com.tangem.common.flatMap import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.common.util.hasDerivation import com.tangem.domain.features.addCustomToken.CustomCurrency import com.tangem.domain.models.scan.ScanResponse @@ -114,7 +115,7 @@ class DefaultCustomTokenInteractor( val manageTokensCandidates = currencyList.map { it.blockchain }.distinct().filter { it.getSupportedCurves().contains(curve) }.mapNotNull { - it.derivationPath(scanResponse.card.derivationStyle) + it.derivationPath(scanResponse.derivationStyleProvider.getDerivationStyle()) } val customTokensCandidates = currencyList.filter { 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 297bf37f54..406963b699 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 @@ -11,14 +11,14 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.derivation.DerivationStyle 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.* +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.features.addCustomToken.CustomCurrency import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.customtoken.impl.domain.CustomTokenInteractor @@ -599,7 +599,7 @@ internal class AddCustomTokenViewModel @Inject constructor( if (blockchain == null) return null val derivationStyle = if (!isDerivationPathSelected()) { - reduxStateHolder.scanResponse?.card?.derivationStyle + reduxStateHolder.scanResponse?.derivationStyleProvider?.getDerivationStyle() } else { DerivationStyle.LEGACY } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt index c2276c9065..42a34e145d 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -1,18 +1,19 @@ package com.tangem.tap.features.details.redux.walletconnect import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.WalletManager +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.extensions.guard import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction import com.tangem.domain.common.BlockchainNetwork -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.DerivationStyleProvider +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.models.scan.CardDTO +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState @@ -357,9 +358,13 @@ class WalletConnectMiddleware { handleScanResponse(scanResponse = scanResponse, session = session, blockchain = blockchain) } - private fun getAvailableBlockchains(card: CardDTO, walletState: WalletState): List { + private fun getAvailableBlockchains( + derivationStyleProvider: DerivationStyleProvider, + walletState: WalletState, + ): List { return walletState.currencies.filter { - it.isBlockchain() && !it.isCustomCurrency(card.derivationStyle) && it.blockchain.isEvm() + it.isBlockchain() && + !it.isCustomCurrency(derivationStyleProvider.getDerivationStyle()) && it.blockchain.isEvm() }.map { it.blockchain } } @@ -390,7 +395,7 @@ class WalletConnectMiddleware { walletPublicKey = wallet.publicKey.seedKey, derivedPublicKey = derivedKey, derivationPath = wallet.publicKey.derivationPath, - derivationStyle = scanResponse.card.derivationStyle, + derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle(), blockchain = wallet.blockchain, ) @@ -403,7 +408,6 @@ class WalletConnectMiddleware { } private fun handleScanResponse(scanResponse: ScanResponse, session: WalletConnectSession, blockchain: Blockchain) { - val card = scanResponse.card if (!scanResponse.cardTypesResolver.isMultiwalletAllowed()) { store.dispatchOnMain(WalletConnectAction.UnsupportedCard) return @@ -415,7 +419,11 @@ class WalletConnectMiddleware { NewWcSessionData(session = updatedSession, scanResponse = scanResponse, blockchain = blockchain), ), ) - val blockchains = if (blockchain.isEvm()) getAvailableBlockchains(card, walletState) else emptyList() + val blockchains = if (blockchain.isEvm()) { + getAvailableBlockchains(scanResponse.derivationStyleProvider, walletState) + } else { + emptyList() + } store.dispatch( GlobalAction.ShowDialog( WalletConnectDialog.ApproveWcSession(session = updatedSession, networks = blockchains), @@ -433,8 +441,9 @@ class WalletConnectMiddleware { } else { blockchain } - val derivation = blockchainToMake.derivationPath(store.state.globalState.scanResponse?.card?.derivationStyle) - ?.rawPath + val derivation = blockchainToMake.derivationPath( + style = store.state.globalState.scanResponse?.derivationStyleProvider?.getDerivationStyle(), + )?.rawPath val blockchainNetwork = BlockchainNetwork( blockchain = blockchainToMake, derivationPath = derivation, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt index 135f597dc1..0446b1ca82 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt @@ -2,9 +2,9 @@ package com.tangem.tap.features.details.redux.walletconnect import com.squareup.moshi.JsonClass import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.WalletManager +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.common.redux.StateDialog diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt index 00a9d94af5..9a76813cab 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt @@ -6,6 +6,7 @@ import com.tangem.core.analytics.Analytics import com.tangem.domain.common.BlockchainNetwork import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.tap.* import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.postUi @@ -92,7 +93,7 @@ private fun handleOtherCardsAction(action: Action) { val blockchainNetwork = BlockchainNetwork( blockchain = primaryBlockchain, - card = updatedCard, + derivationStyleProvider = updatedResponse.derivationStyleProvider, ) .updateTokens( listOfNotNull(primaryToken), @@ -102,11 +103,11 @@ private fun handleOtherCardsAction(action: Action) { listOf( BlockchainNetwork( blockchain = Blockchain.Bitcoin, - card = updatedCard, + derivationStyleProvider = updatedResponse.derivationStyleProvider, ), BlockchainNetwork( blockchain = Blockchain.Ethereum, - card = updatedCard, + derivationStyleProvider = updatedResponse.derivationStyleProvider, ), ) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index 2ce6725c37..d1a927c252 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -12,6 +12,7 @@ import com.tangem.domain.common.BlockchainNetwork import com.tangem.domain.common.TapWorkarounds.canSkipBackup import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.userwallets.Artwork @@ -125,7 +126,10 @@ private fun handleWalletAction(action: Action) { } else { listOf(Blockchain.Bitcoin, Blockchain.Ethereum) }.map { blockchain -> - BlockchainNetwork(blockchain, result.data.card) + BlockchainNetwork( + blockchain = blockchain, + derivationStyleProvider = updatedResponse.derivationStyleProvider, + ) } scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt index c7743263f4..940470bc09 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt @@ -2,18 +2,19 @@ package com.tangem.tap.features.tokens.impl.domain import androidx.paging.PagingData import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.CompletionResult import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.guard import com.tangem.common.extensions.toMapKey import com.tangem.common.flatMap import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.extensions.derivationPath +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.common.util.supportsHdWallet import com.tangem.domain.models.scan.ScanResponse import com.tangem.operations.derivation.ExtendedPublicKeysMap -import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE +import com.tangem.tap.* import com.tangem.tap.common.extensions.dispatchDebugErrorNotification import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.global.GlobalAction @@ -24,10 +25,6 @@ import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain import com.tangem.tap.features.tokens.legacy.redux.TokensMiddleware import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.proxy.AppStateHolder -import com.tangem.tap.store -import com.tangem.tap.tangemSdkManager -import com.tangem.tap.userWalletsListManager -import com.tangem.tap.walletCurrenciesManager import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import timber.log.Timber @@ -51,11 +48,12 @@ internal class DefaultTokensListInteractor( override suspend fun saveChanges(tokens: List, blockchains: List) { val scanResponse = requireNotNull(reduxStateHolder.scanResponse) + val derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle() val currentTokens = store.state.tokensState.addedWallets - .toNonCustomTokensWithBlockchains(style = scanResponse.card.derivationStyle) + .toNonCustomTokensWithBlockchains(derivationStyle = derivationStyle) val currentBlockchains = store.state.tokensState.addedWallets - .toNonCustomBlockchains(derivationStyle = scanResponse.card.derivationStyle) + .toNonCustomBlockchains(derivationStyle = derivationStyle) val blockchainsToAdd = blockchains.filterNot(currentBlockchains::contains) val blockchainsToRemove = currentBlockchains.filterNot(blockchains::contains) @@ -73,18 +71,18 @@ internal class DefaultTokensListInteractor( remove( tokens = tokensToRemove, blockchains = blockchainsToRemove, - derivationStyle = scanResponse.card.derivationStyle, + derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle(), ) add(tokens = tokensToAdd, blockchains = blockchainsToAdd, scanResponse = scanResponse) } private fun List.toNonCustomTokensWithBlockchains( - style: DerivationStyle?, + derivationStyle: DerivationStyle?, ): List { return this.map(WalletDataModel::currency) .mapNotNull { currency -> - if (currency !is Currency.Token || currency.isCustomCurrency(style)) return@mapNotNull null + if (currency !is Currency.Token || currency.isCustomCurrency(derivationStyle)) return@mapNotNull null TokenWithBlockchain(token = currency.token, blockchain = currency.blockchain) } .distinct() @@ -123,7 +121,7 @@ internal class DefaultTokensListInteractor( val currenciesToAdd = convertToCurrencies( tokens = tokens, blockchains = blockchains, - derivationStyle = scanResponse.card.derivationStyle, + derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle(), ) // TODO("[REDACTED_TASK_KEY] use DerivationManager") @@ -184,7 +182,7 @@ internal class DefaultTokensListInteractor( .map(Currency::blockchain) .distinct() .filter { it.getSupportedCurves().contains(curve) } - .mapNotNull { it.derivationPath(scanResponse.card.derivationStyle) } + .mapNotNull { it.derivationPath(scanResponse.derivationStyleProvider.getDerivationStyle()) } val customTokensCandidates = currencyList .filter { it.blockchain.getSupportedCurves().contains(curve) } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt index 21f763e48a..c24f982fca 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt @@ -1,7 +1,7 @@ package com.tangem.tap.features.tokens.legacy.redux import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.tap.domain.model.WalletDataModel import org.rekotlin.Action diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt index c62a8053d9..dca9ea4875 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt @@ -1,7 +1,7 @@ package com.tangem.tap.features.tokens.legacy.redux import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.CompletionResult import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.ByteArrayKey @@ -13,7 +13,8 @@ import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.DomainWrapped -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.extensions.derivationPath +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.common.util.hasDerivation import com.tangem.domain.common.util.supportsHdWallet import com.tangem.domain.features.addCustomToken.CustomCurrency @@ -21,7 +22,7 @@ import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.domainStore import com.tangem.operations.derivation.ExtendedPublicKeysMap -import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE +import com.tangem.tap.* import com.tangem.tap.common.analytics.events.ManageTokens import com.tangem.tap.common.extensions.dispatchDebugErrorNotification import com.tangem.tap.common.extensions.dispatchOnMain @@ -30,11 +31,6 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.wallet.models.Currency -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.tap.tangemSdkManager -import com.tangem.tap.userWalletsListManager -import com.tangem.tap.walletCurrenciesManager import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.rekotlin.Middleware @@ -72,7 +68,7 @@ object TokensMiddleware { currencies = convertToCurrencies( blockchains = blockchainsToRemove, tokens = tokensToRemove, - derivationStyle = scanResponse.card.derivationStyle, + derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle(), ), ) @@ -87,7 +83,7 @@ object TokensMiddleware { val currencyList = convertToCurrencies( blockchains = blockchainsToAdd, tokens = tokensToAdd, - derivationStyle = scanResponse.card.derivationStyle, + derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle(), ) if (scanResponse.supportsHdWallet()) { @@ -175,7 +171,7 @@ object TokensMiddleware { val manageTokensCandidates = currencyList.map { it.blockchain }.distinct().filter { it.getSupportedCurves().contains(curve) }.mapNotNull { - it.derivationPath(scanResponse.card.derivationStyle) + it.derivationPath(scanResponse.derivationStyleProvider.getDerivationStyle()) } val customTokensCandidates = currencyList.filter { diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt index e2589be5b7..8e33fdc8f4 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt @@ -1,7 +1,7 @@ package com.tangem.tap.features.tokens.legacy.redux import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.wallet.models.Currency diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt index 4b82889e22..4af0733400 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt @@ -1,8 +1,9 @@ package com.tangem.tap.features.wallet.models -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.domain.common.BlockchainNetwork +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.features.addCustomToken.CustomCurrency diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 1c0c5027f2..f515410168 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -1,11 +1,7 @@ package com.tangem.tap.features.wallet.ui import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.TextView import androidx.activity.OnBackPressedCallback import androidx.annotation.ColorRes @@ -23,8 +19,8 @@ import com.tangem.common.doOnResult import com.tangem.common.extensions.guard import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.NavigationAction -import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.withMainContext +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.feature.swap.api.SwapFeatureToggleManager import com.tangem.feature.swap.domain.SwapInteractor import com.tangem.sdk.extensions.dpToPx @@ -32,14 +28,7 @@ import com.tangem.tap.common.SnackbarHandler import com.tangem.tap.common.TestActions import com.tangem.tap.common.analytics.events.DetailsScreen import com.tangem.tap.common.analytics.events.Token -import com.tangem.tap.common.extensions.appendIfNotNull -import com.tangem.tap.common.extensions.beginDelayedTransition -import com.tangem.tap.common.extensions.fitChipsByGroupWidth -import com.tangem.tap.common.extensions.getColor -import com.tangem.tap.common.extensions.getString -import com.tangem.tap.common.extensions.hide -import com.tangem.tap.common.extensions.show -import com.tangem.tap.common.extensions.toQrCode +import com.tangem.tap.common.extensions.* import com.tangem.tap.common.recyclerView.SpaceItemDecoration import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.utils.SafeStoreSubscriber @@ -57,15 +46,7 @@ import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter import com.tangem.tap.features.wallet.ui.adapters.WalletDetailWarningMessagesAdapter import com.tangem.tap.features.wallet.ui.images.load import com.tangem.tap.features.wallet.ui.test.TestWallet -import com.tangem.tap.features.wallet.ui.utils.assembleWarnings -import com.tangem.tap.features.wallet.ui.utils.getAvailableActions -import com.tangem.tap.features.wallet.ui.utils.getFormattedCryptoAmount -import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatAmount -import com.tangem.tap.features.wallet.ui.utils.isAvailableToBuy -import com.tangem.tap.features.wallet.ui.utils.isAvailableToSell -import com.tangem.tap.features.wallet.ui.utils.isAvailableToSwap -import com.tangem.tap.features.wallet.ui.utils.mainButton -import com.tangem.tap.features.wallet.ui.utils.shouldShowMultipleAddress +import com.tangem.tap.features.wallet.ui.utils.* import com.tangem.tap.store import com.tangem.tap.userWalletsListManagerSafe import com.tangem.tap.walletCurrenciesManager @@ -336,10 +317,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), SafeSt private fun handleCurrencyIcon(currency: Currency) = with(binding.lWalletDetails.lBalance) { ivCurrency.load( currency = currency, - derivationStyle = store.state.globalState - .scanResponse - ?.card - ?.derivationStyle, + derivationStyle = store.state.globalState.scanResponse + ?.derivationStyleProvider?.getDerivationStyle(), ) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index e0a15c7e4b..3f511f7b65 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -7,7 +7,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.tangem.core.analytics.Analytics -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.extensions.hide @@ -77,10 +77,8 @@ class WalletAdapter : ListAdapter { + fun createDefaultCoinsForMultiCurrencyCard( + card: CardDTO, + derivationStyleProvider: DerivationStyleProvider, + ): List { var blockchains = if (demoConfig.isDemoCardId(card.cardId)) { demoConfig.demoBlockchains } else { @@ -23,25 +28,29 @@ internal class CardCurrenciesFactory(private val demoConfig: DemoConfig) { blockchains = blockchains.mapNotNull { it.getTestnetVersion() } } - return blockchains.mapNotNull { createCoin(it, card) } + return blockchains.mapNotNull { createCoin(it, derivationStyleProvider) } } fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency { - val card = scanResponse.card + val derivationStyleProvider = scanResponse.derivationStyleProvider val resolver = scanResponse.cardTypesResolver val blockchain = resolver.getBlockchain() - val coin = requireNotNull(createCoin(blockchain, card)) { + val coin = requireNotNull(createCoin(blockchain, derivationStyleProvider)) { "Coin for the single currency card cannot be null" } val primaryToken = resolver.getPrimaryToken()?.let { token -> - createToken(token, blockchain, card) + createToken(token, blockchain, derivationStyleProvider) } return primaryToken ?: coin } - private fun createToken(sdkToken: SdkToken, blockchain: Blockchain, card: CardDTO): CryptoCurrency.Token? { + private fun createToken( + sdkToken: SdkToken, + blockchain: Blockchain, + derivationStyleProvider: DerivationStyleProvider, + ): CryptoCurrency.Token? { if (blockchain != Blockchain.Unknown) { Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain") return null @@ -56,11 +65,14 @@ internal class CardCurrenciesFactory(private val demoConfig: DemoConfig) { decimals = sdkToken.decimals, isCustom = false, contractAddress = sdkToken.contractAddress, - derivationPath = getDerivationPath(blockchain, card), + derivationPath = getDerivationPath(blockchain, derivationStyleProvider), ) } - private fun createCoin(blockchain: Blockchain, card: CardDTO): CryptoCurrency.Coin? { + private fun createCoin( + blockchain: Blockchain, + derivationStyleProvider: DerivationStyleProvider, + ): CryptoCurrency.Coin? { if (blockchain == Blockchain.Unknown) { Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain") return null @@ -73,7 +85,7 @@ internal class CardCurrenciesFactory(private val demoConfig: DemoConfig) { symbol = blockchain.currency, iconUrl = getCoinIconUrl(blockchain), decimals = blockchain.decimals(), - derivationPath = getDerivationPath(blockchain, card), + derivationPath = getDerivationPath(blockchain, derivationStyleProvider), ) } } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt index c302d2246f..cbc158d2fc 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt @@ -2,10 +2,10 @@ package com.tangem.data.tokens.utils import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.IconsUtil -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.DerivationStyleProvider +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.common.extensions.toNetworkId -import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.tokens.models.CryptoCurrency.ID import com.tangem.domain.tokens.models.Network import com.tangem.blockchain.common.Token as SdkToken @@ -23,12 +23,8 @@ internal fun isCustomToken(tokenId: ID): Boolean { return tokenId.rawCurrencyId == null } -internal fun getDerivationPath(blockchain: Blockchain, card: CardDTO): String? { - return if (card.settings.isHDWalletAllowed) { - blockchain.derivationPath(card.derivationStyle)?.rawPath - } else { - null - } +internal fun getDerivationPath(blockchain: Blockchain, derivationStyleProvider: DerivationStyleProvider): String? { + return blockchain.derivationPath(derivationStyleProvider.getDerivationStyle())?.rawPath } internal fun getBlockchain(networkId: Network.ID): Blockchain { diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt b/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt index 212bd764be..5cb15b3205 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt @@ -5,8 +5,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.calculateHashCode -import com.tangem.domain.common.TapWorkarounds.derivationStyle -import com.tangem.domain.models.scan.CardDTO +import com.tangem.domain.common.extensions.derivationPath @JsonClass(generateAdapter = true) data class BlockchainNetwork( @@ -15,13 +14,9 @@ data class BlockchainNetwork( val tokens: List, ) { - constructor(blockchain: Blockchain, card: CardDTO) : this( + constructor(blockchain: Blockchain, derivationStyleProvider: DerivationStyleProvider) : this( blockchain = blockchain, - derivationPath = if (card.settings.isHDWalletAllowed) { - blockchain.derivationPath(card.derivationStyle)?.rawPath - } else { - null - }, + derivationPath = blockchain.derivationPath(derivationStyleProvider.getDerivationStyle())?.rawPath, tokens = emptyList(), ) diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/DerivationStyleProvider.kt b/domain/legacy/src/main/java/com/tangem/domain/common/DerivationStyleProvider.kt new file mode 100644 index 0000000000..570071b37a --- /dev/null +++ b/domain/legacy/src/main/java/com/tangem/domain/common/DerivationStyleProvider.kt @@ -0,0 +1,26 @@ +package com.tangem.domain.common + +import com.tangem.blockchain.common.derivation.DerivationStyle +import com.tangem.domain.models.scan.CardDTO + +interface DerivationStyleProvider { + fun getDerivationStyle(): DerivationStyle? +} + +internal class TangemDerivationStyleProvider( + private val cardTypesResolver: CardTypesResolver, + private val card: CardDTO, +) : DerivationStyleProvider { + override fun getDerivationStyle(): DerivationStyle? { + return when { + !card.settings.isHDWalletAllowed -> null + firstBatchesOfWallet1(card) -> DerivationStyle.V1 + cardTypesResolver.isWallet2() -> DerivationStyle.V3 + else -> DerivationStyle.V2 + } + } + + private fun firstBatchesOfWallet1(card: CardDTO): Boolean { + return card.batchId == "AC01" || card.batchId == "AC02" || card.batchId == "CB95" + } +} \ No newline at end of file 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 3a04270558..8ff17001e9 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 @@ -1,7 +1,6 @@ package com.tangem.domain.common import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.common.card.Card import com.tangem.common.card.FirmwareVersion import com.tangem.domain.models.scan.CardDTO @@ -32,14 +31,6 @@ object TapWorkarounds { val CardDTO.useOldStyleDerivation: Boolean get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95" - val CardDTO.derivationStyle: DerivationStyle? - get() = if (!settings.isHDWalletAllowed) { - null - } else if (useOldStyleDerivation) { - DerivationStyle.LEGACY - } else { - DerivationStyle.NEW - } val CardDTO.isExcluded: Boolean get() { val excludedBatch = excludedBatches.contains(batchId) 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 c54218c39a..70c16ba9d7 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 @@ -2,7 +2,9 @@ package com.tangem.domain.common.extensions import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.card.EllipticCurve +import com.tangem.crypto.hdWallet.DerivationPath import java.math.BigDecimal @Suppress("ComplexMethod") @@ -216,6 +218,16 @@ fun Blockchain.getPrimaryCurve(): EllipticCurve? { } } +fun Blockchain.derivationPath(style: DerivationStyle?): DerivationPath? { + if (style == null) return null + if (!getSupportedCurves().contains(EllipticCurve.Secp256k1) && + !getSupportedCurves().contains(EllipticCurve.Ed25519) + ) { + return null + } + return style.getConfig().derivations(this).values.first() +} + private const val NODL = "NODL" private const val NODL_AMOUNT_TO_CREATE_ACCOUNT = 1.5 diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExtensions.kt b/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExtensions.kt index 8438a87f14..65d1cd6ea0 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExtensions.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExtensions.kt @@ -5,7 +5,9 @@ import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.toMapKey import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.common.CardTypesResolver +import com.tangem.domain.common.DerivationStyleProvider import com.tangem.domain.common.TangemCardTypesResolver +import com.tangem.domain.common.TangemDerivationStyleProvider import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.domain.models.scan.ScanResponse @@ -17,6 +19,12 @@ val ScanResponse.cardTypesResolver: CardTypesResolver walletData = walletData, ) +val ScanResponse.derivationStyleProvider: DerivationStyleProvider + get() = TangemDerivationStyleProvider( + cardTypesResolver, + card, + ) + fun ScanResponse.twinsIsTwinned(): Boolean = card.isTangemTwins && walletData != null && secondTwinPublicKey != null fun ScanResponse.supportsHdWallet(): Boolean = card.settings.isHDWalletAllowed fun ScanResponse.supportsBackup(): Boolean = card.settings.isBackupAllowed diff --git a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/CustomCurrency.kt b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/CustomCurrency.kt index 6757215dda..78ff46be86 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/CustomCurrency.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/features/addCustomToken/CustomCurrency.kt @@ -1,8 +1,8 @@ package com.tangem.domain.features.addCustomToken import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.common.form.BaseFieldDataConverter import com.tangem.domain.common.form.FieldId 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 30085691d3..3db713c231 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 @@ -5,49 +5,18 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.guard import com.tangem.datasource.api.tangemTech.models.CoinsResponse import com.tangem.domain.AddCustomTokenError -import com.tangem.domain.AddCustomTokenError.Warning.PotentialScamToken -import com.tangem.domain.AddCustomTokenError.Warning.TokenAlreadyAdded -import com.tangem.domain.AddCustomTokenError.Warning.UnsupportedSolanaToken +import com.tangem.domain.AddCustomTokenError.Warning.* import com.tangem.domain.DomainDialog import com.tangem.domain.DomainWrapped -import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.canHandleToken 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.Field -import com.tangem.domain.common.form.Form -import com.tangem.domain.common.form.TokenContractAddressValidator -import com.tangem.domain.common.form.TokenDecimalsValidator -import com.tangem.domain.common.form.TokenNameValidator -import com.tangem.domain.common.form.TokenNetworkValidator -import com.tangem.domain.common.form.TokenSymbolValidator -import com.tangem.domain.features.addCustomToken.AddCustomTokenService -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.ContractAddress -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Decimals -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.DerivationPath -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Name -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Network -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Symbol -import com.tangem.domain.features.addCustomToken.TokenBlockchainField -import com.tangem.domain.features.addCustomToken.TokenDerivationPathField -import com.tangem.domain.features.addCustomToken.TokenField -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.FieldError -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.Init -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnAddCustomTokenClicked -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnCreate -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnDestroy -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenContractAddressChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenDecimalsChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenDerivationPathChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenNameChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenNetworkChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.OnTokenSymbolChanged -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.Screen -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.SetFoundTokenInfo -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.UpdateForm -import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.Warning +import com.tangem.domain.common.form.* +import com.tangem.domain.common.util.derivationStyleProvider +import com.tangem.domain.features.addCustomToken.* +import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.* +import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.* import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenState.Companion.createInitialScreenState import com.tangem.domain.redux.BaseStoreHub import com.tangem.domain.redux.DomainState @@ -590,7 +559,7 @@ private class AddCustomTokenReducer( ) state.copy( - cardDerivationStyle = card.derivationStyle, + cardDerivationStyle = globalState.scanResponse?.derivationStyleProvider?.getDerivationStyle(), form = Form(AddCustomTokenState.createFormFields(card, CustomTokenType.Blockchain)), tangemTechServiceManager = tangemTechServiceManager, screenState = createInitialScreenState(card.settings.isHDWalletAllowed), 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 3377646d25..f68eeb7b87 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 @@ -1,40 +1,19 @@ package com.tangem.domain.features.addCustomToken.redux import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle 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.TapWorkarounds.isTestCard +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.extensions.isSupportedInApp import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.extensions.supportedTokens -import com.tangem.domain.common.form.CustomTokenValidator -import com.tangem.domain.common.form.DataField -import com.tangem.domain.common.form.FieldDataConverter -import com.tangem.domain.common.form.FieldId -import com.tangem.domain.common.form.FieldToJsonConverter -import com.tangem.domain.common.form.Form -import com.tangem.domain.common.form.StringIsEmptyValidator -import com.tangem.domain.common.form.StringIsNotEmptyValidator -import com.tangem.domain.common.form.TokenContractAddressValidator -import com.tangem.domain.common.form.TokenDecimalsValidator -import com.tangem.domain.common.form.TokenNameValidator -import com.tangem.domain.common.form.TokenNetworkValidator -import com.tangem.domain.common.form.TokenSymbolValidator -import com.tangem.domain.features.addCustomToken.AddCustomTokenService -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.ContractAddress -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Decimals -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.DerivationPath -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Name -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Network -import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.Symbol -import com.tangem.domain.features.addCustomToken.TokenBlockchainField -import com.tangem.domain.features.addCustomToken.TokenDerivationPathField -import com.tangem.domain.features.addCustomToken.TokenField +import com.tangem.domain.common.form.* +import com.tangem.domain.features.addCustomToken.* +import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.* import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.redux.DomainState import com.tangem.domain.redux.state.StringActionStateConverter diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index 34ef60f9ed..bd0ea90ed4 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -8,7 +8,8 @@ import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.datasource.local.walletmanager.WalletManagersStore -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.extensions.derivationPath +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.common.util.hasDerivation import com.tangem.domain.demo.DemoConfig import com.tangem.domain.tokens.models.CryptoCurrency @@ -56,7 +57,8 @@ class DefaultWalletManagersFacade( return getOrCreateWalletManager( userWallet = userWallet, blockchain = blockchain, - derivationPath = blockchain.derivationPath(userWallet.scanResponse.card.derivationStyle), + derivationPath = blockchain + .derivationPath(userWallet.scanResponse.derivationStyleProvider.getDerivationStyle()), ) ?.wallet ?.getExploreUrl() @@ -120,7 +122,7 @@ class DefaultWalletManagersFacade( extraTokens: Set, ): UpdateWalletManagerResult { val scanResponse = userWallet.scanResponse - val derivationPath = blockchain.derivationPath(scanResponse.card.derivationStyle) + val derivationPath = blockchain.derivationPath(scanResponse.derivationStyleProvider.getDerivationStyle()) if (derivationPath != null && !scanResponse.hasDerivation(blockchain, derivationPath.rawPath)) { Timber.e("Derivation missed for: $blockchain") diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index 06ca0ab8c5..12cdb339a1 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -3,7 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels import androidx.lifecycle.* import androidx.paging.cachedIn import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.Provider import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess @@ -11,8 +11,9 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState import com.tangem.domain.card.* import com.tangem.domain.common.CardTypesResolver -import com.tangem.domain.common.TapWorkarounds.derivationStyle +import com.tangem.domain.common.extensions.derivationPath import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase import com.tangem.domain.tokens.GetPrimaryCurrencyUseCase @@ -172,7 +173,7 @@ internal class WalletViewModel @Inject constructor( val wallet = getWallet(index) updateTxHistory( blockchain = getCardTypeResolver(index).getBlockchain(), - derivationStyle = wallet.scanResponse.card.derivationStyle, + derivationStyle = wallet.scanResponse.derivationStyleProvider.getDerivationStyle(), ) updateMarketPrice(userWalletId = wallet.walletId) updateNotifications(index)