diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/models/MarketsListItemUM.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/models/MarketsListItemUM.kt index 9d48452aef..7659617208 100644 --- a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/models/MarketsListItemUM.kt +++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/models/MarketsListItemUM.kt @@ -22,6 +22,7 @@ data class MarketsListItemUM( val isUnder100kMarketCap: Boolean, val stakingRate: TextReference?, val updateTimestamp: Long?, + val networks: List? = null, ) { val chartType: MarketChartLook.Type = when (trendType) { PriceChangeType.UP -> MarketChartLook.Type.Growing @@ -29,6 +30,13 @@ data class MarketsListItemUM( PriceChangeType.NEUTRAL -> MarketChartLook.Type.Neutral } + @Immutable + data class Network( + val networkId: String, + val contractAddress: String?, + val decimalCount: Int?, + ) + @Immutable data class Price( val text: String, diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt index eaeb531130..7b666f4171 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt @@ -18,6 +18,7 @@ interface TangemTechMarketsApi { @Query("order") order: String, @Query("search") search: String?, @Query("timestamp") timestamp: Long?, + @Query("showNetworks") showNetworks: Boolean? = null, ): ApiResponse @GET("v1/coins/{coin_id}") diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt index 31168b8c5b..bd241731d6 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt @@ -27,8 +27,16 @@ data class TokenMarketListResponse( @Json(name = "is_under_market_cap_limit") val isUnderMarketCapLimit: Boolean?, @Json(name = "staking_opportunities") val stakingOpportunities: List?, @Json(name = "max_yield_apy") val maxYieldApy: BigDecimal?, + @Json(name = "networks") val networks: List? = null, ) { + @JsonClass(generateAdapter = true) + data class Network( + @Json(name = "network_id") val networkId: String, + @Json(name = "contract_address") val contractAddress: String?, + @Json(name = "decimal_count") val decimalCount: Int?, + ) + @JsonClass(generateAdapter = true) data class PriceChangePercentage( @Json(name = "24h") val h24: BigDecimal?, diff --git a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt index 834c80a691..12d5b0f694 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt @@ -75,6 +75,7 @@ internal class DefaultMarketsTokenRepository( offset = request.offset, limit = request.limit, timestamp = if (isFirstBatchFetching) null else requestTimeStamp.get(), + showNetworks = request.params.shouldNetworks, ).getOrThrow() } diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt index f43e7ddae1..86b29f8006 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt @@ -42,6 +42,13 @@ internal object TokenMarketListConverter : Converter + TokenMarket.Network( + networkId = network.networkId, + contractAddress = network.contractAddress, + decimalCount = network.decimalCount, + ) + }, ) } return TokenMarketListWithMaxApy(tokens, value.summary?.maxApy) diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt index 3deeee528d..5d6463b790 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt @@ -14,9 +14,16 @@ data class TokenMarket( val tokenCharts: Charts, val yieldRate: BigDecimal?, val updateTimestamp: Long?, + val networks: List?, private val imageHost: String, ) { + data class Network( + val networkId: String, + val contractAddress: String?, + val decimalCount: Int?, + ) + data class Charts( val h24: TokenChart?, val week: TokenChart?, diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt index ffd82b8909..c1a1d9631f 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt @@ -5,6 +5,7 @@ data class TokenMarketListConfig( val searchText: String?, val priceChangeInterval: Interval, val order: Order, + val shouldNetworks: Boolean? = null, ) { enum class Order { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/SwapMarketsListBatchFlowManager.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/SwapMarketsListBatchFlowManager.kt index e25d1bcc4a..2aecafa4e4 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/SwapMarketsListBatchFlowManager.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/SwapMarketsListBatchFlowManager.kt @@ -184,6 +184,7 @@ internal class SwapMarketsListBatchFlowManager( }, priceChangeInterval = TokenMarketListConfig.Interval.H24, order = TokenMarketListConfig.Order.ByRating, + shouldNetworks = true, ), ), ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/converter/SwapMarketsTokenItemConverter.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/converter/SwapMarketsTokenItemConverter.kt index 6ea8ec9f3c..f76ce2af6d 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/converter/SwapMarketsTokenItemConverter.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/market/converter/SwapMarketsTokenItemConverter.kt @@ -44,6 +44,13 @@ internal class SwapMarketsTokenItemConverter( resourceReference(R.string.markets_apy_placeholder, wrappedList(it)) }, updateTimestamp = value.updateTimestamp, + networks = value.networks?.map { network -> + MarketsListItemUM.Network( + networkId = network.networkId, + contractAddress = network.contractAddress, + decimalCount = network.decimalCount, + ) + }, ) } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index 1448ec5de8..35c5fd4fa3 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -43,7 +43,8 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.BlockchainErrorInfo import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase -import com.tangem.domain.markets.GetTokenMarketInfoUseCase +import com.tangem.domain.markets.TokenMarketInfo +import com.tangem.domain.markets.toSerializableParam import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus @@ -73,7 +74,6 @@ import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.feature.swap.analytics.StoriesEvents import com.tangem.feature.swap.analytics.SwapEvents import com.tangem.feature.swap.component.SwapFeeSelectorBlockComponent -import com.tangem.feature.swap.converters.TokenMarketInfoToParamsConverter import com.tangem.feature.swap.domain.SwapInteractor import com.tangem.feature.swap.domain.TransactionFeeResult import com.tangem.feature.swap.domain.TxFeeSealedState @@ -156,7 +156,6 @@ internal class SwapModel @Inject constructor( private val getMarketsTokenListFlowUseCase: GetMarketsTokenListFlowUseCase, swapFeatureToggles: SwapFeatureToggles, private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory, - private val getTokenMarketInfoUseCase: GetTokenMarketInfoUseCase, private val excludedBlockchains: ExcludedBlockchains, private val getUserWalletsUseCase: GetWalletsUseCase, private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase, @@ -2061,23 +2060,25 @@ internal class SwapModel @Inject constructor( private fun addToPortfolioItem(item: MarketsListItemUM) { modelScope.launch { - val tokenInfo = getTokenMarketInfoUseCase( - selectedAppCurrencyFlow.value, - item.id, - item.currencySymbol, - ).getOrNull() ?: return@launch + val tokenMarket = searchMarketsListManager.getTokenMarketById(item.id) ?: return@launch - val converter = TokenMarketInfoToParamsConverter() - val param = converter.convert(tokenInfo) + val param = tokenMarket.toSerializableParam() val hasOnlyHotWallets = getUserWalletsUseCase.invokeSync().all { it is UserWallet.Hot } - val networks = tokenInfo.networks?.filter { network -> + val networks = tokenMarket.networks?.filter { network -> BlockchainUtils.isSupportedNetworkId( blockchainId = network.networkId, excludedBlockchains = excludedBlockchains, hotExcludedBlockchains = hotWalletExcludedBlockchains, hasOnlyHotWallets = hasOnlyHotWallets, ) + }?.map { network -> + TokenMarketInfo.Network( + networkId = network.networkId, + isExchangeable = false, + contractAddress = network.contractAddress, + decimalCount = network.decimalCount, + ) }.orEmpty() addToPortfolioManager = addToPortfolioManagerFactory diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/SwapMarketsListBatchFlowManager.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/SwapMarketsListBatchFlowManager.kt index 3e7b9af39f..e8331efed3 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/SwapMarketsListBatchFlowManager.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/SwapMarketsListBatchFlowManager.kt @@ -184,6 +184,7 @@ internal class SwapMarketsListBatchFlowManager( }, priceChangeInterval = TokenMarketListConfig.Interval.H24, order = TokenMarketListConfig.Order.ByRating, + shouldNetworks = true, ), ), ) @@ -236,6 +237,13 @@ internal class SwapMarketsListBatchFlowManager( .toSet() } + fun getTokenMarketById(id: CryptoCurrency.RawID): TokenMarket? { + return batchFlow.state.value.data + .asSequence() + .flatMap { it.data } + .firstOrNull { it.id == id } + } + private data class ResultBatches( val uiBatches: List>> = emptyList(), val processedItems: List>>? = null, diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/converter/SwapMarketsTokenItemConverter.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/converter/SwapMarketsTokenItemConverter.kt index 78c52b2aab..31ea67416e 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/converter/SwapMarketsTokenItemConverter.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/market/converter/SwapMarketsTokenItemConverter.kt @@ -44,6 +44,13 @@ internal class SwapMarketsTokenItemConverter( resourceReference(R.string.markets_apy_placeholder, wrappedList(it)) }, updateTimestamp = value.updateTimestamp, + networks = value.networks?.map { network -> + MarketsListItemUM.Network( + networkId = network.networkId, + contractAddress = network.contractAddress, + decimalCount = network.decimalCount, + ) + }, ) }