Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-10 17:25:56 +04:00
parent 9c524c8113
commit 11687f6368
34 changed files with 239 additions and 239 deletions

View file

@ -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<CreateProductWalletTaskResponse> {
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<CreateProductWalletTaskResponse> {
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)),
)

View file

@ -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,

View file

@ -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<CreateProductWalletTaskResponse> {
@ -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<CreateProductWalletTaskResponse> {
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

View file

@ -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<BlockchainNetwork> {
private suspend fun getBlockchainsToDerive(
card: CardDTO,
derivationStyleProvider: DerivationStyleProvider,
): List<BlockchainNetwork> {
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<ByteArrayKey, List<DerivationPath>> {
val blockchains = getBlockchainsToDerive(card)
private suspend fun collectDerivations(
card: CardDTO,
derivationStyleProvider: DerivationStyleProvider,
): Map<ByteArrayKey, List<DerivationPath>> {
val blockchains = getBlockchainsToDerive(card, derivationStyleProvider)
val derivations = mutableMapOf<ByteArrayKey, List<DerivationPath>>()
blockchains.forEach { blockchain ->

View file

@ -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<Currency>.addMissingBlockchainsIfNeeded(card: CardDTO): List<Currency> {
private fun List<Currency>.addMissingBlockchainsIfNeeded(
derivationStyleProvider: DerivationStyleProvider,
): List<Currency> {
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)

View file

@ -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 {

View file

@ -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
}

View file

@ -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<Blockchain> {
private fun getAvailableBlockchains(
derivationStyleProvider: DerivationStyleProvider,
walletState: WalletState,
): List<Blockchain> {
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,

View file

@ -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

View file

@ -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,
),
)
}

View file

@ -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 {

View file

@ -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<TokenWithBlockchain>, blockchains: List<Blockchain>) {
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<WalletDataModel>.toNonCustomTokensWithBlockchains(
style: DerivationStyle?,
derivationStyle: DerivationStyle?,
): List<TokenWithBlockchain> {
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) }

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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(),
)
}

View file

@ -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<WalletDataModel, WalletAdapter.WalletsViewHold
ivCurrency.load(
currency = wallet.currency,
derivationStyle = store.state.globalState
.scanResponse
?.card
?.derivationStyle,
derivationStyle = store.state.globalState.scanResponse
?.derivationStyleProvider?.getDerivationStyle(),
)
lContent.tvCurrency.text = wallet.currency.currencyName

View file

@ -7,7 +7,7 @@ import android.widget.TextView
import androidx.constraintlayout.utils.widget.ImageFilterView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.sdk.extensions.dpToPx
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.wallet.databinding.ViewCurrencyIconBinding

View file

@ -6,7 +6,7 @@ import com.badoo.mvicore.modelWatcher
import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Portfolio
import com.tangem.tap.common.entities.FiatCurrency
@ -104,13 +104,13 @@ class MultiWalletView : WalletView() {
watcher.invoke(state)
binding.btnAddToken.setOnClickListener {
val card = store.state.globalState.scanResponse!!.card
Analytics.send(Portfolio.ButtonManageTokens())
store.dispatch(
TokensAction.SetArgs.ManageAccess(
wallets = state.walletsDataFromStores,
derivationStyle = card.derivationStyle,
derivationStyle = store.state.globalState.scanResponse
?.derivationStyleProvider?.getDerivationStyle(),
),
)
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))

View file

@ -10,8 +10,9 @@ import com.tangem.common.extensions.ByteArrayKey
import com.tangem.common.extensions.toMapKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.derivationPath
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.common.util.hasDerivation
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.lib.crypto.DerivationManager
@ -46,13 +47,13 @@ class DerivationManagerImpl(
} else {
null
}
val blockchainNetwork = BlockchainNetwork(blockchain, card)
val appCurrency = com.tangem.tap.features.wallet.models.Currency.fromBlockchainNetwork(
blockchainNetwork,
appToken,
)
val scanResponse = appStateHolder.scanResponse
if (scanResponse != null) {
val blockchainNetwork = BlockchainNetwork(blockchain, scanResponse.derivationStyleProvider)
val appCurrency = com.tangem.tap.features.wallet.models.Currency.fromBlockchainNetwork(
blockchainNetwork,
appToken,
)
deriveMissingBlockchains(
scanResponse = scanResponse,
currencyList = listOf(appCurrency),
@ -70,7 +71,7 @@ class DerivationManagerImpl(
val scanResponse = appStateHolder.scanResponse
val blockchain = Blockchain.fromNetworkId(networkId)
if (scanResponse != null && blockchain != null) {
return blockchain.derivationPath(appStateHolder.getActualCard()?.derivationStyle)?.rawPath
return blockchain.derivationPath(scanResponse.derivationStyleProvider.getDerivationStyle())?.rawPath
}
return null
}
@ -162,7 +163,7 @@ class DerivationManagerImpl(
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 {

View file

@ -9,6 +9,7 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.core.error.DataError
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.tokens.repository.CurrenciesRepository
@ -154,7 +155,8 @@ internal class DefaultCurrenciesRepository(
val response = userTokensStore.getSyncOrNull(userWallet.walletId)
?: userTokensResponseFactory.createUserTokensResponse(
currencies = cardCurrenciesFactory.createDefaultCoinsForMultiCurrencyCard(
userWallet.scanResponse.card,
card = userWallet.scanResponse.card,
derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider,
),
isGroupedByNetwork = false,
isSortedByBalance = false,

View file

@ -1,8 +1,10 @@
package com.tangem.data.tokens.utils
import com.tangem.blockchain.common.Blockchain
import com.tangem.domain.common.DerivationStyleProvider
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
@ -12,7 +14,10 @@ import com.tangem.blockchain.common.Token as SdkToken
internal class CardCurrenciesFactory(private val demoConfig: DemoConfig) {
fun createDefaultCoinsForMultiCurrencyCard(card: CardDTO): List<CryptoCurrency.Coin> {
fun createDefaultCoinsForMultiCurrencyCard(
card: CardDTO,
derivationStyleProvider: DerivationStyleProvider,
): List<CryptoCurrency.Coin> {
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),
)
}
}

View file

@ -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 {

View file

@ -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<Token>,
) {
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(),
)

View file

@ -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"
}
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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),

View file

@ -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

View file

@ -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<CryptoCurrency.Token>,
): 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")

View file

@ -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)