Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-12 12:04:51 +03:00
parent 27ae1ee2a0
commit 1f3f592cee
8 changed files with 58 additions and 37 deletions

View file

@ -1,6 +1,7 @@
package com.tangem.data.managetokens package com.tangem.data.managetokens
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.compatibility.l2BlockchainsCoinIds
import com.tangem.blockchainsdk.utils.isSupportedInApp import com.tangem.blockchainsdk.utils.isSupportedInApp
import com.tangem.blockchainsdk.utils.toNetworkId import com.tangem.blockchainsdk.utils.toNetworkId
import com.tangem.data.common.currency.getBlockchain import com.tangem.data.common.currency.getBlockchain
@ -86,6 +87,10 @@ internal class DefaultManageTokensRepository(
} else { } else {
retryOnError(call = call) retryOnError(call = call)
} }
// filter l2 coins
val updatedCoinsResponse = coinsResponse.copy(
coins = coinsResponse.coins.filterNot { l2BlockchainsCoinIds.contains(it.id) },
)
val tokensResponse = request.params.userWalletId?.let { getSavedUserTokensResponseSync(it) } val tokensResponse = request.params.userWalletId?.let { getSavedUserTokensResponseSync(it) }
val items = if (isFirstBatchFetching && val items = if (isFirstBatchFetching &&
@ -94,13 +99,13 @@ internal class DefaultManageTokensRepository(
request.params.searchText.isNullOrBlank() request.params.searchText.isNullOrBlank()
) { ) {
managedCryptoCurrencyFactory.createWithCustomTokens( managedCryptoCurrencyFactory.createWithCustomTokens(
coinsResponse = coinsResponse, coinsResponse = updatedCoinsResponse,
tokensResponse = tokensResponse, tokensResponse = tokensResponse,
derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider, derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider,
) )
} else { } else {
managedCryptoCurrencyFactory.create( managedCryptoCurrencyFactory.create(
coinsResponse = coinsResponse, coinsResponse = updatedCoinsResponse,
tokensResponse = tokensResponse, tokensResponse = tokensResponse,
derivationStyleProvider = userWallet?.scanResponse?.derivationStyleProvider, derivationStyleProvider = userWallet?.scanResponse?.derivationStyleProvider,
) )

View file

@ -2,6 +2,7 @@ package com.tangem.data.markets
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.compatibility.applyL2Compatibility import com.tangem.blockchainsdk.compatibility.applyL2Compatibility
import com.tangem.blockchainsdk.compatibility.getTokenIdIfL2Network
import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.data.common.currency.getNetwork import com.tangem.data.common.currency.getNetwork
@ -109,9 +110,10 @@ internal class DefaultMarketsTokenRepository(
interval: PriceChangeInterval, interval: PriceChangeInterval,
tokenId: String, tokenId: String,
): TokenChart { ): TokenChart {
val mappedTokenId = getTokenIdIfL2Network(tokenId)
val response = marketsApi.getCoinChart( val response = marketsApi.getCoinChart(
currency = fiatCurrencyCode, currency = fiatCurrencyCode,
coinId = tokenId, coinId = mappedTokenId,
interval = interval.toRequestParam(), interval = interval.toRequestParam(),
) )
@ -123,13 +125,14 @@ internal class DefaultMarketsTokenRepository(
interval: PriceChangeInterval, interval: PriceChangeInterval,
tokenId: String, tokenId: String,
): TokenChart { ): TokenChart {
val mappedTokenId = getTokenIdIfL2Network(tokenId)
val response = marketsApi.getCoinsListCharts( val response = marketsApi.getCoinsListCharts(
coinIds = tokenId, coinIds = mappedTokenId,
currency = fiatCurrencyCode, currency = fiatCurrencyCode,
interval = interval.toRequestParam(), interval = interval.toRequestParam(),
) )
val chart = response.getOrThrow()[tokenId] ?: error("No chart preview data for token $tokenId") val chart = response.getOrThrow()[mappedTokenId] ?: error("No chart preview data for token $mappedTokenId")
return TokenChartConverter.convert(interval, chart) return TokenChartConverter.convert(interval, chart)
} }

View file

@ -1,6 +1,7 @@
package com.tangem.data.tokens.utils package com.tangem.data.tokens.utils
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.compatibility.l2BlockchainsCoinIds
import com.tangem.blockchainsdk.utils.toCoinId import com.tangem.blockchainsdk.utils.toCoinId
import com.tangem.datasource.api.tangemTech.models.QuotesResponse import com.tangem.datasource.api.tangemTech.models.QuotesResponse
@ -51,16 +52,6 @@ internal class QuotesUnsupportedCurrenciesIdAdapter {
* Map that contains unsupported currencies and their replacement for request * Map that contains unsupported currencies and their replacement for request
*/ */
private val ethCoinId = Blockchain.Ethereum.toCoinId() private val ethCoinId = Blockchain.Ethereum.toCoinId()
private val UNSUPPORTED_IDS_WITH_REPLACEMENTS = mapOf( private val UNSUPPORTED_IDS_WITH_REPLACEMENTS = l2BlockchainsCoinIds.associateWith { ethCoinId }
Blockchain.Optimism.toCoinId() to ethCoinId,
Blockchain.Arbitrum.toCoinId() to ethCoinId,
Blockchain.ZkSyncEra.toCoinId() to ethCoinId,
Blockchain.Manta.toCoinId() to ethCoinId,
Blockchain.PolygonZkEVM.toCoinId() to ethCoinId,
Blockchain.Aurora.toCoinId() to ethCoinId,
Blockchain.Base.toCoinId() to ethCoinId,
Blockchain.Blast.toCoinId() to ethCoinId,
Blockchain.Cyber.toCoinId() to ethCoinId,
)
} }
} }

