Updated on 2026-08-14
This commit is contained in:
parent
b284a8195a
commit
9b70e5bc82
14 changed files with 116 additions and 77 deletions
|
|
@ -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<StoredQuote>,
|
||||
) : QuotesStore {
|
||||
|
||||
override fun get(rawCurrenciesIds: Set<String>): Flow<Set<StoredQuote>> {
|
||||
val flows = rawCurrenciesIds.map { rawCurrencyId ->
|
||||
dataStore.get(rawCurrencyId)
|
||||
override fun get(currenciesIds: Set<CryptoCurrency.ID>): Flow<Set<StoredQuote>> {
|
||||
val flows = currenciesIds.mapNotNull { currencyId ->
|
||||
dataStore.get(currencyId.rawCurrencyId ?: return@mapNotNull null)
|
||||
}
|
||||
|
||||
return combine(flows) { quotes -> quotes.toSet() }
|
||||
|
|
|
|||
|
|
@ -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<String>): Flow<Set<StoredQuote>>
|
||||
fun get(currenciesIds: Set<CryptoCurrency.ID>): Flow<Set<StoredQuote>>
|
||||
|
||||
suspend fun store(response: QuotesResponse)
|
||||
}
|
||||
|
|
@ -13,13 +13,13 @@ internal class MockQuotesRepository : QuotesRepository {
|
|||
|
||||
override fun getQuotes(currenciesIds: Set<CryptoCurrency.ID>, refresh: Boolean): Flow<Set<Quote>> {
|
||||
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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ internal class SdkTokenConverter : Converter<CryptoCurrency.Token, SdkToken> {
|
|||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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 = '#'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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<Quote>,
|
||||
networkStatuses: Set<NetworkStatus>,
|
||||
): List<CryptoCurrencyStatus> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue