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 f359605e09..78e6ffb72b 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 @@ -3,6 +3,7 @@ package com.tangem.datasource.local.quote import com.tangem.datasource.api.tangemTech.models.QuotesResponse import com.tangem.datasource.local.datastore.core.StringKeyDataStore import com.tangem.datasource.local.quote.model.StoredQuote +import com.tangem.domain.tokens.models.CryptoCurrency import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -10,9 +11,9 @@ internal class DefaultQuotesStore( private val dataStore: StringKeyDataStore, ) : QuotesStore { - override fun get(rawCurrenciesIds: Set): Flow> { - val flows = rawCurrenciesIds.map { rawCurrencyId -> - dataStore.get(rawCurrencyId) + override fun get(currenciesIds: Set): Flow> { + val flows = currenciesIds.mapNotNull { currencyId -> + dataStore.get(currencyId.rawCurrencyId ?: return@mapNotNull null) } return combine(flows) { quotes -> quotes.toSet() } 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 77a5a65c73..f34d0039b8 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 @@ -2,11 +2,12 @@ package com.tangem.datasource.local.quote import com.tangem.datasource.api.tangemTech.models.QuotesResponse import com.tangem.datasource.local.quote.model.StoredQuote +import com.tangem.domain.tokens.models.CryptoCurrency import kotlinx.coroutines.flow.Flow interface QuotesStore { - fun get(rawCurrenciesIds: Set): Flow> + fun get(currenciesIds: Set): Flow> suspend fun store(response: QuotesResponse) } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/MockQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/MockQuotesRepository.kt index 91ca009e7c..31e9c03dc5 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/MockQuotesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/MockQuotesRepository.kt @@ -13,13 +13,13 @@ internal class MockQuotesRepository : QuotesRepository { override fun getQuotes(currenciesIds: Set, refresh: Boolean): Flow> { return channelFlow { - val quotes = currenciesIds.map { + val quotes = currenciesIds.mapNotNullTo(hashSetOf()) { id -> Quote( - currencyId = it, + rawCurrencyId = id.rawCurrencyId ?: return@mapNotNullTo null, fiatRate = BigDecimal.ZERO, priceChange = BigDecimal.ZERO, ) - }.toSet() + } delay(Random.nextLong(from = 200, until = 2_000)) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt index d38263cbab..6feee38172 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt @@ -39,7 +39,7 @@ internal class NetworkStatusFactory { is CryptoCurrencyAmount.Coin -> currencies.singleOrNull { it is CryptoCurrency.Coin } is CryptoCurrencyAmount.Token -> currencies.firstOrNull { it is CryptoCurrency.Token && - getTokenIdString(it.id) == amount.id && + it.id.rawCurrencyId == amount.id && it.contractAddress == amount.tokenContractAddress } } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCurrenciesFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCurrenciesFactory.kt index 7955f660dd..89d6bfec27 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCurrenciesFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCurrenciesFactory.kt @@ -13,7 +13,7 @@ import com.tangem.blockchain.common.Token as SdkToken internal class ResponseCurrenciesFactory(private val demoConfig: DemoConfig) { fun createCurrency(currencyId: CryptoCurrency.ID, response: UserTokensResponse, card: CardDTO): CryptoCurrency { - val responseTokenId = getTokenIdString(currencyId) + val responseTokenId = currencyId.rawCurrencyId val token = requireNotNull(response.tokens.firstOrNull { it.id == responseTokenId }) { "Unable find a token with provided ID: $responseTokenId" diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt index 091d698368..c302d2246f 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/TokensOperations.kt @@ -6,21 +6,21 @@ import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.models.scan.CardDTO -import com.tangem.domain.tokens.models.CryptoCurrency +import com.tangem.domain.tokens.models.CryptoCurrency.ID import com.tangem.domain.tokens.models.Network import com.tangem.blockchain.common.Token as SdkToken +import com.tangem.domain.tokens.models.CryptoCurrency.ID.Prefix.COIN_PREFIX as COIN_ID_PREFIX +import com.tangem.domain.tokens.models.CryptoCurrency.ID.Prefix.CUSTOM_TOKEN_PREFIX as CUSTOM_TOKEN_ID_PREFIX +import com.tangem.domain.tokens.models.CryptoCurrency.ID.Prefix.TOKEN_PREFIX as TOKEN_ID_PREFIX +import com.tangem.domain.tokens.models.CryptoCurrency.ID.Suffix.ContractAddress as CustomCurrencyIdSuffix +import com.tangem.domain.tokens.models.CryptoCurrency.ID.Suffix.RawID as CurrencyIdSuffix private const val DEFAULT_TOKENS_ICONS_HOST = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins" private const val TOKEN_ICON_SIZE = "large" private const val TOKEN_ICON_EXT = "png" -private const val COIN_ID_PREFIX = "coin_" -private const val TOKEN_ID_PREFIX = "token_" -private const val CUSTOM_TOKEN_ID_PREFIX = "custom_token_" -private const val TOKEN_ID_DELIMITER = '#' - -internal fun isCustomToken(tokenId: CryptoCurrency.ID): Boolean { - return tokenId.value.startsWith(CUSTOM_TOKEN_ID_PREFIX) +internal fun isCustomToken(tokenId: ID): Boolean { + return tokenId.rawCurrencyId == null } internal fun getDerivationPath(blockchain: Blockchain, card: CardDTO): String? { @@ -41,24 +41,14 @@ internal fun getNetworkId(blockchain: Blockchain): Network.ID { return Network.ID(value) } -internal fun getCoinId(blockchain: Blockchain): CryptoCurrency.ID { +internal fun getCoinId(blockchain: Blockchain): ID { return getTokenOrCoinId(blockchain, token = null) } -internal fun getTokenId(blockchain: Blockchain, token: SdkToken): CryptoCurrency.ID { +internal fun getTokenId(blockchain: Blockchain, token: SdkToken): ID { return getTokenOrCoinId(blockchain, token) } -internal fun getTokenIdString(currencyId: CryptoCurrency.ID): String? { - val idValue = currencyId.value - - return if (idValue.startsWith(CUSTOM_TOKEN_ID_PREFIX)) { - null - } else { - idValue.substringAfter(TOKEN_ID_DELIMITER) - } -} - internal fun getTokenIconUrl(blockchain: Blockchain, token: SdkToken): String? { val tokenId = token.id @@ -79,22 +69,15 @@ internal fun getCoinIconUrl(blockchain: Blockchain): String? { return coinId?.let(::getTokenIconUrlFromDefaultHost) } -private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): CryptoCurrency.ID { +private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): ID { val sdkTokenId = token?.id val (prefix, suffix) = when { - token == null -> COIN_ID_PREFIX to blockchain.toCoinId() - sdkTokenId == null -> CUSTOM_TOKEN_ID_PREFIX to token.contractAddress - else -> TOKEN_ID_PREFIX to sdkTokenId + token == null -> COIN_ID_PREFIX to CurrencyIdSuffix(rawId = blockchain.toCoinId()) + sdkTokenId == null -> CUSTOM_TOKEN_ID_PREFIX to CustomCurrencyIdSuffix(contractAddress = token.contractAddress) + else -> TOKEN_ID_PREFIX to CurrencyIdSuffix(rawId = sdkTokenId) } - val value = buildString { - append(prefix) - append(blockchain.id) - append(TOKEN_ID_DELIMITER) - append(suffix.lowercase()) - } - - return CryptoCurrency.ID(value) + return ID(prefix, getNetworkId(blockchain), suffix) } private fun getTokenIconUrlFromDefaultHost(tokenId: String): String { diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/UserTokensResponseFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/UserTokensResponseFactory.kt index 21a66808da..d112ad4476 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/UserTokensResponseFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/UserTokensResponseFactory.kt @@ -30,7 +30,7 @@ internal class UserTokensResponseFactory { val blockchain = getBlockchain(currency.networkId) return UserTokensResponse.Token( - id = getTokenIdString(currency.id), + id = currency.id.rawCurrencyId, networkId = blockchain.toNetworkId(), derivationPath = currency.derivationPath, name = currency.name, diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTokenConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTokenConverter.kt index fd556d4026..a6ceecff07 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTokenConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTokenConverter.kt @@ -8,7 +8,7 @@ internal class SdkTokenConverter : Converter { override fun convert(value: CryptoCurrency.Token): SdkToken { return SdkToken( - id = value.id.value.takeUnless { value.isCustom }, + id = value.id.rawCurrencyId, name = value.name, symbol = value.symbol, contractAddress = value.contractAddress, diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/CryptoCurrency.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/CryptoCurrency.kt index e523648894..d31577a3a9 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/CryptoCurrency.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/CryptoCurrency.kt @@ -65,15 +65,68 @@ sealed class CryptoCurrency { } /** - * Value class for uniquely identifying a cryptocurrency. + * Represents a unique identifier for a cryptocurrency, constructed from various components. * - * @property value The unique identifier value. + * The ID is designed to ensure that different cryptocurrencies, whether they are standard tokens, custom tokens or + * standard coins, can be distinctly identified within a system. + * + * @property value Constructed unique identifier value, made up of prefix, network ID, and suffix. + * @property rawCurrencyId Represents not unique currency ID from the blockchain network. `null` if + * its ID of the custom token. */ - @JvmInline - value class ID(val value: String) { + data class ID( + private val prefix: Prefix, + private val networkId: Network.ID, + private val suffix: Suffix, + ) { - init { - require(value.isNotBlank()) { "Crypto currency ID must not be blank" } + val value: String = buildString { + append(prefix.value) + append(networkId.value) + append(DELIMITER) + append(suffix.value) + } + + val rawCurrencyId: String? = (suffix as? Suffix.RawID)?.rawId + + /** + * Represents the different types of prefixes that can be associated with a cryptocurrency ID. + * These prefixes can help in quickly categorizing the type of cryptocurrency. + */ + enum class Prefix(val value: String) { + /** Prefix for standard coins. */ + COIN_PREFIX(value = "coin_"), + + /** Prefix for standard tokens. */ + TOKEN_PREFIX(value = "token_"), + + /** Prefix for custom tokens. */ + CUSTOM_TOKEN_PREFIX(value = "custom_"), + } + + /** + * Represents the suffix part of the cryptocurrency ID. + * + * The suffix can either be a raw ID or a contract address. + */ + sealed class Suffix { + + /** The value of the suffix, which could be either a raw ID or a contract address. */ + abstract val value: String + + /** Represents a raw ID suffix. */ + data class RawID(val rawId: String) : Suffix() { + override val value: String = rawId + } + + /** Represents a contract address suffix. */ + data class ContractAddress(val contractAddress: String) : Suffix() { + override val value: String = contractAddress + } + } + + private companion object { + const val DELIMITER = '#' } } diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/Quote.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/Quote.kt index 808d81e25a..835e84fe4f 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/Quote.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/models/Quote.kt @@ -5,12 +5,12 @@ import java.math.BigDecimal /** * Represents a financial quote for a specific cryptocurrency, including its fiat exchange rate and price change. * - * @property currencyId The unique identifier of the cryptocurrency for which the quote is provided. + * @property rawCurrencyId The unique identifier of the token for which the quote is provided. * @property fiatRate The current fiat exchange rate for the cryptocurrency. * @property priceChange The price change for the cryptocurrency. */ data class Quote( - val currencyId: CryptoCurrency.ID, + val rawCurrencyId: String, val fiatRate: BigDecimal, val priceChange: BigDecimal, ) \ No newline at end of file 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 5d17887c55..555b0fab08 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 @@ -79,7 +79,7 @@ internal class CurrenciesStatusesOperations( val quoteFlow = getQuotes(nonEmptySetOf(currency.id)) .map { maybeQuotes -> maybeQuotes.map { quotes -> - quotes.singleOrNull { it.currencyId == currency.id } + quotes.singleOrNull { it.rawCurrencyId == currency.id.rawCurrencyId } } } @@ -102,11 +102,11 @@ internal class CurrenciesStatusesOperations( quotes: Set, networkStatuses: Set, ): List { - return currencies.map { token -> - val quote = quotes.firstOrNull { it.currencyId == token.id } - val networkStatus = networkStatuses.firstOrNull { it.networkId == token.networkId } + return currencies.map { currency -> + val quote = quotes.firstOrNull { it.rawCurrencyId == currency.id.rawCurrencyId } + val networkStatus = networkStatuses.firstOrNull { it.networkId == currency.networkId } - createStatus(token, quote, networkStatus) + createStatus(currency, quote, networkStatus) } } 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 0607456029..a7e128d112 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 @@ -8,61 +8,61 @@ import java.math.BigDecimal internal object MockQuotes { val quote1 = Quote( - currencyId = MockTokens.token1.id, + rawCurrencyId = MockTokens.token1.id.rawCurrencyId!!, fiatRate = BigDecimal("1.23"), priceChange = BigDecimal("0.01"), ) val quote2 = Quote( - currencyId = MockTokens.token2.id, + rawCurrencyId = MockTokens.token2.id.rawCurrencyId!!, fiatRate = BigDecimal("2.34"), priceChange = BigDecimal("-0.02"), ) val quote3 = Quote( - currencyId = MockTokens.token3.id, + rawCurrencyId = MockTokens.token3.id.rawCurrencyId!!, fiatRate = BigDecimal("3.45"), priceChange = BigDecimal("0.03"), ) val quote4 = Quote( - currencyId = MockTokens.token4.id, + rawCurrencyId = MockTokens.token4.id.rawCurrencyId!!, fiatRate = BigDecimal("4.56"), priceChange = BigDecimal("-0.04"), ) val quote5 = Quote( - currencyId = MockTokens.token5.id, + rawCurrencyId = MockTokens.token5.id.rawCurrencyId!!, fiatRate = BigDecimal("5.67"), priceChange = BigDecimal("0.05"), ) val quote6 = Quote( - currencyId = MockTokens.token6.id, + rawCurrencyId = MockTokens.token6.id.rawCurrencyId!!, fiatRate = BigDecimal("6.78"), priceChange = BigDecimal("-0.06"), ) val quote7 = Quote( - currencyId = MockTokens.token7.id, + rawCurrencyId = MockTokens.token7.id.rawCurrencyId!!, fiatRate = BigDecimal("7.89"), priceChange = BigDecimal("0.07"), ) val quote8 = Quote( - currencyId = MockTokens.token8.id, + rawCurrencyId = MockTokens.token8.id.rawCurrencyId!!, fiatRate = BigDecimal("8.90"), priceChange = BigDecimal("-0.08"), ) val quote9 = Quote( - currencyId = MockTokens.token9.id, + rawCurrencyId = MockTokens.token9.id.rawCurrencyId!!, fiatRate = BigDecimal("9.01"), priceChange = BigDecimal("0.09"), ) val quote10 = Quote( - currencyId = MockTokens.token10.id, + rawCurrencyId = MockTokens.token10.id.rawCurrencyId!!, fiatRate = BigDecimal("10.12"), priceChange = BigDecimal("-0.10"), ) diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt index c5e38d7101..7e22b04347 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt @@ -1,12 +1,13 @@ package com.tangem.domain.tokens.mock import com.tangem.domain.tokens.models.CryptoCurrency +import com.tangem.domain.tokens.models.CryptoCurrency.ID internal object MockTokens { val token1 get() = CryptoCurrency.Coin( - id = CryptoCurrency.ID("token1"), + id = ID(ID.Prefix.COIN_PREFIX, MockNetworks.network1.id, ID.Suffix.RawID("token1")), networkId = MockNetworks.network1.id, name = "Token 1", symbol = "T1", @@ -16,7 +17,7 @@ internal object MockTokens { ) val token2 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token2"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network1.id, ID.Suffix.RawID("token2")), networkId = MockNetworks.network1.id, name = "Token 2", symbol = "T2", @@ -28,7 +29,7 @@ internal object MockTokens { ) val token3 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token3"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network1.id, ID.Suffix.RawID("token3")), networkId = MockNetworks.network1.id, name = "Token 3", symbol = "T3", @@ -40,7 +41,7 @@ internal object MockTokens { ) val token4 get() = CryptoCurrency.Coin( - id = CryptoCurrency.ID("token4"), + id = ID(ID.Prefix.COIN_PREFIX, MockNetworks.network2.id, ID.Suffix.RawID("token4")), networkId = MockNetworks.network2.id, name = "Token 4", symbol = "T4", @@ -50,7 +51,7 @@ internal object MockTokens { ) val token5 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token5"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network2.id, ID.Suffix.RawID("token5")), networkId = MockNetworks.network2.id, name = "Token 5", symbol = "T5", @@ -62,7 +63,7 @@ internal object MockTokens { ) val token6 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token6"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network2.id, ID.Suffix.RawID("token6")), networkId = MockNetworks.network2.id, name = "Token 6", symbol = "T6", @@ -74,7 +75,7 @@ internal object MockTokens { ) val token7 get() = CryptoCurrency.Coin( - id = CryptoCurrency.ID("token7"), + id = ID(ID.Prefix.COIN_PREFIX, MockNetworks.network3.id, ID.Suffix.RawID("token7")), networkId = MockNetworks.network3.id, name = "Token 7", symbol = "T7", @@ -84,7 +85,7 @@ internal object MockTokens { ) val token8 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token8"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network3.id, ID.Suffix.RawID("token8")), networkId = MockNetworks.network3.id, name = "Token 8", symbol = "T8", @@ -96,7 +97,7 @@ internal object MockTokens { ) val token9 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token9"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network3.id, ID.Suffix.RawID("token9")), networkId = MockNetworks.network3.id, name = "Token 9", symbol = "T9", @@ -108,7 +109,7 @@ internal object MockTokens { ) val token10 get() = CryptoCurrency.Token( - id = CryptoCurrency.ID("token10"), + id = ID(ID.Prefix.TOKEN_PREFIX, MockNetworks.network3.id, ID.Suffix.RawID("token10")), networkId = MockNetworks.network3.id, name = "Token 10", symbol = "T10", diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt index 93acd79dc2..4dd2d81154 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt @@ -74,7 +74,7 @@ internal object MockTokensStates { val networkStatus = MockNetworks.verifiedNetworksStatuses .first { it.networkId == status.currency.networkId } val amount = (networkStatus.value as NetworkStatus.Verified).amounts[status.currency.id]!! - val quote = MockQuotes.quotes.first { it.currencyId == status.currency.id } + val quote = MockQuotes.quotes.first { it.rawCurrencyId == status.currency.id.rawCurrencyId } val fiatAmount = amount * quote.fiatRate status.copy(