View file

@ -69,4 +69,5 @@ dependencies {
/* Libs */ /* Libs */
implementation(projects.libs.crypto) implementation(projects.libs.crypto)
implementation(projects.libs.blockchainSdk)
} }

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.lifecycle.compose.LifecycleStartEffect import androidx.lifecycle.compose.LifecycleStartEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.blockchainsdk.compatibility.getTokenIdIfL2Network
import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.decompose.model.getOrCreateModel
@ -31,12 +32,18 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
portfolioComponentFactory: MarketsPortfolioComponent.Factory, portfolioComponentFactory: MarketsPortfolioComponent.Factory,
) : AppComponentContext by appComponentContext, MarketsTokenDetailsComponent { ) : AppComponentContext by appComponentContext, MarketsTokenDetailsComponent {
private val model: MarketsTokenDetailsModel = getOrCreateModel(params) // applying l2 compatibility
private val updatedParams = params.copy(
token = params.token.copy(
id = getTokenIdIfL2Network(params.token.id),
),
)
private val model: MarketsTokenDetailsModel = getOrCreateModel(updatedParams)
private val portfolioComponent: MarketsPortfolioComponent? = if (params.showPortfolio) { private val portfolioComponent: MarketsPortfolioComponent? = if (updatedParams.showPortfolio) {
portfolioComponentFactory.create( portfolioComponentFactory.create(
context = child("my_portfolio"), context = child("my_portfolio"),
params = MarketsPortfolioComponent.Params(params.token), params = MarketsPortfolioComponent.Params(updatedParams.token),
) )
} else { } else {
null null

View file

@ -14,7 +14,10 @@ import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.markets.* import com.tangem.domain.markets.GetCurrencyQuotesUseCase
import com.tangem.domain.markets.GetTokenPriceChartUseCase
import com.tangem.domain.markets.PriceChangeInterval
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.features.markets.token.block.TokenMarketBlockComponent import com.tangem.features.markets.token.block.TokenMarketBlockComponent
import com.tangem.features.markets.token.block.impl.ui.state.TokenMarketBlockUM import com.tangem.features.markets.token.block.impl.ui.state.TokenMarketBlockUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider

View file

@ -386,20 +386,21 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
val rawId = cryptoCurrencyStatus.currency.id.rawCurrencyId ?: return@launch val rawId = cryptoCurrencyStatus.currency.id.rawCurrencyId ?: return@launch
val tokenMarketParams = TokenMarketParams(
id = rawId,
name = cryptoCurrencyStatus.currency.name,
symbol = cryptoCurrencyStatus.currency.symbol,
tokenQuotes = TokenMarketParams.Quotes(
currentPrice = cryptoCurrencyStatus.value.fiatRate ?: BigDecimal.ZERO,
h24Percent = cryptoCurrencyStatus.value.priceChange,
weekPercent = null,
monthPercent = null,
),
imageUrl = cryptoCurrencyStatus.currency.iconUrl,
)
appRouter.push( appRouter.push(
AppRoute.MarketsTokenDetails( AppRoute.MarketsTokenDetails(
TokenMarketParams( token = tokenMarketParams,
id = rawId,
name = cryptoCurrencyStatus.currency.name,
symbol = cryptoCurrencyStatus.currency.symbol,
tokenQuotes = TokenMarketParams.Quotes(
currentPrice = cryptoCurrencyStatus.value.fiatRate ?: BigDecimal.ZERO,
h24Percent = cryptoCurrencyStatus.value.priceChange,
weekPercent = null,
monthPercent = null,
),
imageUrl = cryptoCurrencyStatus.currency.iconUrl,
),
appCurrency = getSelectedAppCurrencyUseCase.unwrap(), appCurrency = getSelectedAppCurrencyUseCase.unwrap(),
showPortfolio = true, showPortfolio = true,
), ),

View file

@ -7,7 +7,7 @@ import com.tangem.datasource.api.markets.models.response.TokenMarketInfoResponse
import com.tangem.datasource.api.tangemTech.models.CoinsResponse import com.tangem.datasource.api.tangemTech.models.CoinsResponse
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
val l2NetworksList = listOf( internal val l2BlockchainsList = listOf(
Blockchain.Optimism, Blockchain.Optimism,
Blockchain.Arbitrum, Blockchain.Arbitrum,
Blockchain.ZkSyncEra, Blockchain.ZkSyncEra,
@ -19,9 +19,13 @@ val l2NetworksList = listOf(
Blockchain.Cyber, Blockchain.Cyber,
) )
val l2BlockchainsCoinIds = l2BlockchainsList.map { it.toCoinId() }
val ETHEREUM_COIN_ID = Blockchain.Ethereum.toCoinId()
fun getL2CompatibilityTokenComparison(token: UserTokensResponse.Token, currencyId: String): Boolean { fun getL2CompatibilityTokenComparison(token: UserTokensResponse.Token, currencyId: String): Boolean {
return if (currencyId == ETHEREUM_COIN_ID) { return if (currencyId == ETHEREUM_COIN_ID) {
l2NetworksList.map { it.toCoinId() }.contains(token.id) || currencyId == token.id l2BlockchainsCoinIds.contains(token.id) || currencyId == token.id
} else { } else {
token.id == currencyId token.id == currencyId
} }
@ -29,7 +33,7 @@ fun getL2CompatibilityTokenComparison(token: UserTokensResponse.Token, currencyI
fun List<CoinsResponse.Coin.Network>.applyL2Compatibility(coinId: String): List<CoinsResponse.Coin.Network> { fun List<CoinsResponse.Coin.Network>.applyL2Compatibility(coinId: String): List<CoinsResponse.Coin.Network> {
return if (coinId == ETHEREUM_COIN_ID) { return if (coinId == ETHEREUM_COIN_ID) {
val l2Networks = l2NetworksList.map { val l2Networks = l2BlockchainsList.map {
CoinsResponse.Coin.Network( CoinsResponse.Coin.Network(
networkId = it.toNetworkId(), networkId = it.toNetworkId(),
) )
@ -43,7 +47,7 @@ fun List<CoinsResponse.Coin.Network>.applyL2Compatibility(coinId: String): List<
fun TokenMarketInfoResponse.applyL2Compatibility(coinId: String): TokenMarketInfoResponse { fun TokenMarketInfoResponse.applyL2Compatibility(coinId: String): TokenMarketInfoResponse {
val networks = this.networks ?: return this val networks = this.networks ?: return this
return if (coinId == ETHEREUM_COIN_ID) { return if (coinId == ETHEREUM_COIN_ID) {
val l2Networks = l2NetworksList.map { val l2Networks = l2BlockchainsList.map {
TokenMarketInfoResponse.Network( TokenMarketInfoResponse.Network(
networkId = it.toNetworkId(), networkId = it.toNetworkId(),
contractAddress = null, contractAddress = null,
@ -56,4 +60,10 @@ fun TokenMarketInfoResponse.applyL2Compatibility(coinId: String): TokenMarketInf
} }
} }
const val ETHEREUM_COIN_ID = "ethereum" fun getTokenIdIfL2Network(tokenId: String): String {
return if (l2BlockchainsCoinIds.contains(tokenId)) {
ETHEREUM_COIN_ID
} else {
tokenId
}
}