Updated on 2026-08-14
This commit is contained in:
parent
642bcca31f
commit
81a16c8bb1
46 changed files with 610 additions and 615 deletions
|
|
@ -7,61 +7,61 @@ import java.math.BigDecimal
|
|||
internal object MockQuotes {
|
||||
|
||||
val quote1 = Quote(
|
||||
tokenId = MockTokens.token1.id,
|
||||
currencyId = MockTokens.token1.id,
|
||||
fiatRate = BigDecimal("1.23"),
|
||||
priceChange = BigDecimal("0.01"),
|
||||
)
|
||||
|
||||
val quote2 = Quote(
|
||||
tokenId = MockTokens.token2.id,
|
||||
currencyId = MockTokens.token2.id,
|
||||
fiatRate = BigDecimal("2.34"),
|
||||
priceChange = BigDecimal("-0.02"),
|
||||
)
|
||||
|
||||
val quote3 = Quote(
|
||||
tokenId = MockTokens.token3.id,
|
||||
currencyId = MockTokens.token3.id,
|
||||
fiatRate = BigDecimal("3.45"),
|
||||
priceChange = BigDecimal("0.03"),
|
||||
)
|
||||
|
||||
val quote4 = Quote(
|
||||
tokenId = MockTokens.token4.id,
|
||||
currencyId = MockTokens.token4.id,
|
||||
fiatRate = BigDecimal("4.56"),
|
||||
priceChange = BigDecimal("-0.04"),
|
||||
)
|
||||
|
||||
val quote5 = Quote(
|
||||
tokenId = MockTokens.token5.id,
|
||||
currencyId = MockTokens.token5.id,
|
||||
fiatRate = BigDecimal("5.67"),
|
||||
priceChange = BigDecimal("0.05"),
|
||||
)
|
||||
|
||||
val quote6 = Quote(
|
||||
tokenId = MockTokens.token6.id,
|
||||
currencyId = MockTokens.token6.id,
|
||||
fiatRate = BigDecimal("6.78"),
|
||||
priceChange = BigDecimal("-0.06"),
|
||||
)
|
||||
|
||||
val quote7 = Quote(
|
||||
tokenId = MockTokens.token7.id,
|
||||
currencyId = MockTokens.token7.id,
|
||||
fiatRate = BigDecimal("7.89"),
|
||||
priceChange = BigDecimal("0.07"),
|
||||
)
|
||||
|
||||
val quote8 = Quote(
|
||||
tokenId = MockTokens.token8.id,
|
||||
currencyId = MockTokens.token8.id,
|
||||
fiatRate = BigDecimal("8.90"),
|
||||
priceChange = BigDecimal("-0.08"),
|
||||
)
|
||||
|
||||
val quote9 = Quote(
|
||||
tokenId = MockTokens.token9.id,
|
||||
currencyId = MockTokens.token9.id,
|
||||
fiatRate = BigDecimal("9.01"),
|
||||
priceChange = BigDecimal("0.09"),
|
||||
)
|
||||
|
||||
val quote10 = Quote(
|
||||
tokenId = MockTokens.token10.id,
|
||||
currencyId = MockTokens.token10.id,
|
||||
fiatRate = BigDecimal("10.12"),
|
||||
priceChange = BigDecimal("-0.10"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,25 +1,23 @@
|
|||
package com.tangem.data.tokens.mock
|
||||
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal object MockTokens {
|
||||
|
||||
val token1
|
||||
get() = Token(
|
||||
id = Token.ID("token1"),
|
||||
get() = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID("token1"),
|
||||
networkId = MockNetworks.network1.id,
|
||||
name = "Token 1",
|
||||
symbol = "T1",
|
||||
isCustom = false,
|
||||
decimals = 8,
|
||||
iconUrl = null,
|
||||
contractAddress = null,
|
||||
derivationPath = null,
|
||||
)
|
||||
val token2
|
||||
get() = Token(
|
||||
id = Token.ID("token2"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token2"),
|
||||
networkId = MockNetworks.network1.id,
|
||||
name = "Token 2",
|
||||
symbol = "T2",
|
||||
|
|
@ -30,8 +28,8 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token3
|
||||
get() = Token(
|
||||
id = Token.ID("token3"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token3"),
|
||||
networkId = MockNetworks.network1.id,
|
||||
name = "Token 3",
|
||||
symbol = "T3",
|
||||
|
|
@ -42,20 +40,18 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token4
|
||||
get() = Token(
|
||||
id = Token.ID("token4"),
|
||||
get() = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID("token4"),
|
||||
networkId = MockNetworks.network2.id,
|
||||
name = "Token 4",
|
||||
symbol = "T4",
|
||||
isCustom = false,
|
||||
decimals = 8,
|
||||
iconUrl = null,
|
||||
contractAddress = null,
|
||||
derivationPath = null,
|
||||
)
|
||||
val token5
|
||||
get() = Token(
|
||||
id = Token.ID("token5"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token5"),
|
||||
networkId = MockNetworks.network2.id,
|
||||
name = "Token 5",
|
||||
symbol = "T5",
|
||||
|
|
@ -66,8 +62,8 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token6
|
||||
get() = Token(
|
||||
id = Token.ID("token6"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token6"),
|
||||
networkId = MockNetworks.network2.id,
|
||||
name = "Token 6",
|
||||
symbol = "T6",
|
||||
|
|
@ -78,20 +74,18 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token7
|
||||
get() = Token(
|
||||
id = Token.ID("token7"),
|
||||
get() = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID("token7"),
|
||||
networkId = MockNetworks.network3.id,
|
||||
name = "Token 7",
|
||||
symbol = "T7",
|
||||
isCustom = false,
|
||||
decimals = 8,
|
||||
iconUrl = null,
|
||||
contractAddress = null,
|
||||
derivationPath = null,
|
||||
)
|
||||
val token8
|
||||
get() = Token(
|
||||
id = Token.ID("token8"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token8"),
|
||||
networkId = MockNetworks.network3.id,
|
||||
name = "Token 8",
|
||||
symbol = "T8",
|
||||
|
|
@ -102,8 +96,8 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token9
|
||||
get() = Token(
|
||||
id = Token.ID("token9"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token9"),
|
||||
networkId = MockNetworks.network3.id,
|
||||
name = "Token 9",
|
||||
symbol = "T9",
|
||||
|
|
@ -114,8 +108,8 @@ internal object MockTokens {
|
|||
derivationPath = null,
|
||||
)
|
||||
val token10
|
||||
get() = Token(
|
||||
id = Token.ID("token10"),
|
||||
get() = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID("token10"),
|
||||
networkId = MockNetworks.network3.id,
|
||||
name = "Token 10",
|
||||
symbol = "T10",
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import com.tangem.data.common.cache.CacheRegistry
|
||||
import com.tangem.data.tokens.utils.CardTokensFactory
|
||||
import com.tangem.data.tokens.utils.ResponseTokensFactory
|
||||
import com.tangem.data.tokens.utils.CardCurrenciesFactory
|
||||
import com.tangem.data.tokens.utils.ResponseCurrenciesFactory
|
||||
import com.tangem.data.tokens.utils.UserTokensResponseFactory
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.repository.TokensRepository
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
|
@ -27,18 +27,18 @@ internal class DefaultTokensRepository(
|
|||
) : TokensRepository {
|
||||
|
||||
private val demoConfig = DemoConfig()
|
||||
private val responseTokensFactory = ResponseTokensFactory(demoConfig)
|
||||
private val cardTokensFactory = CardTokensFactory(demoConfig)
|
||||
private val responseCurrenciesFactory = ResponseCurrenciesFactory(demoConfig)
|
||||
private val cardCurrenciesFactory = CardCurrenciesFactory(demoConfig)
|
||||
private val userTokensResponseFactory = UserTokensResponseFactory()
|
||||
|
||||
override suspend fun saveTokens(
|
||||
userWalletId: UserWalletId,
|
||||
tokens: Set<Token>,
|
||||
currencies: Set<CryptoCurrency>,
|
||||
isGroupedByNetwork: Boolean,
|
||||
isSortedByBalance: Boolean,
|
||||
) = withContext(dispatchers.io) {
|
||||
val response = userTokensResponseFactory.createUserTokensResponse(
|
||||
tokens = tokens,
|
||||
currencies = currencies,
|
||||
isGroupedByNetwork = isGroupedByNetwork,
|
||||
isSortedByBalance = isSortedByBalance,
|
||||
)
|
||||
|
|
@ -46,7 +46,7 @@ internal class DefaultTokensRepository(
|
|||
storeAndPushTokens(userWalletId, response)
|
||||
}
|
||||
|
||||
override suspend fun getSingleCurrencyWalletToken(userWalletId: UserWalletId): Token {
|
||||
override suspend fun getPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {
|
||||
val userWallet = withContext(dispatchers.io) {
|
||||
requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) {
|
||||
"Unable to find a user wallet with provided ID: $userWalletId"
|
||||
|
|
@ -56,11 +56,13 @@ internal class DefaultTokensRepository(
|
|||
"Single currency wallet excepted, but multi currency wallet was found: $userWalletId"
|
||||
}
|
||||
|
||||
return cardTokensFactory
|
||||
.createPrimaryTokenForSingleCurrencyCard(userWallet.scanResponse)
|
||||
return cardCurrenciesFactory.createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse)
|
||||
}
|
||||
|
||||
override fun getMultiCurrencyWalletTokens(userWalletId: UserWalletId, refresh: Boolean): Flow<Set<Token>> {
|
||||
override fun getMultiCurrencyWalletCurrencies(
|
||||
userWalletId: UserWalletId,
|
||||
refresh: Boolean,
|
||||
): Flow<Set<CryptoCurrency>> {
|
||||
return channelFlow {
|
||||
val userWallet = withContext(dispatchers.io) {
|
||||
requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) {
|
||||
|
|
@ -72,7 +74,7 @@ internal class DefaultTokensRepository(
|
|||
}
|
||||
|
||||
launch(dispatchers.io) {
|
||||
getMultiCurrencyWalletTokens(userWallet).collectLatest(::send)
|
||||
getMultiCurrencyWalletCurrencies(userWallet).collectLatest(::send)
|
||||
}
|
||||
|
||||
launch(dispatchers.io) {
|
||||
|
|
@ -93,9 +95,9 @@ internal class DefaultTokensRepository(
|
|||
.flowOn(dispatchers.io)
|
||||
}
|
||||
|
||||
private fun getMultiCurrencyWalletTokens(userWallet: UserWallet): Flow<Set<Token>> {
|
||||
private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow<Set<CryptoCurrency>> {
|
||||
return userTokensStore.get(userWallet.walletId).map { storedTokens ->
|
||||
responseTokensFactory.createTokens(
|
||||
responseCurrenciesFactory.createTokens(
|
||||
response = storedTokens,
|
||||
card = userWallet.scanResponse.card,
|
||||
)
|
||||
|
|
@ -131,7 +133,9 @@ internal class DefaultTokensRepository(
|
|||
if (NOT_FOUND_HTTP_CODE in errorMessage) {
|
||||
val response = userTokensStore.getSyncOrNull(userWallet.walletId)
|
||||
?: userTokensResponseFactory.createUserTokensResponse(
|
||||
tokens = cardTokensFactory.createDefaultTokensForMultiCurrencyCard(userWallet.scanResponse.card),
|
||||
currencies = cardCurrenciesFactory.createDefaultCoinsForMultiCurrencyCard(
|
||||
userWallet.scanResponse.card,
|
||||
),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import com.tangem.data.tokens.mock.MockNetworks
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -19,7 +19,7 @@ internal class MockNetworksRepository : NetworksRepository {
|
|||
|
||||
override fun getNetworkStatuses(
|
||||
userWalletId: UserWalletId,
|
||||
networks: Map<Network.ID, Set<Token.ID>>,
|
||||
networks: Map<Network.ID, Set<CryptoCurrency.ID>>,
|
||||
refresh: Boolean,
|
||||
): Flow<Set<NetworkStatus>> {
|
||||
return flowOf(
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import com.tangem.data.tokens.mock.MockQuotes
|
||||
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 kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
internal class MockQuotesRepository : QuotesRepository {
|
||||
|
||||
override fun getQuotes(tokensIds: Set<Token.ID>, refresh: Boolean): Flow<Set<Quote>> {
|
||||
override fun getQuotes(tokensIds: Set<CryptoCurrency.ID>, refresh: Boolean): Flow<Set<Quote>> {
|
||||
return flowOf(
|
||||
MockQuotes.quotes
|
||||
.filter { it.tokenId in tokensIds }
|
||||
.filter { it.currencyId in tokensIds }
|
||||
.toSet(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import com.tangem.domain.common.util.cardTypesResolver
|
|||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import timber.log.Timber
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
import com.tangem.domain.tokens.model.Token as DomainToken
|
||||
|
||||
internal class CardTokensFactory(private val demoConfig: DemoConfig) {
|
||||
internal class CardCurrenciesFactory(private val demoConfig: DemoConfig) {
|
||||
|
||||
fun createDefaultTokensForMultiCurrencyCard(card: CardDTO): Set<DomainToken> {
|
||||
fun createDefaultCoinsForMultiCurrencyCard(card: CardDTO): Set<CryptoCurrency.Coin> {
|
||||
var blockchains = if (demoConfig.isDemoCardId(card.cardId)) {
|
||||
demoConfig.demoBlockchains
|
||||
} else {
|
||||
|
|
@ -26,7 +26,7 @@ internal class CardTokensFactory(private val demoConfig: DemoConfig) {
|
|||
return blockchains.mapNotNull { createCoin(it, card) }.toSet()
|
||||
}
|
||||
|
||||
fun createPrimaryTokenForSingleCurrencyCard(scanResponse: ScanResponse): DomainToken {
|
||||
fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency {
|
||||
val card = scanResponse.card
|
||||
val resolver = scanResponse.cardTypesResolver
|
||||
val blockchain = resolver.getBlockchain()
|
||||
|
|
@ -41,13 +41,13 @@ internal class CardTokensFactory(private val demoConfig: DemoConfig) {
|
|||
return primaryToken ?: coin
|
||||
}
|
||||
|
||||
private fun createToken(sdkToken: SdkToken, blockchain: Blockchain, card: CardDTO): DomainToken? {
|
||||
private fun createToken(sdkToken: SdkToken, blockchain: Blockchain, card: CardDTO): CryptoCurrency.Token? {
|
||||
if (blockchain != Blockchain.Unknown) {
|
||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||
return null
|
||||
}
|
||||
|
||||
return DomainToken(
|
||||
return CryptoCurrency.Token(
|
||||
id = getTokenId(blockchain, sdkToken),
|
||||
networkId = getNetworkId(blockchain),
|
||||
name = sdkToken.name,
|
||||
|
|
@ -60,21 +60,19 @@ internal class CardTokensFactory(private val demoConfig: DemoConfig) {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createCoin(blockchain: Blockchain, card: CardDTO): DomainToken? {
|
||||
private fun createCoin(blockchain: Blockchain, card: CardDTO): CryptoCurrency.Coin? {
|
||||
if (blockchain != Blockchain.Unknown) {
|
||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||
return null
|
||||
}
|
||||
|
||||
return DomainToken(
|
||||
return CryptoCurrency.Coin(
|
||||
id = getCoinId(blockchain),
|
||||
networkId = getNetworkId(blockchain),
|
||||
name = blockchain.fullName,
|
||||
symbol = blockchain.currency,
|
||||
iconUrl = getCoinIconUrl(blockchain),
|
||||
decimals = blockchain.decimals(),
|
||||
isCustom = false,
|
||||
contractAddress = null,
|
||||
derivationPath = getDerivationPath(blockchain, card),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.tangem.data.tokens.utils
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import timber.log.Timber
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
|
||||
internal class ResponseCurrenciesFactory(private val demoConfig: DemoConfig) {
|
||||
|
||||
fun createTokens(response: UserTokensResponse, card: CardDTO): Set<CryptoCurrency> {
|
||||
return response.tokens.mapNotNull { createToken(it, card) }.toSet()
|
||||
}
|
||||
|
||||
private fun createToken(responseToken: UserTokensResponse.Token, card: CardDTO): CryptoCurrency? {
|
||||
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
|
||||
if (blockchain == null || blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")
|
||||
return null
|
||||
}
|
||||
|
||||
if (demoConfig.isDemoCardId(card.cardId)) {
|
||||
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
||||
}
|
||||
|
||||
val sdkToken = createSdkToken(responseToken)
|
||||
return if (sdkToken == null) {
|
||||
createCoin(blockchain, responseToken)
|
||||
} else {
|
||||
createToken(blockchain, sdkToken, responseToken.derivationPath)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSdkToken(token: UserTokensResponse.Token): SdkToken? {
|
||||
return token.contractAddress?.let { contractAddress ->
|
||||
SdkToken(
|
||||
name = token.name,
|
||||
symbol = token.symbol,
|
||||
contractAddress = contractAddress,
|
||||
decimals = token.decimals,
|
||||
id = token.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCoin(blockchain: Blockchain, responseToken: UserTokensResponse.Token): CryptoCurrency.Coin {
|
||||
return CryptoCurrency.Coin(
|
||||
id = getCoinId(blockchain),
|
||||
networkId = getNetworkId(blockchain),
|
||||
name = responseToken.name,
|
||||
symbol = responseToken.symbol,
|
||||
decimals = responseToken.decimals,
|
||||
derivationPath = responseToken.derivationPath,
|
||||
iconUrl = getCoinIconUrl(blockchain),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createToken(blockchain: Blockchain, sdkToken: Token, derivationPath: String?): CryptoCurrency.Token {
|
||||
val id = getTokenId(blockchain, sdkToken)
|
||||
|
||||
return CryptoCurrency.Token(
|
||||
id = id,
|
||||
networkId = getNetworkId(blockchain),
|
||||
name = sdkToken.name,
|
||||
symbol = sdkToken.symbol,
|
||||
decimals = sdkToken.decimals,
|
||||
derivationPath = derivationPath,
|
||||
iconUrl = getTokenIconUrl(blockchain, sdkToken),
|
||||
contractAddress = sdkToken.contractAddress,
|
||||
isCustom = isCustomToken(id),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package com.tangem.data.tokens.utils
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import timber.log.Timber
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
|
||||
internal class ResponseTokensFactory(private val demoConfig: DemoConfig) {
|
||||
|
||||
fun createTokens(response: UserTokensResponse, card: CardDTO): Set<Token> {
|
||||
return response.tokens.mapNotNull { createToken(it, card) }.toSet()
|
||||
}
|
||||
|
||||
private fun createToken(token: UserTokensResponse.Token, card: CardDTO): Token? {
|
||||
var blockchain = Blockchain.fromNetworkId(token.networkId)
|
||||
if (blockchain == null) {
|
||||
Timber.e("Unable to find a blockchain with the network ID: ${token.networkId}")
|
||||
return null
|
||||
}
|
||||
|
||||
if (demoConfig.isDemoCardId(card.cardId)) {
|
||||
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
||||
}
|
||||
|
||||
val sdkToken = createSdkToken(token)
|
||||
val (tokenId, iconUrl) = if (sdkToken == null) {
|
||||
getCoinId(blockchain) to getCoinIconUrl(blockchain)
|
||||
} else {
|
||||
getTokenId(blockchain, sdkToken) to getTokenIconUrl(blockchain, sdkToken)
|
||||
}
|
||||
|
||||
return Token(
|
||||
id = tokenId,
|
||||
networkId = getNetworkId(blockchain),
|
||||
name = token.name,
|
||||
symbol = token.symbol,
|
||||
decimals = token.decimals,
|
||||
iconUrl = iconUrl,
|
||||
contractAddress = token.contractAddress,
|
||||
derivationPath = token.derivationPath,
|
||||
isCustom = isCustomToken(tokenId),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSdkToken(token: UserTokensResponse.Token): SdkToken? {
|
||||
return token.contractAddress?.let { contractAddress ->
|
||||
SdkToken(
|
||||
name = token.name,
|
||||
symbol = token.symbol,
|
||||
contractAddress = contractAddress,
|
||||
decimals = token.decimals,
|
||||
id = token.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ 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.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
import com.tangem.domain.tokens.model.Token as DomainToken
|
||||
|
||||
private const val DEFAULT_TOKENS_ICONS_HOST = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins"
|
||||
private const val TOKEN_ICON_SIZE = "large"
|
||||
|
|
@ -19,7 +19,7 @@ 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: DomainToken.ID): Boolean {
|
||||
internal fun isCustomToken(tokenId: CryptoCurrency.ID): Boolean {
|
||||
return tokenId.value.startsWith(CUSTOM_TOKEN_ID_PREFIX)
|
||||
}
|
||||
|
||||
|
|
@ -41,17 +41,17 @@ internal fun getNetworkId(blockchain: Blockchain): Network.ID {
|
|||
return Network.ID(value)
|
||||
}
|
||||
|
||||
internal fun getCoinId(blockchain: Blockchain): DomainToken.ID {
|
||||
internal fun getCoinId(blockchain: Blockchain): CryptoCurrency.ID {
|
||||
return getTokenOrCoinId(blockchain, token = null)
|
||||
}
|
||||
|
||||
internal fun getTokenId(blockchain: Blockchain, token: SdkToken): DomainToken.ID {
|
||||
internal fun getTokenId(blockchain: Blockchain, token: SdkToken): CryptoCurrency.ID {
|
||||
return getTokenOrCoinId(blockchain, token)
|
||||
}
|
||||
|
||||
internal fun getResponseTokenId(token: DomainToken): String? {
|
||||
return token.id.value.substringAfter(TOKEN_ID_DELIMITER)
|
||||
.takeUnless { token.isCustom }
|
||||
internal fun getResponseTokenId(currency: CryptoCurrency): String? {
|
||||
return currency.id.value.substringAfter(TOKEN_ID_DELIMITER)
|
||||
.takeUnless { currency is CryptoCurrency.Token && currency.isCustom }
|
||||
}
|
||||
|
||||
internal fun getTokenIconUrl(blockchain: Blockchain, token: SdkToken): String? {
|
||||
|
|
@ -74,7 +74,7 @@ internal fun getCoinIconUrl(blockchain: Blockchain): String? {
|
|||
return coinId?.let(::getTokenIconUrlFromDefaultHost)
|
||||
}
|
||||
|
||||
private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): DomainToken.ID {
|
||||
private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): CryptoCurrency.ID {
|
||||
val sdkTokenId = token?.id
|
||||
val (prefix, suffix) = when {
|
||||
token == null -> COIN_ID_PREFIX to blockchain.toCoinId()
|
||||
|
|
@ -89,7 +89,7 @@ private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): DomainTo
|
|||
append(suffix.lowercase())
|
||||
}
|
||||
|
||||
return DomainToken.ID(value)
|
||||
return CryptoCurrency.ID(value)
|
||||
}
|
||||
|
||||
private fun getTokenIconUrlFromDefaultHost(tokenId: String): String {
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@ package com.tangem.data.tokens.utils
|
|||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
||||
internal class UserTokensResponseFactory {
|
||||
|
||||
fun createUserTokensResponse(
|
||||
tokens: Set<Token>,
|
||||
currencies: Set<CryptoCurrency>,
|
||||
isGroupedByNetwork: Boolean,
|
||||
isSortedByBalance: Boolean,
|
||||
): UserTokensResponse {
|
||||
return UserTokensResponse(
|
||||
tokens = tokens.map(::createResponseToken),
|
||||
tokens = currencies.map(::createResponseToken),
|
||||
group = if (isGroupedByNetwork) {
|
||||
UserTokensResponse.GroupType.NETWORK
|
||||
} else {
|
||||
|
|
@ -26,17 +26,17 @@ internal class UserTokensResponseFactory {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createResponseToken(domainToken: Token): UserTokensResponse.Token {
|
||||
val blockchain = getBlockchain(domainToken.networkId)
|
||||
private fun createResponseToken(currency: CryptoCurrency): UserTokensResponse.Token {
|
||||
val blockchain = getBlockchain(currency.networkId)
|
||||
|
||||
return UserTokensResponse.Token(
|
||||
id = getResponseTokenId(domainToken),
|
||||
id = getResponseTokenId(currency),
|
||||
networkId = blockchain.toNetworkId(),
|
||||
derivationPath = domainToken.derivationPath,
|
||||
name = domainToken.name,
|
||||
symbol = domainToken.symbol,
|
||||
decimals = domainToken.decimals,
|
||||
contractAddress = domainToken.contractAddress,
|
||||
derivationPath = currency.derivationPath,
|
||||
name = currency.name,
|
||||
symbol = currency.symbol,
|
||||
decimals = currency.decimals,
|
||||
contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue