From 5883823eb348212ba7471f19b158dbd772e21ea0 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 3 Feb 2025 12:24:11 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../hotcrypto/DefaultHotCryptoLoader.kt | 2 +- .../local/quote/DefaultQuotesStore.kt | 14 +--- .../datasource/local/quote/QuotesStore.kt | 4 +- .../common/currency/CryptoCurrencyFactory.kt | 4 +- .../data/common/currency/TokensOperations.kt | 19 +++-- .../currency/UserTokensResponseFactory.kt | 2 +- .../DefaultCustomTokensRepository.kt | 4 +- .../utils/ManagedCryptoCurrencyFactory.kt | 7 +- data/markets/build.gradle.kts | 1 + .../markets/DefaultMarketsTokenRepository.kt | 22 ++--- .../converters/TokenMarketChartsConverter.kt | 5 +- .../converters/TokenMarketListConverter.kt | 3 +- .../converters/TokenQuotesShortConverter.kt | 5 +- .../converters/HotCryptoCurrencyConverter.kt | 2 +- .../data/staking/DefaultStakingRepository.kt | 4 +- .../data/tokens/paging/CoinsPagingSource.kt | 82 ------------------- .../tokens/paging/CoinsResponseConverter.kt | 52 ------------ .../repository/DefaultCurrenciesRepository.kt | 6 +- .../repository/DefaultQuotesRepository.kt | 31 +++---- .../data/tokens/utils/QuotesConverter.kt | 8 +- .../DefaultWalletManagersFacade.kt | 4 +- .../model/CryptoCurrencyAmount.kt | 3 +- .../utils/CryptoCurrencyTypeConverter.kt | 2 +- .../walletmanager/utils/SdkTokenConverter.kt | 2 +- .../utils/UpdateWalletManagerResultFactory.kt | 9 +- .../managetokens/SaveManagedTokensUseCase.kt | 2 +- .../repository/CustomTokensRepository.kt | 2 +- domain/markets/models/build.gradle.kts | 1 + .../com/tangem/domain/markets/TokenMarket.kt | 3 +- .../domain/markets/TokenMarketParams.kt | 3 +- .../markets/GetCurrencyQuotesUseCase.kt | 4 +- .../markets/GetTokenExchangesUseCase.kt | 3 +- .../markets/GetTokenFullQuotesUseCase.kt | 3 +- .../markets/GetTokenMarketInfoUseCase.kt | 3 +- .../markets/GetTokenPriceChartUseCase.kt | 3 +- .../repositories/MarketsTokenRepository.kt | 14 ++-- .../domain/staking/model/stakekit/Yield.kt | 2 - .../domain/tokens/model/CryptoCurrency.kt | 12 ++- .../com/tangem/domain/tokens/model/Quote.kt | 8 +- .../tokens/model/staking/YieldExtentions.kt | 7 ++ .../tokens/FetchCardTokenListUseCase.kt | 4 +- .../tokens/FetchCurrencyStatusUseCase.kt | 2 +- .../domain/tokens/FetchTokenListUseCase.kt | 5 +- ...AllWalletsCryptoCurrencyStatusesUseCase.kt | 2 +- ...RefreshMultiCurrencyWalletQuotesUseCase.kt | 2 +- .../CurrenciesStatusesLceOperations.kt | 2 +- .../CurrenciesStatusesOperations.kt | 19 +++-- .../operations/CurrencyStatusOperations.kt | 2 +- .../tokens/repository/CurrenciesRepository.kt | 2 +- .../tokens/repository/QuotesRepository.kt | 8 +- .../tangem/domain/tokens/mock/MockQuotes.kt | 6 +- .../repository/MockCurrenciesRepository.kt | 4 +- .../tokens/repository/MockQuotesRepository.kt | 10 +-- .../DefaultMarketsTokenDetailsComponent.kt | 3 +- .../impl/model/MarketsTokenDetailsModel.kt | 2 +- .../impl/loader/PortfolioDataLoader.kt | 5 +- .../impl/model/SelectNetworkUMConverter.kt | 2 +- .../tokenlist/impl/model/MarketsListModel.kt | 7 +- .../MarketsListBatchFlowManager.kt | 5 +- .../statemanager/MarketsListUMStateManager.kt | 5 +- .../markets/tokenlist/impl/ui/MarketsList.kt | 3 +- .../ui/components/MarketsListLazyColumn.kt | 4 +- .../MarketChartListItemPreviewDataProvider.kt | 13 +-- .../impl/ui/state/MarketsListItemUM.kt | 3 +- .../tokenlist/impl/ui/state/MarketsListUM.kt | 3 +- .../presentation/state/fee/FeeStateFactory.kt | 2 +- .../RewardsValidatorStateConverter.kt | 2 +- .../helpers/StakingFeeTransactionLoader.kt | 1 + .../state/helpers/StakingTransactionSender.kt | 1 + .../feature/swap/domain/SwapInteractorImpl.kt | 7 +- .../factory/express/ExchangeStatusFactory.kt | 3 +- 71 files changed, 221 insertions(+), 285 deletions(-) delete mode 100644 data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsPagingSource.kt delete mode 100644 data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsResponseConverter.kt create mode 100644 domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/staking/YieldExtentions.kt diff --git a/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/hotcrypto/DefaultHotCryptoLoader.kt b/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/hotcrypto/DefaultHotCryptoLoader.kt index 4a8260bf8d..6ca3229ae4 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/hotcrypto/DefaultHotCryptoLoader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/hotcrypto/DefaultHotCryptoLoader.kt @@ -46,7 +46,7 @@ internal class DefaultHotCryptoLoader @Inject constructor( override suspend fun update(currencies: List) { updateInternal { hotToken -> currencies.none { - it.id.rawCurrencyId == hotToken.id && + it.id.rawCurrencyId?.value == hotToken.id && (it as? CryptoCurrency.Token)?.contractAddress == hotToken.contractAddress && it.network.id.value == hotToken.networkId } diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt index fc0d1e0e42..962b4afddd 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt @@ -11,11 +11,9 @@ internal class DefaultQuotesStore( private val dataStore: StringKeyDataStore, ) : QuotesStore { - override fun get(currenciesIds: Set): Flow> { + override fun get(currenciesIds: Set): Flow> { return channelFlow { - val flows = currenciesIds.mapNotNull { currencyId -> - currencyId.rawCurrencyId?.let(dataStore::get) - } + val flows = currenciesIds.map { currencyId -> dataStore.get(currencyId.value) } if (dataStore.isEmpty() || flows.isEmpty()) { send(emptySet()) @@ -30,12 +28,8 @@ internal class DefaultQuotesStore( } } - override suspend fun getSync(currenciesIds: Set): Set { - return currenciesIds.mapNotNull { currencyId -> - currencyId.rawCurrencyId?.let { - dataStore.getSyncOrNull(it) - } - }.toSet() + override suspend fun getSync(currenciesIds: Set): Set { + return currenciesIds.mapNotNull { currencyId -> dataStore.getSyncOrNull(currencyId.value) }.toSet() } override suspend fun store(response: QuotesResponse) { diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt index dd3f577782..38f90100e4 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt @@ -7,9 +7,9 @@ import kotlinx.coroutines.flow.Flow interface QuotesStore { - fun get(currenciesIds: Set): Flow> + fun get(currenciesIds: Set): Flow> - suspend fun getSync(currenciesIds: Set): Set + suspend fun getSync(currenciesIds: Set): Set suspend fun store(response: QuotesResponse) } \ No newline at end of file diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/CryptoCurrencyFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/CryptoCurrencyFactory.kt index 7b9c905f0d..35efb1a541 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/CryptoCurrencyFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/CryptoCurrencyFactory.kt @@ -18,7 +18,7 @@ class CryptoCurrencyFactory( @Suppress("LongParameterList") // Yep, it's long fun createToken( network: Network, - rawId: String?, + rawId: CryptoCurrency.RawID?, name: String, symbol: String, decimals: Int, @@ -125,7 +125,7 @@ class CryptoCurrencyFactory( symbol = cryptoCurrency.symbol, contractAddress = cryptoCurrency.contractAddress, decimals = cryptoCurrency.decimals, - id = cryptoCurrency.id.rawCurrencyId, + id = cryptoCurrency.id.rawCurrencyId?.value, ) val blockchain = Blockchain.fromNetworkId(cryptoCurrency.network.backendId) ?: Blockchain.Unknown val id = getTokenId(network, sdkToken) diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/TokensOperations.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/TokensOperations.kt index 724649c959..e2cfb5809b 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/TokensOperations.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/TokensOperations.kt @@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.IconsUtil import com.tangem.blockchainsdk.utils.toCoinId import com.tangem.datasource.api.tangemTech.models.UserTokensResponse +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrency.ID import com.tangem.domain.tokens.model.Network import com.tangem.blockchain.common.Token as SdkToken @@ -31,15 +32,16 @@ fun getCoinId(network: Network, coinId: String): ID { fun getTokenId(network: Network, sdkToken: SdkToken): ID { val sdkTokenId = sdkToken.id + val tokenId = sdkTokenId?.let { CryptoCurrency.RawID(it) } - return getTokenId(network, sdkTokenId, sdkToken.contractAddress) + return getTokenId(network, tokenId, sdkToken.contractAddress) } -fun getTokenId(network: Network, rawTokenId: String?, contractAddress: String): ID { +fun getTokenId(network: Network, rawTokenId: CryptoCurrency.RawID?, contractAddress: String): ID { val suffix = if (rawTokenId == null) { CustomCurrencyIdSuffix(contractAddress) } else { - CurrencyIdSuffix(rawTokenId, contractAddress) + CurrencyIdSuffix(rawTokenId.value, contractAddress) } return ID(TOKEN_ID_PREFIX, getCurrencyIdBody(network), suffix) @@ -47,11 +49,12 @@ fun getTokenId(network: Network, rawTokenId: String?, contractAddress: String): fun getTokenIconUrl(blockchain: Blockchain, token: SdkToken): String? { val tokenId = token.id + val rawID = tokenId?.let { CryptoCurrency.RawID(it) } - return if (tokenId == null) { + return if (rawID == null) { IconsUtil.getTokenIconUri(blockchain, token)?.toString() } else { - getTokenIconUrlFromDefaultHost(tokenId) + getTokenIconUrlFromDefaultHost(rawID) } } @@ -59,7 +62,7 @@ fun getCoinIconUrl(blockchain: Blockchain): String? { val coinId = when (blockchain) { Blockchain.Unknown -> null else -> blockchain.toCoinId() - } + }?.let { CryptoCurrency.RawID(it) } return coinId?.let(::getTokenIconUrlFromDefaultHost) } @@ -84,13 +87,13 @@ private fun getCurrencyIdBody(network: Network): CurrencyIdBody { } } -fun getTokenIconUrlFromDefaultHost(tokenId: String): String { +fun getTokenIconUrlFromDefaultHost(tokenId: CryptoCurrency.RawID): String { return buildString { append(DEFAULT_TOKENS_ICONS_HOST) append('/') append(TOKEN_ICON_SIZE) append('/') - append(tokenId) + append(tokenId.value) append('.') append(TOKEN_ICON_EXT) } diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensResponseFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensResponseFactory.kt index 4ba8bbd2a2..b01f5114ad 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensResponseFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensResponseFactory.kt @@ -30,7 +30,7 @@ class UserTokensResponseFactory { val blockchain = getBlockchain(currency.network.id) return UserTokensResponse.Token( - id = currency.id.rawCurrencyId, + id = currency.id.rawCurrencyId?.value, networkId = blockchain.toNetworkId(), derivationPath = currency.network.derivationPath.value, name = currency.name, diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt index e146654abd..6c9f005ae9 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt @@ -122,7 +122,7 @@ internal class DefaultCustomTokensRepository( if (coinNetwork != null) { cryptoCurrencyFactory.createToken( network = network, - rawId = coin.id, + rawId = CryptoCurrency.RawID(coin.id), name = coin.name, symbol = coin.symbol, decimals = coinNetwork.decimalCount!!.toInt(), @@ -154,7 +154,7 @@ internal class DefaultCustomTokensRepository( override suspend fun createToken( managedCryptoCurrency: ManagedCryptoCurrency.Token, sourceNetwork: ManagedCryptoCurrency.SourceNetwork.Default, - rawId: String?, + rawId: CryptoCurrency.RawID?, ): CryptoCurrency.Token { return cryptoCurrencyFactory.createToken( network = sourceNetwork.network, diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt index 5ac35825b0..98ccc3e720 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt @@ -20,6 +20,7 @@ import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.model.ManagedCryptoCurrency.SourceNetwork import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network internal class ManagedCryptoCurrencyFactory( @@ -114,7 +115,11 @@ internal class ManagedCryptoCurrencyFactory( ) } else { ManagedCryptoCurrency.Custom.Token( - currencyId = getTokenId(network, token.id, contractAddress), + currencyId = getTokenId( + network = network, + rawTokenId = token.id?.let { CryptoCurrency.RawID(it) }, + contractAddress = contractAddress, + ), name = token.name, symbol = token.symbol, iconUrl = token.id?.let { getIconUrl(it) }, diff --git a/data/markets/build.gradle.kts b/data/markets/build.gradle.kts index e52469954f..9e8f4d07a7 100644 --- a/data/markets/build.gradle.kts +++ b/data/markets/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { implementation(projects.domain.markets) implementation(projects.domain.models) implementation(projects.domain.tokens.models) + implementation(projects.domain.tokens) implementation(projects.data.common) 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 4159ad1c21..4b2f305bcf 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 @@ -125,10 +125,10 @@ internal class DefaultMarketsTokenRepository( override suspend fun getChart( fiatCurrencyCode: String, interval: PriceChangeInterval, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ) = withContext(dispatcherProvider.io) { - val mappedTokenId = getTokenIdIfL2Network(tokenId) + val mappedTokenId = getTokenIdIfL2Network(tokenId.value) val response = marketsApi.getCoinChart( currency = fiatCurrencyCode, coinId = mappedTokenId, @@ -161,10 +161,10 @@ internal class DefaultMarketsTokenRepository( override suspend fun getChartPreview( fiatCurrencyCode: String, interval: PriceChangeInterval, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ) = withContext(dispatcherProvider.io) { - val mappedTokenId = getTokenIdIfL2Network(tokenId) + val mappedTokenId = getTokenIdIfL2Network(tokenId.value) val chart = catchListErrorAndSendEvent { marketsApi.getCoinsListCharts( @@ -193,7 +193,7 @@ internal class DefaultMarketsTokenRepository( override suspend fun getTokenInfo( fiatCurrencyCode: String, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, languageCode: String, ) = withContext(dispatcherProvider.io) { @@ -203,16 +203,16 @@ internal class DefaultMarketsTokenRepository( ) { marketsApi.getCoinMarketData( currency = fiatCurrencyCode, - coinId = tokenId, + coinId = tokenId.value, language = languageCode, ).getOrThrow() } - val resultResponse = result.applyL2Compatibility(tokenId) + val resultResponse = result.applyL2Compatibility(tokenId.value) return@withContext tokenMarketInfoConverter.convert(resultResponse) } - override suspend fun getTokenQuotes(fiatCurrencyCode: String, tokenId: String, tokenSymbol: String) = + override suspend fun getTokenQuotes(fiatCurrencyCode: String, tokenId: CryptoCurrency.RawID, tokenSymbol: String) = withContext(dispatcherProvider.io) { // for second markets iteration we should use extended api method with all required fields @@ -222,7 +222,7 @@ internal class DefaultMarketsTokenRepository( ) { tangemTechApi.getQuotes( currencyId = fiatCurrencyCode, - coinIds = tokenId, + coinIds = tokenId.value, fields = marketsQuoteFields.joinToString(separator = ","), ).getOrThrow() } @@ -263,10 +263,10 @@ internal class DefaultMarketsTokenRepository( } } - override suspend fun getTokenExchanges(tokenId: String): List { + override suspend fun getTokenExchanges(tokenId: CryptoCurrency.RawID): List { return withContext(dispatcherProvider.io) { cacheRegistry.invokeOnExpire(key = "coins/$tokenId/exchanges", skipCache = false) { - val response = marketsApi.getCoinExchanges(coinId = tokenId).getOrThrow() + val response = marketsApi.getCoinExchanges(coinId = tokenId.value).getOrThrow() tokenExchangesStore.store(value = response.exchanges) } diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketChartsConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketChartsConverter.kt index fdd44ffba9..e426157da0 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketChartsConverter.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketChartsConverter.kt @@ -4,16 +4,17 @@ import com.tangem.datasource.api.markets.models.response.TokenMarketChartListRes import com.tangem.domain.markets.PriceChangeInterval import com.tangem.domain.markets.TokenMarket import com.tangem.domain.markets.TokenMarketListConfig +import com.tangem.domain.tokens.model.CryptoCurrency internal object TokenMarketChartsConverter { fun convert( chartsToCopy: TokenMarket.Charts, - tokenId: String, + tokenId: CryptoCurrency.RawID, interval: TokenMarketListConfig.Interval, value: TokenMarketChartListResponse, ): TokenMarket.Charts { - val prices = requireNotNull(value[tokenId]) { + val prices = requireNotNull(value[tokenId.value]) { "$tokenId is not found in the response. This shouldn't have happened." } return when (interval) { 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 c4836449f3..38d39f1843 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 @@ -3,6 +3,7 @@ package com.tangem.data.markets.converters import com.tangem.datasource.api.markets.models.response.TokenMarketListResponse import com.tangem.domain.markets.TokenMarket import com.tangem.domain.markets.TokenQuotesShort +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.utils.converter.Converter internal object TokenMarketListConverter : Converter> { @@ -18,7 +19,7 @@ internal object TokenMarketListConverter : Converter TokenMarket( - id = token.id, + id = CryptoCurrency.RawID(token.id), name = token.name, symbol = token.symbol, marketRating = token.marketRating, diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenQuotesShortConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenQuotesShortConverter.kt index 2bc1c6933c..c3c78e5dfb 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenQuotesShortConverter.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenQuotesShortConverter.kt @@ -2,12 +2,13 @@ package com.tangem.data.markets.converters import com.tangem.datasource.api.tangemTech.models.QuotesResponse import com.tangem.domain.markets.TokenQuotesShort +import com.tangem.domain.tokens.model.CryptoCurrency import java.math.BigDecimal internal object TokenQuotesShortConverter { - fun convert(tokenId: String, value: QuotesResponse): TokenQuotesShort { - val quote = requireNotNull(value.quotes[tokenId]) { + fun convert(tokenId: CryptoCurrency.RawID, value: QuotesResponse): TokenQuotesShort { + val quote = requireNotNull(value.quotes[tokenId.value]) { "$tokenId is not found in the response. This shouldn't have happened." } return TokenQuotesShort( diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt b/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt index 1742009b08..884f659b20 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt @@ -37,7 +37,7 @@ internal class HotCryptoCurrencyConverter( val currency = if (contractAddress != null && decimals != null) { cryptoCurrencyFactory.createToken( network = network, - rawId = value.id, + rawId = CryptoCurrency.RawID(value.id), name = value.name, symbol = value.symbol, decimals = decimals, diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index f2f8cf8090..93b0908573 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -579,9 +579,9 @@ internal class DefaultStakingRepository( } } - private fun findPrefetchedYield(yields: List, currencyId: String, symbol: String): Yield? { + private fun findPrefetchedYield(yields: List, currencyId: CryptoCurrency.RawID, symbol: String): Yield? { return yields.find { yield -> - yield.tokens.any { it.coinGeckoId == currencyId && it.symbol == symbol } + yield.tokens.any { it.coinGeckoId == currencyId.value && it.symbol == symbol } } } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsPagingSource.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsPagingSource.kt deleted file mode 100644 index 9cf7b0092c..0000000000 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsPagingSource.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.data.tokens.paging - -import androidx.paging.PagingSource -import androidx.paging.PagingState -import com.tangem.datasource.api.common.response.getOrThrow -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.api.tangemTech.models.CoinsResponse -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.tokens.model.Quote -import com.tangem.domain.tokens.model.Token -import com.tangem.domain.tokens.repository.QuotesRepository -import com.tangem.utils.coroutines.CoroutineDispatcherProvider - -/** - * A PagingSource responsible for retrieving tokens from the Tangem Tech API and adding to them quotes information. - * - * @property api Tangem Tech API - * @property quotesRepository Repository providing quotes data. - * @property dispatchers Coroutine dispatchers provider. - * @property searchText The search text used to filter tokens. - */ -internal class CoinsPagingSource( - private val api: TangemTechApi, - private val quotesRepository: QuotesRepository, - private val dispatchers: CoroutineDispatcherProvider, - private val searchText: String?, -) : PagingSource() { - - override fun getRefreshKey(state: PagingState): Int? { - return state.anchorPosition?.let { anchorPosition -> - state.closestPageToPosition(anchorPosition)?.prevKey?.plus(other = 1) - ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(other = 1) - } - } - - override suspend fun load(params: LoadParams): LoadResult { - val page = params.key ?: 0 - - return com.tangem.utils.coroutines.runCatching(dispatchers.io) { - api.getCoins( - active = true, // TODO change when voting functionality is implemented - searchText = searchText, - offset = page * params.loadSize, - limit = params.loadSize, - ).getOrThrow() - }.fold( - onSuccess = { response -> - val coinsIds = response.coins.map { coin -> - CryptoCurrency.ID( - prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX, - body = CryptoCurrency.ID.Body.NetworkId(coin.id), - suffix = CryptoCurrency.ID.Suffix.RawID(coin.id), - ) - } - - try { - val quotes = quotesRepository.getQuotesSync(currenciesIds = coinsIds.toSet(), refresh = false) - LoadResult.Page( - data = CoinsResponseConverter.convert( - CoinsData( - response.coins, - response.imageHost, - quotes, - ), - ), - prevKey = if (page == 0) null else page.minus(other = 1), - nextKey = if (response.coins.isEmpty()) null else page.plus(other = 1), - ) - } catch (t: Throwable) { - LoadResult.Error(t) - } - }, - onFailure = { LoadResult.Error(it) }, - ) - } -} - -data class CoinsData( - val coins: List, - val imageHost: String?, - val quotes: Set, -) \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsResponseConverter.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsResponseConverter.kt deleted file mode 100644 index c2b2108053..0000000000 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/paging/CoinsResponseConverter.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.tangem.data.tokens.paging - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.data.common.currency.getNetworkStandardType -import com.tangem.datasource.api.tangemTech.models.CoinsResponse -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.tokens.model.Token -import com.tangem.utils.converter.Converter - -/** - * Converter from data model [CoinsResponse] to list of domain models [Token] - */ -internal object CoinsResponseConverter : Converter> { - - override fun convert(value: CoinsData): List { - return value.coins.map { coin -> - val id = CryptoCurrency.ID( - CryptoCurrency.ID.Prefix.TOKEN_PREFIX, - CryptoCurrency.ID.Body.NetworkId(coin.id), - CryptoCurrency.ID.Suffix.RawID(coin.id), - ) - val quote = value.quotes.find { it.rawCurrencyId == id.rawCurrencyId } - Token( - id = id.rawCurrencyId ?: coin.name, - name = coin.name, - symbol = coin.symbol, - iconUrl = getIconUrl(coin.id, value.imageHost), - isAvailable = coin.active, - networks = coin.networks.mapNotNull { network -> - val blockchain = Blockchain.fromNetworkId(network.networkId) ?: return@mapNotNull null - Token.Network( - networkId = network.networkId, - standardType = getNetworkStandardType(blockchain).name, - name = blockchain.fullName, - address = network.contractAddress, - iconUrl = getIconUrl(network.networkId, value.imageHost), - decimalCount = network.decimalCount?.toInt(), - ) - }, - quote = quote, - ) - } - } -} - -internal fun getIconUrl(id: String, imageHost: String? = null): String { - return "${imageHost ?: DEFAULT_IMAGE_HOST}large/$id.png" -} - -private const val DEFAULT_IMAGE_HOST = - "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/" \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 80a7803738..39f05b3b1c 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -486,7 +486,9 @@ internal class DefaultCurrenciesRepository( } @OptIn(ExperimentalCoroutinesApi::class) - override fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> { + override fun getAllWalletsCryptoCurrencies( + currencyRawId: CryptoCurrency.RawID, + ): Flow>> { return userWalletsStore.userWallets.flatMapLatest { userWallets -> userWallets.forEach { fetchTokensIfCacheExpired(userWallet = it, refresh = false) } @@ -496,7 +498,7 @@ internal class DefaultCurrenciesRepository( if (userWallet.isMultiCurrency) { getSavedUserTokensResponse(userWallet.walletId).map { storedTokens -> val filterResponse = storedTokens.tokens.filter { - getL2CompatibilityTokenComparison(it, currencyRawId) + getL2CompatibilityTokenComparison(it, currencyRawId.value) } responseCurrenciesFactory.createCurrencies( diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt index a680263464..0f38f7682d 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt @@ -37,7 +37,7 @@ internal class DefaultQuotesRepository( private val mutex = Mutex() @OptIn(ExperimentalCoroutinesApi::class) - override fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean): Flow> { + override fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean): Flow> { return appPreferencesStore.getObject( key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, ) @@ -51,7 +51,7 @@ internal class DefaultQuotesRepository( .flowOn(dispatchers.io) } - override suspend fun fetchQuotes(currenciesIds: Set) { + override suspend fun fetchQuotes(currenciesIds: Set) { withContext(dispatchers.io) { val selectedAppCurrency = requireNotNull( value = appPreferencesStore.getObjectSyncOrNull( @@ -64,7 +64,7 @@ internal class DefaultQuotesRepository( } } - override suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set { + override suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set { return withContext(dispatchers.io) { val selectedAppCurrency = requireNotNull( value = appPreferencesStore.getObjectSyncOrNull( @@ -81,7 +81,7 @@ internal class DefaultQuotesRepository( } } - override suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote? { + override suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote? { return withContext(dispatchers.io) { val setOfCurrencyId = setOf(currencyId) val quote = quotesStore.getSync(setOfCurrencyId).firstOrNull() @@ -90,7 +90,7 @@ internal class DefaultQuotesRepository( } private suspend fun fetchExpiredQuotes( - currenciesIds: Set, + currenciesIds: Set, appCurrencyId: String, refresh: Boolean, ) { @@ -110,15 +110,17 @@ internal class DefaultQuotesRepository( } } - private suspend fun fetchQuotes(rawCurrenciesIds: Set, appCurrencyId: String) { - val replacementIdsResult = quotesUnsupportedCurrenciesAdapter.replaceUnsupportedCurrencies(rawCurrenciesIds) + private suspend fun fetchQuotes(rawCurrenciesIds: Set, appCurrencyId: String) { + val replacementIdsResult = quotesUnsupportedCurrenciesAdapter.replaceUnsupportedCurrencies( + rawCurrenciesIds.map { it.value }.toSet(), + ) val response = safeApiCallWithTimeout( call = { val coinIds = replacementIdsResult.idsForRequest.joinToString(separator = ",") tangemTechApi.getQuotes(appCurrencyId, coinIds).bind() }, onError = { error -> - cacheRegistry.invalidate(rawCurrenciesIds.map(::getQuoteCacheKey)) + cacheRegistry.invalidate(rawCurrenciesIds.map { getQuoteCacheKey(it) }) throw error }, @@ -132,21 +134,20 @@ internal class DefaultQuotesRepository( } private suspend fun filterExpiredCurrenciesIds( - currenciesIds: Set, + currenciesIds: Set, refresh: Boolean, - ): Set { + ): Set { return currenciesIds.fold(hashSetOf()) { acc, currencyId -> - val rawCurrencyId = currencyId.rawCurrencyId - if (rawCurrencyId != null && rawCurrencyId !in acc) { + if (currencyId !in acc) { cacheRegistry.invokeOnExpire( - key = getQuoteCacheKey(rawCurrencyId), + key = getQuoteCacheKey(currencyId), skipCache = refresh, - block = { acc.add(rawCurrencyId) }, + block = { acc.add(currencyId) }, ) } acc } } - private fun getQuoteCacheKey(rawCurrencyId: String): String = "quote_$rawCurrencyId" + private fun getQuoteCacheKey(rawCurrencyId: CryptoCurrency.RawID): String = "quote_${rawCurrencyId.value}" } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/QuotesConverter.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/QuotesConverter.kt index 79af4417b7..ec86873987 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/QuotesConverter.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/QuotesConverter.kt @@ -6,16 +6,16 @@ import com.tangem.domain.tokens.model.Quote import com.tangem.utils.converter.Converter import java.math.BigDecimal -typealias QuotesConverterValue = Pair, Set> +typealias QuotesConverterValue = Pair, Set> internal class QuotesConverter : Converter> { override fun convert(value: QuotesConverterValue): Set { val (setOfCurrencyId, setOfStoredQuote) = value return setOfCurrencyId.mapTo(hashSetOf()) { id -> - setOfStoredQuote.find { id.rawCurrencyId == it.rawCurrencyId } + setOfStoredQuote.find { id.value == it.rawCurrencyId } ?.let(::convertExistStoredQuote) - ?: Quote.Empty(id.rawCurrencyId) + ?: Quote.Empty(id) } } @@ -23,7 +23,7 @@ internal class QuotesConverter : Converter> { val (rawCurrencyId, responseQuote) = storedQuote return Quote.Value( - rawCurrencyId = rawCurrencyId, + rawCurrencyId = CryptoCurrency.RawID(rawCurrencyId), fiatRate = responseQuote.price ?: BigDecimal.ZERO, priceChange = (responseQuote.priceChange24h ?: BigDecimal.ZERO).movePointLeft(2), ) diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index 440e818d8f..9811e8d408 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -217,7 +217,7 @@ class DefaultWalletManagersFacade( symbol = currency.symbol, contractAddress = currency.contractAddress, decimals = currency.decimals, - id = currency.id.rawCurrencyId, + id = currency.id.rawCurrencyId?.value, ) TransactionHistoryRequest.FilterType.Contract(blockchainToken) } @@ -255,7 +255,7 @@ class DefaultWalletManagersFacade( symbol = currency.symbol, contractAddress = currency.contractAddress, decimals = currency.decimals, - id = currency.id.rawCurrencyId, + id = currency.id.rawCurrencyId?.value, ) TransactionHistoryRequest.FilterType.Contract(blockchainToken) } diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/model/CryptoCurrencyAmount.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/model/CryptoCurrencyAmount.kt index 6ae9f6ae43..800cde28ef 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/model/CryptoCurrencyAmount.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/model/CryptoCurrencyAmount.kt @@ -1,5 +1,6 @@ package com.tangem.domain.walletmanager.model +import com.tangem.domain.tokens.model.CryptoCurrency import java.math.BigDecimal sealed class CryptoCurrencyAmount { @@ -9,7 +10,7 @@ sealed class CryptoCurrencyAmount { data class Coin(override val value: BigDecimal) : CryptoCurrencyAmount() data class Token( - val tokenId: String?, + val tokenId: CryptoCurrency.RawID?, val tokenContractAddress: String, override val value: BigDecimal, ) : CryptoCurrencyAmount() diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/CryptoCurrencyTypeConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/CryptoCurrencyTypeConverter.kt index 53d7f303c5..d782bfdea2 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/CryptoCurrencyTypeConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/CryptoCurrencyTypeConverter.kt @@ -15,7 +15,7 @@ internal class CryptoCurrencyTypeConverter : Converter { override fun convert(value: CryptoCurrency.Token): SdkToken { return SdkToken( - id = value.id.rawCurrencyId, + id = value.id.rawCurrencyId?.value, name = value.name, symbol = value.symbol, contractAddress = value.contractAddress, diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/UpdateWalletManagerResultFactory.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/UpdateWalletManagerResultFactory.kt index e3a15932b4..6e9b4c2c1f 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/UpdateWalletManagerResultFactory.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/UpdateWalletManagerResultFactory.kt @@ -2,6 +2,7 @@ package com.tangem.domain.walletmanager.utils import com.tangem.blockchain.common.* import com.tangem.blockchainsdk.utils.amountToCreateAccount +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.walletmanager.model.Address import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction @@ -84,7 +85,11 @@ internal class UpdateWalletManagerResultFactory { val demoAmounts = hashSetOf(CryptoCurrencyAmount.Coin(amountValue)) return tokens.mapTo(demoAmounts) { token -> - CryptoCurrencyAmount.Token(token.id, token.contractAddress, amountValue) + CryptoCurrencyAmount.Token( + tokenId = token.id?.let { CryptoCurrency.RawID(it) }, + tokenContractAddress = token.contractAddress, + value = amountValue, + ) } } @@ -107,7 +112,7 @@ internal class UpdateWalletManagerResultFactory { private fun createCurrencyAmount(amount: Amount): CryptoCurrencyAmount? { return when (val type = amount.type) { is AmountType.Token -> CryptoCurrencyAmount.Token( - tokenId = type.token.id, + tokenId = type.token.id?.let { CryptoCurrency.RawID(it) }, tokenContractAddress = type.token.contractAddress, value = getCurrencyAmountValue(amount) ?: return null, ) diff --git a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt index dd2f977457..817a68b712 100644 --- a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt +++ b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt @@ -111,7 +111,7 @@ class SaveManagedTokensUseCase( is ManagedCryptoCurrency.SourceNetwork.Default -> customTokensRepository.createToken( managedCryptoCurrency = token, sourceNetwork = sourceNetwork, - rawId = token.id.value, + rawId = CryptoCurrency.RawID(token.id.value), ) is ManagedCryptoCurrency.SourceNetwork.Main -> customTokensRepository.createCoin( userWalletId = userWalletId, diff --git a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/repository/CustomTokensRepository.kt b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/repository/CustomTokensRepository.kt index 3b0d13aba6..86db4be54c 100644 --- a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/repository/CustomTokensRepository.kt +++ b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/repository/CustomTokensRepository.kt @@ -33,7 +33,7 @@ interface CustomTokensRepository { suspend fun createToken( managedCryptoCurrency: ManagedCryptoCurrency.Token, sourceNetwork: ManagedCryptoCurrency.SourceNetwork.Default, - rawId: String?, + rawId: CryptoCurrency.RawID?, ): CryptoCurrency.Token suspend fun createCustomToken( diff --git a/domain/markets/models/build.gradle.kts b/domain/markets/models/build.gradle.kts index 7558c5ca61..dafb0e3da4 100644 --- a/domain/markets/models/build.gradle.kts +++ b/domain/markets/models/build.gradle.kts @@ -5,6 +5,7 @@ plugins { } dependencies { + api(projects.domain.tokens.models) implementation(projects.domain.core) implementation(deps.kotlin.serialization) 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 e7d0c1d6e9..1724d9ce45 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 @@ -1,9 +1,10 @@ package com.tangem.domain.markets +import com.tangem.domain.tokens.model.CryptoCurrency import java.math.BigDecimal data class TokenMarket( - val id: String, + val id: CryptoCurrency.RawID, val name: String, val symbol: String, val marketRating: Int?, diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketParams.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketParams.kt index e14b1f417b..77c288aa8b 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketParams.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketParams.kt @@ -1,11 +1,12 @@ package com.tangem.domain.markets import com.tangem.domain.core.serialization.SerializedBigDecimal +import com.tangem.domain.tokens.model.CryptoCurrency import kotlinx.serialization.Serializable @Serializable data class TokenMarketParams( - val id: String, + val id: CryptoCurrency.RawID, val name: String, val symbol: String, val tokenQuotes: Quotes, diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetCurrencyQuotesUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetCurrencyQuotesUseCase.kt index 0a8d0d931d..91a67b1d12 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetCurrencyQuotesUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetCurrencyQuotesUseCase.kt @@ -16,8 +16,10 @@ class GetCurrencyQuotesUseCase( interval: PriceChangeInterval, refresh: Boolean, ): Flow> { + val rawId = currencyID.rawCurrencyId ?: return flowOf(None) + return quotesRepository.getQuotesUpdates( - currenciesIds = setOf(currencyID), + currenciesIds = setOf(rawId), refresh = refresh, ).map { it.filterIsInstance().firstOrNull().toOption() }.catch { emit(None) } } diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenExchangesUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenExchangesUseCase.kt index a2862b339f..7139071dd9 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenExchangesUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenExchangesUseCase.kt @@ -2,6 +2,7 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.tokens.model.CryptoCurrency /** * Get token exchanges use case @@ -12,7 +13,7 @@ class GetTokenExchangesUseCase( private val marketsTokenRepository: MarketsTokenRepository, ) { - suspend operator fun invoke(tokenId: String): Either> { + suspend operator fun invoke(tokenId: CryptoCurrency.RawID): Either> { return Either.catch { marketsTokenRepository.getTokenExchanges(tokenId = tokenId) } } } \ No newline at end of file diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenFullQuotesUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenFullQuotesUseCase.kt index e8b8470add..ee0b3fbac4 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenFullQuotesUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenFullQuotesUseCase.kt @@ -3,13 +3,14 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.tokens.model.CryptoCurrency class GetTokenFullQuotesUseCase( private val marketsTokenRepository: MarketsTokenRepository, ) { suspend operator fun invoke( appCurrency: AppCurrency, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ): Either { return Either.catch { diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketInfoUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketInfoUseCase.kt index 2038181eef..a330e614ce 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketInfoUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketInfoUseCase.kt @@ -3,6 +3,7 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.utils.SupportedLanguages class GetTokenMarketInfoUseCase( @@ -11,7 +12,7 @@ class GetTokenMarketInfoUseCase( suspend operator fun invoke( appCurrency: AppCurrency, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ): Either { return Either.catch { diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenPriceChartUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenPriceChartUseCase.kt index c6d677f34b..a47186eb3d 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenPriceChartUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenPriceChartUseCase.kt @@ -3,6 +3,7 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.tokens.model.CryptoCurrency class GetTokenPriceChartUseCase( private val marketsTokenRepository: MarketsTokenRepository, @@ -11,7 +12,7 @@ class GetTokenPriceChartUseCase( suspend operator fun invoke( appCurrency: AppCurrency, interval: PriceChangeInterval, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, preview: Boolean, ): Either { diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt index 1f728f1a0f..80a1a97480 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt @@ -15,25 +15,29 @@ interface MarketsTokenRepository { suspend fun getChart( fiatCurrencyCode: String, interval: PriceChangeInterval, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ): TokenChart suspend fun getChartPreview( fiatCurrencyCode: String, interval: PriceChangeInterval, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, ): TokenChart suspend fun getTokenInfo( fiatCurrencyCode: String, - tokenId: String, + tokenId: CryptoCurrency.RawID, tokenSymbol: String, languageCode: String, ): TokenMarketInfo - suspend fun getTokenQuotes(fiatCurrencyCode: String, tokenId: String, tokenSymbol: String): TokenQuotes + suspend fun getTokenQuotes( + fiatCurrencyCode: String, + tokenId: CryptoCurrency.RawID, + tokenSymbol: String, + ): TokenQuotes suspend fun createCryptoCurrency( userWalletId: UserWalletId, @@ -46,5 +50,5 @@ interface MarketsTokenRepository { * * @param tokenId token id */ - suspend fun getTokenExchanges(tokenId: String): List + suspend fun getTokenExchanges(tokenId: CryptoCurrency.RawID): List } \ No newline at end of file diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt index 9f201fb81e..c3dd3636ce 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/Yield.kt @@ -21,8 +21,6 @@ data class Yield( val preferredValidators: List get() = validators.filter { it.preferred } - fun getCurrentToken(rawCurrencyId: String?) = tokens.firstOrNull { rawCurrencyId == it.coinGeckoId } ?: token - @Serializable data class Status( val enter: Boolean, diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt index a0468f3100..017bc65de0 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt @@ -93,7 +93,7 @@ sealed class CryptoCurrency { } /** Represents a raw cryptocurrency ID. If it is a custom token, the value will be `null`. */ - val rawCurrencyId: String? get() = (suffix as? Suffix.RawID)?.rawId + val rawCurrencyId: RawID? get() = (suffix as? Suffix.RawID)?.rawId?.let { RawID(it) } val contractAddress: String? get() = (suffix as? Suffix.RawID)?.contractAddress @@ -196,6 +196,16 @@ sealed class CryptoCurrency { } } + /** + * Represents a raw cryptocurrency ID. Used for backend calls. + * Use with caution, as it does not provide the same level of uniqueness as [ID]. + */ + @Serializable + @JvmInline + value class RawID(val value: String) { + override fun toString(): String = value + } + protected fun checkProperties() { require(name.isNotBlank()) { "Crypto currency name must not be blank" } require(symbol.isNotBlank()) { "Crypto currency symbol must not be blank" } diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/Quote.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/Quote.kt index d54b9a2342..c330160b97 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/Quote.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/Quote.kt @@ -4,14 +4,14 @@ import java.math.BigDecimal sealed interface Quote { - val rawCurrencyId: String? + val rawCurrencyId: CryptoCurrency.RawID /** * Represents unknown financial information for a specific cryptocurrency. * - * @property rawCurrencyId The raw cryptocurrency ID. If it is a custom token, the value will be `null`. + * @property rawCurrencyId The raw cryptocurrency ID. */ - data class Empty(override val rawCurrencyId: String?) : Quote + data class Empty(override val rawCurrencyId: CryptoCurrency.RawID) : Quote /** * Represents financial information for a specific cryptocurrency, including its fiat exchange rate and price change. @@ -21,7 +21,7 @@ sealed interface Quote { * @property priceChange The price change for the cryptocurrency. */ data class Value( - override val rawCurrencyId: String, + override val rawCurrencyId: CryptoCurrency.RawID, val fiatRate: BigDecimal, val priceChange: BigDecimal, ) : Quote diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/staking/YieldExtentions.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/staking/YieldExtentions.kt new file mode 100644 index 0000000000..d013d4e03b --- /dev/null +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/staking/YieldExtentions.kt @@ -0,0 +1,7 @@ +package com.tangem.domain.tokens.model.staking + +import com.tangem.domain.staking.model.stakekit.Yield +import com.tangem.domain.tokens.model.CryptoCurrency + +fun Yield.getCurrentToken(rawCurrencyId: CryptoCurrency.RawID?) = + tokens.firstOrNull { rawCurrencyId?.value == it.coinGeckoId } ?: token \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt index 0fc9607d48..9bac51630e 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt @@ -37,7 +37,7 @@ class FetchCardTokenListUseCase( } val fetchQuotes = async { fetchQuotes( - currenciesIds = currencies.mapTo(destination = hashSetOf(), transform = CryptoCurrency::id), + currenciesIds = currencies.mapNotNullTo(destination = hashSetOf()) { it.id.rawCurrencyId }, refresh = refresh, ) } @@ -79,7 +79,7 @@ class FetchCardTokenListUseCase( ) } - private suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean) { + private suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean) { catch( block = { quotesRepository.getQuotesSync(currenciesIds, refresh) }, catch = { /* Ignore error */ }, diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt index b5a73a5ac3..a6455893a6 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt @@ -125,7 +125,7 @@ class FetchCurrencyStatusUseCase( private suspend fun Raise.fetchQuote(currencyId: CryptoCurrency.ID, refresh: Boolean) { catch( - block = { quotesRepository.getQuotesSync(setOf(currencyId), refresh) }, + block = { quotesRepository.getQuotesSync(setOfNotNull(currencyId.rawCurrencyId), refresh) }, ) { raise(CurrencyStatusError.DataError(it)) } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt index f1ef16bca8..9b8dea0263 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt @@ -105,7 +105,10 @@ class FetchTokenListUseCase( private suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean) { catch( - block = { quotesRepository.getQuotesSync(currenciesIds, refresh) }, + block = { + val rawIds = currenciesIds.mapNotNull { it.rawCurrencyId }.toSet() + quotesRepository.getQuotesSync(rawIds, refresh) + }, ) { /* Ignore error */ } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt index 8fc8bef040..0dfb01856e 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt @@ -41,7 +41,7 @@ class GetAllWalletsCryptoCurrencyStatusesUseCase( */ @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke( - currencyRawId: String, + currencyRawId: CryptoCurrency.RawID, ): Flow>>> { return currenciesRepository.getAllWalletsCryptoCurrencies(currencyRawId) .flatMapLatest { userWalletsWithCurrencies: Map> -> diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt index aeba9d2c14..70564f24ef 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt @@ -47,7 +47,7 @@ class RefreshMultiCurrencyWalletQuotesUseCase( private suspend fun fetchQuotes(currenciesIds: Set) { catch( block = { - quotesRepository.fetchQuotes(currenciesIds) + quotesRepository.fetchQuotes(currenciesIds.mapNotNullTo(hashSetOf(), CryptoCurrency.ID::rawCurrencyId)) }, catch = { /* Ignore error */ }, ) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt index 16052e2974..a978af55f4 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesLceOperations.kt @@ -166,7 +166,7 @@ internal class CurrenciesStatusesLceOperations( } private fun getQuotes(tokensIds: NonEmptySet): Flow>> { - return quotesRepository.getQuotesUpdates(tokensIds) + return quotesRepository.getQuotesUpdates(tokensIds.mapNotNull { it.rawCurrencyId }.toSet()) .map, Either>> { it.right() } .retryWhen { cause, _ -> emit(TokenListError.DataError(cause).left()) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt index f2ef6e1efb..1035011308 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt @@ -31,7 +31,8 @@ internal class CurrenciesStatusesOperations( currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId).toNonEmptyListOrNull() ?: return emptyList().right() val (networks, currenciesIds) = getIds(nonEmptyCurrencies) - val quotes = quotesRepository.getQuotesSync(currenciesIds, false).right() + val rawIds = currenciesIds.mapNotNull { it.rawCurrencyId }.toSet() + val quotes = quotesRepository.getQuotesSync(rawIds, false).right() val networkStatuses = networksRepository.getNetworkStatusesSync(userWalletId, networks, false).right() val yieldBalances = getYieldBalancesSync(nonEmptyCurrencies) @@ -60,7 +61,8 @@ internal class CurrenciesStatusesOperations( } else { currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, cryptoCurrencyId) } - val quotes = quotesRepository.getQuoteSync(cryptoCurrencyId)?.right() ?: Error.EmptyQuotes.left() + val quote = cryptoCurrencyId.rawCurrencyId?.let { quotesRepository.getQuoteSync(it) }?.right() + ?: Error.EmptyQuotes.left() val networkStatuses = networksRepository.getNetworkStatusesSync( userWalletId, @@ -71,7 +73,7 @@ internal class CurrenciesStatusesOperations( }.right() val yieldBalances = getYieldBalanceSync(currency) - return createCurrencyStatus(currency, quotes, networkStatuses, yieldBalances) + return createCurrencyStatus(currency, quote, networkStatuses, yieldBalances) }, catch = { raise(Error.DataError(it)) }, ) @@ -104,7 +106,10 @@ internal class CurrenciesStatusesOperations( catch = { raise(Error.DataError(it)) }, ) val quotes = catch( - block = { quotesRepository.getQuoteSync(currency.id)?.right() ?: Error.EmptyQuotes.left() }, + block = { + currency.id.rawCurrencyId?.let { quotesRepository.getQuoteSync(it) } + ?.right() ?: Error.EmptyQuotes.left() + }, catch = { Error.DataError(it).left() }, ) val networkStatus = catch( @@ -176,8 +181,7 @@ internal class CurrenciesStatusesOperations( fun getCurrencyStatusFlow( currency: CryptoCurrency, includeQuotes: Boolean = true, - ): Flow,> { + ): Flow> { val (networks, currenciesIds) = getIds(nonEmptyListOf(currency)) val quoteFlow = if (includeQuotes) { @@ -344,7 +348,8 @@ internal class CurrenciesStatusesOperations( } private fun getQuotes(tokensIds: NonEmptySet): Flow>> { - return quotesRepository.getQuotesUpdates(tokensIds) + val rawIds = tokensIds.mapNotNull { it.rawCurrencyId }.toSet() + return quotesRepository.getQuotesUpdates(rawIds) .map, Either>> { quotes -> if (quotes.isEmpty()) Error.EmptyQuotes.left() else quotes.right() } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt index 41d94b2cf2..2c73402bff 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt @@ -74,7 +74,7 @@ internal class CurrencyStatusOperations( val yieldBalanceData = yieldBalance as? YieldBalance.Data val isCurrentAddressStaking = yieldBalanceData?.address == status.address.defaultAddress.value val filteredTokenBalances = yieldBalanceData?.balance?.items?.filter { - it.token.coinGeckoId == currency.id.rawCurrencyId + it.token.coinGeckoId == currency.id.rawCurrencyId?.value } val currentYieldBalance = if (isCurrentAddressStaking && filteredTokenBalances?.isNotEmpty() == true) { yieldBalanceData.copy( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt index c99a692b70..04fa86295f 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt @@ -248,7 +248,7 @@ interface CurrenciesRepository { ): CryptoCurrency.Token /** Get crypto currencies by [currencyRawId] from all user wallets */ - fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> + fun getAllWalletsCryptoCurrencies(currencyRawId: CryptoCurrency.RawID): Flow>> fun isNetworkFeeZero(userWalletId: UserWalletId, network: Network): Boolean } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt index 57a8429697..98e2f0193c 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt @@ -17,7 +17,7 @@ interface QuotesRepository { * @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved. * @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies. */ - fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean = false): Flow> + fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean = false): Flow> /** * Retrieves quotes for a set of specified cryptocurrencies, identified by their unique IDs. @@ -28,9 +28,9 @@ interface QuotesRepository { * @param refresh A boolean flag indicating whether the data should be refreshed. * @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies. */ - suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set + suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set - suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote? + suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote? - suspend fun fetchQuotes(currenciesIds: Set) + suspend fun fetchQuotes(currenciesIds: Set) } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt index 002f80eae8..5dde109c87 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt @@ -1,6 +1,7 @@ package com.tangem.domain.tokens.mock import arrow.core.nonEmptySetOf +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Quote import java.math.BigDecimal @@ -67,11 +68,10 @@ internal object MockQuotes { priceChange = BigDecimal("-0.10"), ) - val quote11 = Quote.Empty(null) - val quote12 = Quote.Empty("null") + val quote11 = Quote.Empty(CryptoCurrency.RawID("null")) val quotes = nonEmptySetOf( quote1, quote2, quote3, quote4, quote5, quote6, quote7, quote8, quote9, quote10, - quote11, quote12, + quote11, ) } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt index ce99852888..a94add56b4 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt @@ -153,7 +153,9 @@ internal class MockCurrenciesRepository( error("not implemented") } - override fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> { + override fun getAllWalletsCryptoCurrencies( + currencyRawId: CryptoCurrency.RawID, + ): Flow>> { return emptyFlow() } diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt index 393432cf16..86f2775a96 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt @@ -13,18 +13,18 @@ internal class MockQuotesRepository( private val quotes: Flow>>, ) : QuotesRepository { - override fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean): Flow> { + override fun getQuotesUpdates(currenciesIds: Set, refresh: Boolean): Flow> { return quotes.map { it.getOrElse { e -> throw e } } } - override suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set { + override suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set { return getQuotesUpdates(currenciesIds).first() } - override suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote { + override suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote { return quotes.map { it.getOrElse { e -> throw e } }.first() - .first { it.rawCurrencyId == currencyId.rawCurrencyId } + .first { it.rawCurrencyId == currencyId } } - override suspend fun fetchQuotes(currenciesIds: Set) {} + override suspend fun fetchQuotes(currenciesIds: Set) {} } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/DefaultMarketsTokenDetailsComponent.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/DefaultMarketsTokenDetailsComponent.kt index 2628335d48..3ee3a5edce 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/DefaultMarketsTokenDetailsComponent.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/DefaultMarketsTokenDetailsComponent.kt @@ -13,6 +13,7 @@ import com.tangem.core.decompose.context.child import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.res.TangemTheme +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.details.MarketsTokenDetailsComponent import com.tangem.features.markets.details.MarketsTokenDetailsComponent.Params import com.tangem.features.markets.details.impl.analytics.MarketDetailsAnalyticsEvent @@ -38,7 +39,7 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor( // applying l2 compatibility private val updatedParams = params.copy( token = params.token.copy( - id = getTokenIdIfL2Network(params.token.id), + id = CryptoCurrency.RawID(getTokenIdIfL2Network(params.token.id.value)), ), ) private val analyticsParams = params.analyticsParams diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt index c6c2a86b49..04d2edcb0c 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt @@ -134,7 +134,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( modelScope.launch { sendFeedbackEmailUseCase( type = FeedbackEmailType.CurrencyDescriptionError( - currencyId = params.token.id, + currencyId = params.token.id.value, currencyName = params.token.name, ), ) diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt index ac016c1bbf..f4e8c0aad9 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt @@ -9,6 +9,7 @@ import com.tangem.domain.tokens.GetAllWalletsCryptoCurrencyStatusesUseCase import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase import com.tangem.domain.tokens.error.TokenListError +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId @@ -37,7 +38,7 @@ internal class PortfolioDataLoader @Inject constructor( /** Load data by [currencyRawId] */ @OptIn(ExperimentalCoroutinesApi::class) - fun load(currencyRawId: String): Flow { + fun load(currencyRawId: CryptoCurrency.RawID): Flow { return combine( flow = getAllWalletsCryptoCurrenciesData(currencyRawId = currencyRawId), flow2 = getSelectedAppCurrencyFlow(), @@ -62,7 +63,7 @@ internal class PortfolioDataLoader @Inject constructor( @OptIn(ExperimentalCoroutinesApi::class) private fun getAllWalletsCryptoCurrenciesData( - currencyRawId: String, + currencyRawId: CryptoCurrency.RawID, ): Flow>> { return getAllWalletsCryptoCurrencyStatusesUseCase(currencyRawId) .distinctUntilChanged() diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/SelectNetworkUMConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/SelectNetworkUMConverter.kt index 05b33043d7..8599ad97d5 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/SelectNetworkUMConverter.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/SelectNetworkUMConverter.kt @@ -24,7 +24,7 @@ internal class SelectNetworkUMConverter( override fun convert(value: TokenMarketParams): SelectNetworkUM { return SelectNetworkUM( - tokenId = value.id, + tokenId = value.id.value, iconUrl = value.imageUrl, tokenName = value.name, tokenCurrencySymbol = value.symbol, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt index f3dd2d3c1a..7e94d860a3 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt @@ -9,6 +9,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase import com.tangem.domain.markets.TokenMarket +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.entry.BottomSheetState import com.tangem.features.markets.tokenlist.impl.analytics.MarketsListAnalyticsEvent import com.tangem.features.markets.tokenlist.impl.model.statemanager.MarketsListBatchFlowManager @@ -48,7 +49,7 @@ internal class MarketsListModel @Inject constructor( initialValue = AppCurrency.Default, ) - private val visibleItemIds = MutableStateFlow>(emptyList()) + private val visibleItemIds = MutableStateFlow>(emptyList()) private val marketsListUMStateManager = MarketsListUMStateManager( currentVisibleIds = Provider { visibleItemIds.value }, @@ -72,8 +73,8 @@ internal class MarketsListModel @Inject constructor( getMarketsTokenListFlowUseCase = getMarketsTokenListFlowUseCase, batchFlowType = GetMarketsTokenListFlowUseCase.BatchFlowType.Search, currentAppCurrency = Provider { currentAppCurrency.value }, - currentTrendInterval = Provider { marketsListUMStateManager.selectedInterval }, // FIXME fix on backend - currentSortByType = Provider { SortByTypeUM.Rating }, // FIXME maybe fix on backend + currentTrendInterval = Provider { marketsListUMStateManager.selectedInterval }, + currentSortByType = Provider { SortByTypeUM.Rating }, currentSearchText = Provider { marketsListUMStateManager.searchQuery }, modelScope = modelScope, dispatchers = dispatchers, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt index bc5dcaed36..e178484e78 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt @@ -2,6 +2,7 @@ package com.tangem.features.markets.tokenlist.impl.model.statemanager import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.* +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.tokenlist.impl.model.converters.MarketsTokenItemConverter import com.tangem.features.markets.tokenlist.impl.model.utils.logAction import com.tangem.features.markets.tokenlist.impl.model.utils.logStatus @@ -302,7 +303,7 @@ internal class MarketsListBatchFlowManager( } } - fun getBatchKeysByItemIds(ids: List): Set { + fun getBatchKeysByItemIds(ids: List): Set { val currentData = batchFlow.state.value.data return currentData @@ -311,7 +312,7 @@ internal class MarketsListBatchFlowManager( .toSet() } - fun getTokenById(id: String): TokenMarket? { + fun getTokenById(id: CryptoCurrency.RawID): TokenMarket? { return batchFlow.state.value.data.map { it.data }.flatten().find { it.id == id } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt index 6c2b177d24..aa7f006d19 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt @@ -6,6 +6,7 @@ import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.event.consumedEvent import com.tangem.core.ui.event.triggeredEvent import com.tangem.core.ui.extensions.resourceReference +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.impl.R import com.tangem.features.markets.tokenlist.impl.ui.state.* import com.tangem.utils.Provider @@ -18,9 +19,9 @@ import kotlinx.coroutines.flow.update @Stable internal class MarketsListUMStateManager( - private val currentVisibleIds: Provider>, + private val currentVisibleIds: Provider>, private val onLoadMoreUiItems: () -> Unit, - private val visibleItemsChanged: (itemsKeys: List) -> Unit, + private val visibleItemsChanged: (itemsKeys: List) -> Unit, private val onRetryButtonClicked: () -> Unit, private val onTokenClick: (MarketsListItemUM) -> Unit, ) { diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt index 752717b1bb..e1b6bfd37b 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt @@ -36,6 +36,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.entry.BottomSheetState import com.tangem.features.markets.impl.R import com.tangem.features.markets.tokenlist.impl.ui.components.MarketsListLazyColumn @@ -298,7 +299,7 @@ private fun Preview() { items = MarketChartListItemPreviewDataProvider().values .flatMap { item -> List(size = 10) { item } } .mapIndexed { index, item -> - item.copy(id = index.toString()) + item.copy(id = CryptoCurrency.RawID(index.toString())) } .toImmutableList(), showUnder100kTokensNotification = false, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt index 77b086ff3b..703e2eae67 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt @@ -17,6 +17,7 @@ import com.tangem.core.ui.event.EventEffect import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.impl.R import com.tangem.features.markets.tokenlist.impl.ui.state.ListUM import kotlinx.coroutines.launch @@ -88,7 +89,7 @@ internal fun MarketsListLazyColumn( is ListUM.Content -> { items( items = state.items, - key = { it.id + TOKEN_LAZY_LIST_ID_SEPARATOR + it.marketCap.toString() }, + key = { it.id.value + TOKEN_LAZY_LIST_ID_SEPARATOR + it.marketCap.toString() }, ) { item -> MarketsListItem( model = item, @@ -193,6 +194,7 @@ private fun VisibleItemsTracker(listState: LazyListState, state: ListUM) { derivedStateOf { listState.layoutInfo.visibleItemsInfo.mapNotNull { (it.key as? String)?.split(TOKEN_LAZY_LIST_ID_SEPARATOR)?.first() + ?.let { rawId -> CryptoCurrency.RawID(rawId) } } } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/preview/MarketChartListItemPreviewDataProvider.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/preview/MarketChartListItemPreviewDataProvider.kt index e0c4a52d54..97eecee6d1 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/preview/MarketChartListItemPreviewDataProvider.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/preview/MarketChartListItemPreviewDataProvider.kt @@ -4,13 +4,14 @@ package com.tangem.features.markets.tokenlist.impl.ui.preview import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import com.tangem.common.ui.charts.state.MarketChartRawData import com.tangem.core.ui.components.marketprice.PriceChangeType +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.tokenlist.impl.ui.state.MarketsListItemUM import kotlinx.collections.immutable.persistentListOf internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParameterProvider( collection = listOf( MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin", currencySymbol = "BTC", iconUrl = "", @@ -25,7 +26,7 @@ internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParamet isUnder100kMarketCap = false, ), MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin", currencySymbol = "BTC", iconUrl = null, @@ -38,7 +39,7 @@ internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParamet isUnder100kMarketCap = false, ), MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin", currencySymbol = "BTC", iconUrl = null, @@ -53,7 +54,7 @@ internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParamet isUnder100kMarketCap = false, ), MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin", currencySymbol = "BTC", iconUrl = null, @@ -68,7 +69,7 @@ internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParamet isUnder100kMarketCap = false, ), MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin", currencySymbol = "BTC", iconUrl = null, @@ -83,7 +84,7 @@ internal class MarketChartListItemPreviewDataProvider : CollectionPreviewParamet isUnder100kMarketCap = false, ), MarketsListItemUM( - id = "1", + id = CryptoCurrency.RawID("1"), name = "Bitcoin", currencySymbol = "BTC", iconUrl = null, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListItemUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListItemUM.kt index 9bc808aee8..458a1e29a3 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListItemUM.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListItemUM.kt @@ -4,10 +4,11 @@ import androidx.compose.runtime.Immutable import com.tangem.common.ui.charts.state.MarketChartLook import com.tangem.common.ui.charts.state.MarketChartRawData import com.tangem.core.ui.components.marketprice.PriceChangeType +import com.tangem.domain.tokens.model.CryptoCurrency @Immutable data class MarketsListItemUM( - val id: String, + val id: CryptoCurrency.RawID, val name: String, val currencySymbol: String, val iconUrl: String?, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt index 10ed82175e..298f90f22f 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt @@ -6,6 +6,7 @@ import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.event.StateEvent import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.features.markets.impl.R import kotlinx.collections.immutable.ImmutableList @@ -44,7 +45,7 @@ sealed class ListUM { val showUnder100kTokensNotification: Boolean, val showUnder100kTokensNotificationWasHidden: Boolean, val loadMore: () -> Unit, - val visibleIdsChanged: (List) -> Unit, + val visibleIdsChanged: (List) -> Unit, val onShowTokensUnder100kClicked: () -> Unit, val triggerScrollReset: StateEvent, val onItemClick: (MarketsListItemUM) -> Unit, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt index 709bd1f9bc..e31d57f978 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt @@ -229,7 +229,7 @@ internal class FeeStateFactory( symbol = this.token.symbol, contractAddress = this.token.contractAddress, decimals = this.token.decimals, - id = this.token.id.rawCurrencyId, + id = this.token.id.rawCurrencyId?.value, ), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt index b151140d55..d9996e2ded 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt @@ -89,7 +89,7 @@ internal class RewardsValidatorStateConverter( formattedCryptoAmount = cryptoAmount, fiatAmount = fiatValue, formattedFiatAmount = formattedFiatAmount, - rawCurrencyId = cryptoCurrency.id.rawCurrencyId, + rawCurrencyId = cryptoCurrency.id.rawCurrencyId?.value, pendingActions = balance.pendingActions.toPersistentList(), isClickable = true, type = balance.type, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt index 9167845687..6ed1669b40 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingFeeTransactionLoader.kt @@ -15,6 +15,7 @@ import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.model.stakekit.transaction.ActionParams import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.model.staking.getCurrentToken import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.wallets.models.UserWallet diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt index 09b6415c41..1de6d402d2 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/helpers/StakingTransactionSender.kt @@ -18,6 +18,7 @@ import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction import com.tangem.domain.staking.model.stakekit.transaction.StakingTransactionStatus import com.tangem.domain.staking.model.stakekit.transaction.StakingTransactionType import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.model.staking.getCurrentToken import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 597b837eac..53e6b2335c 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -2134,14 +2134,17 @@ internal class SwapInteractorImpl @AssistedInject constructor( } private suspend fun getQuotes(vararg ids: CryptoCurrency.ID): Map { - val set = ids.toSet().getQuotesOrEmpty(false).filterIsInstance() + val set = ids.mapNotNull { it.rawCurrencyId } + .toSet() + .getQuotesOrEmpty(false) + .filterIsInstance() return ids .mapNotNull { id -> set.find { it.rawCurrencyId == id.rawCurrencyId }?.let { id to it } } .toMap() } - private suspend fun Set.getQuotesOrEmpty(refresh: Boolean): Set { + private suspend fun Set.getQuotesOrEmpty(refresh: Boolean): Set { return try { quotesRepository.getQuotesSync(this, refresh) } catch (t: Throwable) { diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt index 25d87bd106..b63aad6b70 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt @@ -205,7 +205,8 @@ internal class ExchangeStatusFactory @AssistedInject constructor( private suspend fun Set.getQuotesOrEmpty(refresh: Boolean): Set { return try { - quotesRepository.getQuotesSync(this, refresh) + val rawIds = mapNotNull { it.rawCurrencyId }.toSet() + quotesRepository.getQuotesSync(rawIds, refresh) } catch (t: Throwable) { emptySet() }