Updated on 2026-08-14
This commit is contained in:
commit
7c7f07080e
1413 changed files with 24740 additions and 8757 deletions
|
|
@ -2,9 +2,8 @@ package com.tangem.data.common.currency
|
|||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
/**
|
||||
* Factory for creating list of [CryptoCurrency] for selected card
|
||||
|
|
@ -20,7 +19,18 @@ interface CardCryptoCurrencyFactory {
|
|||
* @param network network
|
||||
*/
|
||||
@Throws
|
||||
suspend fun create(userWalletId: UserWalletId, network: Network): List<CryptoCurrency>
|
||||
suspend fun create(userWalletId: UserWalletId, network: Network): List<CryptoCurrency> {
|
||||
return create(userWalletId = userWalletId, networks = setOf(network))[network].orEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal method for creating list of [CryptoCurrency] in [networks] for any card
|
||||
*
|
||||
* @param userWalletId user wallet id that determines type of card
|
||||
* @param networks networks
|
||||
*/
|
||||
@Throws
|
||||
suspend fun create(userWalletId: UserWalletId, networks: Set<Network>): Map<Network, List<CryptoCurrency>>
|
||||
|
||||
/**
|
||||
* Universal method for creating list of [CryptoCurrency] in [network] for any card
|
||||
|
|
@ -46,23 +56,23 @@ interface CardCryptoCurrencyFactory {
|
|||
/**
|
||||
* Create default coins for multi currency card
|
||||
*
|
||||
* @param scanResponse scan response
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
fun createDefaultCoinsForMultiCurrencyCard(scanResponse: ScanResponse): List<CryptoCurrency.Coin>
|
||||
fun createDefaultCoinsForMultiCurrencyWallet(userWallet: UserWallet): List<CryptoCurrency.Coin>
|
||||
|
||||
/**
|
||||
* Create primary currency for single currency card
|
||||
*
|
||||
* @param scanResponse scan response
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
@Throws
|
||||
fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency
|
||||
fun createPrimaryCurrencyForSingleCurrencyCard(userWallet: UserWallet.Cold): CryptoCurrency
|
||||
|
||||
/**
|
||||
* Create currencies for single currency card with token (like, NODL)
|
||||
*
|
||||
* @param scanResponse scan response
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
@Throws
|
||||
fun createCurrenciesForSingleCurrencyCardWithToken(scanResponse: ScanResponse): List<CryptoCurrency>
|
||||
fun createCurrenciesForSingleCurrencyCardWithToken(userWallet: UserWallet.Cold): List<CryptoCurrency>
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import com.tangem.blockchainsdk.utils.toCoinId
|
|||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import timber.log.Timber
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class CryptoCurrencyFactory(
|
|||
sdkToken: SdkToken,
|
||||
blockchain: Blockchain,
|
||||
extraDerivationPath: String?,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
): CryptoCurrency.Token? {
|
||||
if (blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||
|
|
@ -56,7 +56,7 @@ class CryptoCurrencyFactory(
|
|||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
) ?: return null
|
||||
|
||||
val id = getTokenId(network, sdkToken)
|
||||
|
|
@ -76,7 +76,7 @@ class CryptoCurrencyFactory(
|
|||
fun createCoin(
|
||||
blockchain: Blockchain,
|
||||
extraDerivationPath: String?,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
): CryptoCurrency.Coin? {
|
||||
if (blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||
|
|
@ -86,15 +86,15 @@ class CryptoCurrencyFactory(
|
|||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
) ?: return null
|
||||
|
||||
return createCoin(network)
|
||||
}
|
||||
|
||||
fun createCoin(networkId: String, extraDerivationPath: String?, scanResponse: ScanResponse): CryptoCurrency.Coin? {
|
||||
fun createCoin(networkId: String, extraDerivationPath: String?, userWallet: UserWallet): CryptoCurrency.Coin? {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId) ?: Blockchain.Unknown
|
||||
return createCoin(blockchain, extraDerivationPath, scanResponse)
|
||||
return createCoin(blockchain, extraDerivationPath, userWallet)
|
||||
}
|
||||
|
||||
fun createCoin(network: Network): CryptoCurrency.Coin {
|
||||
|
|
@ -115,7 +115,7 @@ class CryptoCurrencyFactory(
|
|||
token: Token,
|
||||
networkId: String,
|
||||
extraDerivationPath: String?,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
): CryptoCurrency.Token? {
|
||||
val sdkToken = SdkToken(
|
||||
name = token.name,
|
||||
|
|
@ -129,7 +129,7 @@ class CryptoCurrencyFactory(
|
|||
sdkToken = sdkToken,
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +141,8 @@ class CryptoCurrencyFactory(
|
|||
decimals = cryptoCurrency.decimals,
|
||||
id = cryptoCurrency.id.rawCurrencyId?.value,
|
||||
)
|
||||
val blockchain = Blockchain.fromNetworkId(cryptoCurrency.network.backendId) ?: Blockchain.Unknown
|
||||
val blockchain =
|
||||
Blockchain.fromNetworkId(cryptoCurrency.network.backendId) ?: Blockchain.Unknown
|
||||
val id = getTokenId(network, sdkToken)
|
||||
return CryptoCurrency.Token(
|
||||
id = id,
|
||||
|
|
|
|||
|
|
@ -2,21 +2,18 @@ package com.tangem.data.common.currency
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.card.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
|
||||
/**
|
||||
* Default implementation of factory for creating list of [CryptoCurrency] for selected card
|
||||
|
|
@ -36,40 +33,45 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
|
||||
private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory(excludedBlockchains) }
|
||||
|
||||
override suspend fun create(userWalletId: UserWalletId, network: Network): List<CryptoCurrency> {
|
||||
override suspend fun create(
|
||||
userWalletId: UserWalletId,
|
||||
networks: Set<Network>,
|
||||
): Map<Network, List<CryptoCurrency>> {
|
||||
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
|
||||
|
||||
val blockchain = Blockchain.fromNetworkId(networkId = network.backendId)
|
||||
|
||||
// multi-currency wallet
|
||||
if (userWallet !is UserWallet.Cold || userWallet.isMultiCurrency) {
|
||||
return getMultiWalletCurrencies(userWallet = userWallet, networks = setOf(network))[network].orEmpty()
|
||||
return getMultiWalletCurrencies(userWallet = userWallet, networks = networks)
|
||||
}
|
||||
|
||||
// check if the blockchain of single-currency wallet is the same as network
|
||||
val cardBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain()
|
||||
if (cardBlockchain != blockchain) return emptyList()
|
||||
val cardNetworkId = userWallet.scanResponse.cardTypesResolver.getBlockchain().toNetworkId()
|
||||
val cardNetwork = networks.firstOrNull { it.backendId == cardNetworkId }
|
||||
|
||||
if (cardNetwork == null) return emptyMap()
|
||||
|
||||
// single-currency wallet with token (NODL)
|
||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
return createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse)
|
||||
val currencies = createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||
return mapOf(cardNetwork to currencies)
|
||||
}
|
||||
|
||||
// single-currency wallet
|
||||
return createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf)
|
||||
val primaryCurrency = createPrimaryCurrencyForSingleCurrencyCard(userWallet)
|
||||
return mapOf(cardNetwork to listOf(primaryCurrency))
|
||||
}
|
||||
|
||||
override suspend fun createByRawId(userWalletId: UserWalletId, networkRawId: Network.RawID): List<CryptoCurrency> {
|
||||
override suspend fun createByRawId(userWalletId: UserWalletId, network: Network.RawID): List<CryptoCurrency> {
|
||||
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
|
||||
|
||||
val blockchain = networkRawId.toBlockchain()
|
||||
val blockchain = network.toBlockchain()
|
||||
|
||||
// multi-currency wallet
|
||||
if (userWallet.isMultiCurrency || userWallet !is UserWallet.Cold) {
|
||||
return getMultiWalletCurrenciesByRawId(
|
||||
userWallet = userWallet,
|
||||
rawIds = setOf(networkRawId),
|
||||
)[networkRawId].orEmpty()
|
||||
rawIds = setOf(network),
|
||||
)[network].orEmpty()
|
||||
}
|
||||
|
||||
// check if the blockchain of single-currency wallet is the same as network
|
||||
|
|
@ -78,11 +80,11 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
|
||||
// single-currency wallet with token (NODL)
|
||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
return createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse)
|
||||
return createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||
}
|
||||
|
||||
// single-currency wallet
|
||||
return createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf)
|
||||
return createPrimaryCurrencyForSingleCurrencyCard(userWallet).let(::listOf)
|
||||
}
|
||||
|
||||
override suspend fun createCurrenciesForMultiCurrencyCard(
|
||||
|
|
@ -94,44 +96,54 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
return getMultiWalletCurrencies(userWallet = userWallet, networks = networks)
|
||||
}
|
||||
|
||||
override fun createDefaultCoinsForMultiCurrencyCard(scanResponse: ScanResponse): List<CryptoCurrency.Coin> {
|
||||
require(scanResponse.cardTypesResolver.isMultiwalletAllowed()) { "It isn't multi-currency wallet" }
|
||||
override fun createDefaultCoinsForMultiCurrencyWallet(userWallet: UserWallet): List<CryptoCurrency.Coin> {
|
||||
require(userWallet.isMultiCurrency) { "It isn't multi-currency wallet" }
|
||||
|
||||
val card = scanResponse.card
|
||||
val blockchains = when (userWallet) {
|
||||
is UserWallet.Cold -> {
|
||||
val card = userWallet.scanResponse.card
|
||||
|
||||
var blockchains = if (demoConfig.isDemoCardId(card.cardId)) {
|
||||
demoConfig.demoBlockchains
|
||||
} else {
|
||||
listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
}
|
||||
var blockchainsInternal = if (demoConfig.isDemoCardId(card.cardId)) {
|
||||
demoConfig.demoBlockchains
|
||||
} else {
|
||||
listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
}
|
||||
|
||||
if (card.isTestCard) {
|
||||
blockchains = blockchains.mapNotNull { it.getTestnetVersion() }
|
||||
if (card.isTestCard) {
|
||||
blockchainsInternal = blockchainsInternal.mapNotNull { it.getTestnetVersion() }
|
||||
}
|
||||
|
||||
blockchainsInternal
|
||||
}
|
||||
|
||||
is UserWallet.Hot -> listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
}
|
||||
|
||||
return blockchains.mapNotNull {
|
||||
cryptoCurrencyFactory.createCoin(
|
||||
blockchain = it,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency {
|
||||
require(scanResponse.cardTypesResolver.isSingleWallet()) { "It isn't single-currency wallet" }
|
||||
override fun createPrimaryCurrencyForSingleCurrencyCard(userWallet: UserWallet.Cold): CryptoCurrency {
|
||||
require(userWallet.scanResponse.cardTypesResolver.isSingleWallet()) {
|
||||
"It isn't single-currency wallet"
|
||||
}
|
||||
|
||||
return with(getSingleWalletCurrencies(scanResponse)) {
|
||||
return with(getSingleWalletCurrencies(userWallet)) {
|
||||
primaryToken ?: coin
|
||||
}
|
||||
}
|
||||
|
||||
override fun createCurrenciesForSingleCurrencyCardWithToken(scanResponse: ScanResponse): List<CryptoCurrency> {
|
||||
require(scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
override fun createCurrenciesForSingleCurrencyCardWithToken(userWallet: UserWallet.Cold): List<CryptoCurrency> {
|
||||
require(userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
"It isn't single-currency wallet with token"
|
||||
}
|
||||
|
||||
return with(getSingleWalletCurrencies(scanResponse)) {
|
||||
return with(getSingleWalletCurrencies(userWallet)) {
|
||||
listOfNotNull(coin, primaryToken)
|
||||
}
|
||||
}
|
||||
|
|
@ -143,13 +155,15 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
return responseCryptoCurrenciesFactory.createCurrencies(
|
||||
val existingNetworkWithCurrencies = responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token ->
|
||||
networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath }
|
||||
},
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
userWallet = userWallet,
|
||||
)
|
||||
.groupBy(CryptoCurrency::network)
|
||||
|
||||
return networks.associateWith { emptyList<CryptoCurrency>() } + existingNetworkWithCurrencies
|
||||
}
|
||||
|
||||
private suspend fun getMultiWalletCurrenciesByRawId(
|
||||
|
|
@ -163,19 +177,19 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
|
||||
return responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token -> token.networkId in networkIds },
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
userWallet = userWallet,
|
||||
)
|
||||
.groupBy { it.network.id.rawId }
|
||||
}
|
||||
|
||||
private fun getSingleWalletCurrencies(scanResponse: ScanResponse): SingleWalletCurrencies {
|
||||
val resolver = scanResponse.cardTypesResolver
|
||||
private fun getSingleWalletCurrencies(userWallet: UserWallet.Cold): SingleWalletCurrencies {
|
||||
val resolver = userWallet.cardTypesResolver
|
||||
val blockchain = resolver.getBlockchain()
|
||||
|
||||
val coin = cryptoCurrencyFactory.createCoin(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
|
||||
requireNotNull(coin) { "Coin for the single currency card cannot be null" }
|
||||
|
|
@ -185,12 +199,15 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
sdkToken = token,
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
|
||||
return SingleWalletCurrencies(coin = coin, primaryToken = primaryToken)
|
||||
}
|
||||
|
||||
private data class SingleWalletCurrencies(val coin: CryptoCurrency, val primaryToken: CryptoCurrency?)
|
||||
private data class SingleWalletCurrencies(
|
||||
val coin: CryptoCurrency,
|
||||
val primaryToken: CryptoCurrency?,
|
||||
)
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ import com.tangem.blockchainsdk.utils.fromNetworkId
|
|||
import com.tangem.blockchainsdk.utils.toCoinId
|
||||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
|
|
@ -17,41 +17,41 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
private val networkFactory: NetworkFactory,
|
||||
) {
|
||||
|
||||
fun createCurrency(currencyId: String, response: UserTokensResponse, scanResponse: ScanResponse): CryptoCurrency {
|
||||
fun createCurrency(currencyId: String, response: UserTokensResponse, userWallet: UserWallet): CryptoCurrency {
|
||||
return response.tokens
|
||||
.asSequence()
|
||||
.mapNotNull { createCurrency(it, scanResponse) }
|
||||
.mapNotNull { createCurrency(it, userWallet) }
|
||||
.first { it.id.value == currencyId }
|
||||
}
|
||||
|
||||
fun createCurrencies(response: UserTokensResponse, scanResponse: ScanResponse): List<CryptoCurrency> {
|
||||
return createCurrencies(tokens = response.tokens, scanResponse = scanResponse)
|
||||
fun createCurrencies(response: UserTokensResponse, userWallet: UserWallet): List<CryptoCurrency> {
|
||||
return createCurrencies(tokens = response.tokens, userWallet = userWallet)
|
||||
}
|
||||
|
||||
fun createCurrencies(tokens: List<UserTokensResponse.Token>, scanResponse: ScanResponse): List<CryptoCurrency> {
|
||||
fun createCurrencies(tokens: List<UserTokensResponse.Token>, userWallet: UserWallet): List<CryptoCurrency> {
|
||||
return tokens
|
||||
.asSequence()
|
||||
.mapNotNull { createCurrency(it, scanResponse) }
|
||||
.mapNotNull { createCurrency(it, userWallet) }
|
||||
.distinctBy(CryptoCurrency::id)
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun createCurrency(responseToken: UserTokensResponse.Token, scanResponse: ScanResponse): CryptoCurrency? {
|
||||
fun createCurrency(responseToken: UserTokensResponse.Token, userWallet: UserWallet): CryptoCurrency? {
|
||||
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
|
||||
if (blockchain == null || blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")
|
||||
return null
|
||||
}
|
||||
|
||||
if (scanResponse.cardTypesResolver.isTestCard()) {
|
||||
if (userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isTestCard()) {
|
||||
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
||||
}
|
||||
|
||||
val sdkToken = createSdkToken(responseToken)
|
||||
return if (sdkToken == null) {
|
||||
createCoin(blockchain, responseToken, scanResponse)
|
||||
createCoin(blockchain, responseToken, userWallet)
|
||||
} else {
|
||||
createToken(blockchain, sdkToken, responseToken.derivationPath, scanResponse)
|
||||
createToken(blockchain, sdkToken, responseToken.derivationPath, userWallet)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,12 +70,12 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
private fun createCoin(
|
||||
blockchain: Blockchain,
|
||||
responseToken: UserTokensResponse.Token,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
): CryptoCurrency.Coin? {
|
||||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = responseToken.derivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
) ?: return null
|
||||
|
||||
return CryptoCurrency.Coin(
|
||||
|
|
@ -105,12 +105,12 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
blockchain: Blockchain,
|
||||
sdkToken: Token,
|
||||
responseDerivationPath: String?,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
): CryptoCurrency.Token? {
|
||||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = responseDerivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
) ?: return null
|
||||
|
||||
val id = getTokenId(network, sdkToken)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ package com.tangem.data.common.currency
|
|||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.data.common.tokens.UserTokensBackwardCompatibility
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.data.common.quote.QuotesFetcher
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import com.tangem.blockchain.common.FeePaidCurrency
|
|||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.extensions.canHandleToken
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.card.DerivationStyleProvider
|
||||
import com.tangem.domain.card.common.extensions.canHandleToken
|
||||
import com.tangem.domain.card.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -31,19 +30,18 @@ class NetworkFactory @Inject constructor(
|
|||
*
|
||||
* @param blockchain blockchain
|
||||
* @param extraDerivationPath extra derivation path
|
||||
* @param scanResponse scan response
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
fun create(blockchain: Blockchain, extraDerivationPath: String?, scanResponse: ScanResponse): Network? {
|
||||
fun create(blockchain: Blockchain, extraDerivationPath: String?, userWallet: UserWallet): Network? {
|
||||
return create(
|
||||
blockchain = blockchain,
|
||||
derivationPath = createDerivationPath(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
cardDerivationStyleProvider = scanResponse.derivationStyleProvider,
|
||||
cardDerivationStyleProvider = userWallet.derivationStyleProvider,
|
||||
),
|
||||
canHandleTokens = scanResponse.card.canHandleToken(
|
||||
canHandleTokens = userWallet.canHandleToken(
|
||||
blockchain = blockchain,
|
||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
),
|
||||
)
|
||||
|
|
@ -54,17 +52,16 @@ class NetworkFactory @Inject constructor(
|
|||
*
|
||||
* @param networkId network id
|
||||
* @param derivationPath derivation path
|
||||
* @param scanResponse scan response
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
fun create(networkId: Network.ID, derivationPath: Network.DerivationPath, scanResponse: ScanResponse): Network? {
|
||||
fun create(networkId: Network.ID, derivationPath: Network.DerivationPath, userWallet: UserWallet): Network? {
|
||||
val blockchain = networkId.toBlockchain()
|
||||
|
||||
return create(
|
||||
blockchain = blockchain,
|
||||
derivationPath = derivationPath,
|
||||
canHandleTokens = scanResponse.card.canHandleToken(
|
||||
canHandleTokens = userWallet.canHandleToken(
|
||||
blockchain = blockchain,
|
||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ import com.tangem.data.common.network.NetworkFactory
|
|||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.configs.GenericCardConfig
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.card.configs.GenericCardConfig
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
|
|
@ -266,7 +266,9 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
CreateCurrenciesForMultiWalletModel(
|
||||
multiWallet = createMultiWallet(),
|
||||
userTokensResponse = createUserTokensResponse(),
|
||||
expected = Result.success(emptyMap()),
|
||||
expected = Result.success(
|
||||
setOf(ethereum.network, bitcoin.network).associateWith { emptyList() },
|
||||
),
|
||||
),
|
||||
CreateCurrenciesForMultiWalletModel(
|
||||
multiWallet = createMultiWallet(),
|
||||
|
|
@ -306,7 +308,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
val multiWallet = model.multiWallet
|
||||
|
||||
// Act
|
||||
val actual = factory.createDefaultCoinsForMultiCurrencyCard(scanResponse = multiWallet.scanResponse)
|
||||
val actual = factory.createDefaultCoinsForMultiCurrencyWallet(multiWallet)
|
||||
|
||||
// Assert
|
||||
val expected = model.expected
|
||||
|
|
@ -353,7 +355,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
|
||||
// Act
|
||||
val actual = runCatching {
|
||||
factory.createPrimaryCurrencyForSingleCurrencyCard(scanResponse = singleWallet.scanResponse)
|
||||
factory.createPrimaryCurrencyForSingleCurrencyCard(singleWallet)
|
||||
}
|
||||
|
||||
// Assert
|
||||
|
|
@ -403,7 +405,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
|
||||
// Act
|
||||
val actual = runCatching {
|
||||
factory.createCurrenciesForSingleCurrencyCardWithToken(scanResponse = userWallet.scanResponse)
|
||||
factory.createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||
}
|
||||
|
||||
// Assert
|
||||
|
|
@ -552,7 +554,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
sdkToken = userWallet.scanResponse.cardTypesResolver.getPrimaryToken()!!,
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
userWallet = userWallet,
|
||||
)!!
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
|||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.datasource.api.common.response.ApiResponseError
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
|
|
|||
|
|
@ -5,13 +5,15 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||
import com.tangem.common.test.utils.ProvideTestModels
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.configs.GenericCardConfig
|
||||
import com.tangem.domain.common.configs.MultiWalletCardConfig
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.card.DerivationStyleProvider
|
||||
import com.tangem.domain.card.configs.GenericCardConfig
|
||||
import com.tangem.domain.card.configs.MultiWalletCardConfig
|
||||
import com.tangem.domain.card.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.junit.jupiter.api.Nested
|
||||
|
|
@ -43,7 +45,7 @@ class NetworkFactoryTest {
|
|||
val actual = networkFactory.create(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
)
|
||||
|
||||
// Assert
|
||||
|
|
@ -59,14 +61,14 @@ class NetworkFactoryTest {
|
|||
networkFactory.create(
|
||||
blockchain = model.blockchain,
|
||||
extraDerivationPath = model.extraDerivationPath,
|
||||
scanResponse = model.scanResponse,
|
||||
userWallet = model.userWallet,
|
||||
)
|
||||
}
|
||||
is CreateTestModel.Second -> {
|
||||
networkFactory.create(
|
||||
networkId = model.networkId,
|
||||
derivationPath = model.derivationPath,
|
||||
scanResponse = model.scanResponse,
|
||||
userWallet = model.userWallet,
|
||||
)
|
||||
}
|
||||
is CreateTestModel.Third -> {
|
||||
|
|
@ -89,27 +91,27 @@ class NetworkFactoryTest {
|
|||
CreateTestModel.First(
|
||||
blockchain = Blockchain.Unknown,
|
||||
extraDerivationPath = null, // never-mind
|
||||
scanResponse = createMultiWalletScanResponse(), // never-mind
|
||||
userWallet = createUserWallet(),
|
||||
expected = null,
|
||||
),
|
||||
createFirst(
|
||||
extraDerivationPath = null,
|
||||
scanResponse = createGenericScanResponse(), // default derivation path is null
|
||||
userWallet = createUserWallet(createGenericScanResponse()), // default derivation path is null
|
||||
expectedDerivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
createFirst(
|
||||
extraDerivationPath = null,
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"), // use default
|
||||
),
|
||||
createFirst(
|
||||
extraDerivationPath = "m/44'/60'/0'/0/0", // as default
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
||||
),
|
||||
createFirst(
|
||||
extraDerivationPath = "m/84'/0'/0'/0/0",
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
expectedDerivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
||||
),
|
||||
// endregion
|
||||
|
|
@ -118,23 +120,23 @@ class NetworkFactoryTest {
|
|||
CreateTestModel.Second(
|
||||
networkId = Network.ID(value = "1", derivationPath = Network.DerivationPath.None),
|
||||
derivationPath = Network.DerivationPath.None, // never-mind
|
||||
scanResponse = createMultiWalletScanResponse(), // never-mind
|
||||
userWallet = createUserWallet(), // never-mind
|
||||
expected = null,
|
||||
),
|
||||
createSecond(
|
||||
scanResponse = createGenericScanResponse(), // default derivation path is null
|
||||
userWallet = createUserWallet(createGenericScanResponse()), // default derivation path is null
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
createSecond(
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
createSecond(
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
||||
),
|
||||
createSecond(
|
||||
scanResponse = createMultiWalletScanResponse(),
|
||||
userWallet = createUserWallet(),
|
||||
derivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
||||
),
|
||||
// endregion
|
||||
|
|
@ -176,13 +178,13 @@ class NetworkFactoryTest {
|
|||
|
||||
private fun createFirst(
|
||||
extraDerivationPath: String?,
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
expectedDerivationPath: Network.DerivationPath,
|
||||
): CreateTestModel.First {
|
||||
return CreateTestModel.First(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||
id = Network.ID(
|
||||
value = Blockchain.Ethereum.id,
|
||||
|
|
@ -195,13 +197,13 @@ class NetworkFactoryTest {
|
|||
}
|
||||
|
||||
private fun createSecond(
|
||||
scanResponse: ScanResponse,
|
||||
userWallet: UserWallet,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CreateTestModel.Second {
|
||||
return CreateTestModel.Second(
|
||||
networkId = Network.ID(value = Blockchain.Ethereum.id, derivationPath = derivationPath),
|
||||
derivationPath = derivationPath,
|
||||
scanResponse = scanResponse,
|
||||
userWallet = userWallet,
|
||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||
id = Network.ID(
|
||||
value = Blockchain.Ethereum.id,
|
||||
|
|
@ -232,6 +234,10 @@ class NetworkFactoryTest {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createUserWallet(scanResponse: ScanResponse = createMultiWalletScanResponse()): UserWallet.Cold {
|
||||
return MockUserWalletFactory.create(scanResponse)
|
||||
}
|
||||
|
||||
private fun createMultiWalletScanResponse(): ScanResponse {
|
||||
return MockScanResponseFactory.create(
|
||||
cardConfig = MultiWalletCardConfig,
|
||||
|
|
@ -254,14 +260,14 @@ class NetworkFactoryTest {
|
|||
data class First(
|
||||
val blockchain: Blockchain,
|
||||
val extraDerivationPath: String?,
|
||||
val scanResponse: ScanResponse,
|
||||
val userWallet: UserWallet,
|
||||
override val expected: Network?,
|
||||
) : CreateTestModel
|
||||
|
||||
data class Second(
|
||||
val networkId: Network.ID,
|
||||
val derivationPath: Network.DerivationPath,
|
||||
val scanResponse: ScanResponse,
|
||||
val userWallet: UserWallet,
|
||||
override val expected: Network?,
|
||||
) : CreateTestModel
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ internal class DefaultQuotesFetcherTest {
|
|||
@Test
|
||||
fun `fetch if all currencies ids ARE CACHED and EXPIRED`() = runTest {
|
||||
// Arrange
|
||||
val cachedQuote = MockQuoteResponseFactory.createSinglePrice(BigDecimal.ZERO)
|
||||
val cachedQuote = MockQuoteResponseFactory.createSinglePrice(BigDecimal.ONE)
|
||||
val apiQuote = MockQuoteResponseFactory.createSinglePrice(BigDecimal.ONE)
|
||||
val apiResponse = ApiResponse.Success(
|
||||
data = QuotesResponse(quotes = mapOf("ethereum" to apiQuote)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue