From 68f5cef7b591538cef9ed50752ab37f07d17760b Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 31 Jul 2023 19:44:09 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../repository/DefaultTokensRepository.kt | 2 +- .../data/tokens/utils/CardTokensFactory.kt | 11 +- .../tokens/utils/ResponseTokensFactory.kt | 15 ++- .../data/tokens/utils/TokensOperations.kt | 122 +++++++++++------- .../tokens/utils/UserTokensResponseFactory.kt | 5 +- 5 files changed, 93 insertions(+), 62 deletions(-) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultTokensRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultTokensRepository.kt index 1c83a87d60..f38aae9394 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultTokensRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultTokensRepository.kt @@ -67,7 +67,7 @@ internal class DefaultTokensRepository( "Unable to find a user wallet with provided ID: $userWalletId" } } - require(!userWallet.isMultiCurrency) { + require(userWallet.isMultiCurrency) { "Multi currency wallet excepted, but single currency wallet was found: $userWalletId" } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CardTokensFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CardTokensFactory.kt index d41f73f91b..b569162bd8 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CardTokensFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CardTokensFactory.kt @@ -6,7 +6,6 @@ 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.Network import timber.log.Timber import com.tangem.blockchain.common.Token as SdkToken import com.tangem.domain.tokens.model.Token as DomainToken @@ -49,11 +48,11 @@ internal class CardTokensFactory(private val demoConfig: DemoConfig) { } return DomainToken( - id = getTokenId(sdkToken, blockchain), - networkId = Network.ID(blockchain.id), + id = getTokenId(blockchain, sdkToken), + networkId = getNetworkId(blockchain), name = sdkToken.name, symbol = sdkToken.symbol, - iconUrl = getCoinOrTokenIconUrl(sdkToken, blockchain), + iconUrl = getTokenIconUrl(blockchain, sdkToken), decimals = sdkToken.decimals, isCustom = false, contractAddress = sdkToken.contractAddress, @@ -69,10 +68,10 @@ internal class CardTokensFactory(private val demoConfig: DemoConfig) { return DomainToken( id = getCoinId(blockchain), - networkId = Network.ID(blockchain.id), + networkId = getNetworkId(blockchain), name = blockchain.fullName, symbol = blockchain.currency, - iconUrl = getCoinIconId(blockchain), + iconUrl = getCoinIconUrl(blockchain), decimals = blockchain.decimals(), isCustom = false, contractAddress = null, diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseTokensFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseTokensFactory.kt index 5ca7fea388..081b7ffa64 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseTokensFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseTokensFactory.kt @@ -2,11 +2,9 @@ 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.TapWorkarounds.derivationStyle 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.Network import com.tangem.domain.tokens.model.Token import timber.log.Timber import com.tangem.blockchain.common.Token as SdkToken @@ -29,17 +27,22 @@ internal class ResponseTokensFactory(private val demoConfig: DemoConfig) { } 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 = getTokenId(sdkToken, blockchain), - networkId = Network.ID(blockchain.id), + id = tokenId, + networkId = getNetworkId(blockchain), name = token.name, symbol = token.symbol, decimals = token.decimals, - iconUrl = getCoinOrTokenIconUrl(sdkToken, blockchain), + iconUrl = iconUrl, contractAddress = token.contractAddress, derivationPath = token.derivationPath, - isCustom = isCustomToken(token.id, token.derivationPath, card.derivationStyle, blockchain), + isCustom = isCustomToken(tokenId), ) } 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 72938103a5..157df77386 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 @@ -1,59 +1,26 @@ package com.tangem.data.tokens.utils import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.IconsUtil 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.Token +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" private const val TOKEN_ICON_EXT = "png" -internal fun isCustomToken( - tokenId: String?, - tokenDerivationPath: String?, - cardDerivationStyle: DerivationStyle?, - blockchain: Blockchain, -): Boolean { - if (tokenId == null) return true +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 = '#' - if (tokenDerivationPath == null || cardDerivationStyle == null) return false - - return tokenDerivationPath != blockchain.derivationPath(cardDerivationStyle)?.rawPath -} - -internal fun getTokenId(token: SdkToken?, blockchain: Blockchain): Token.ID { - val tokenId = token?.id - - return when { - token == null -> getCoinId(blockchain) - tokenId == null -> getCustomTokenId(token.contractAddress, blockchain) - else -> Token.ID(tokenId) - } -} - -internal fun getCoinId(blockchain: Blockchain): Token.ID { - val value = blockchain.toCoinId() - - return Token.ID(value) -} - -internal fun getCoinOrTokenIconUrl(token: SdkToken?, blockchain: Blockchain): String? { - val tokenId = token?.id - - return when { - token == null -> getCoinIconId(blockchain) - tokenId == null -> IconsUtil.getTokenIconUri(blockchain, token)?.toString() - else -> getTokenIconUrlFromDefaultHost(tokenId) - } -} - -internal fun getCoinIconId(blockchain: Blockchain): String { - return getTokenIconUrlFromDefaultHost(blockchain.toCoinId()) +internal fun isCustomToken(tokenId: DomainToken.ID): Boolean { + return tokenId.value.startsWith(CUSTOM_TOKEN_ID_PREFIX) } internal fun getDerivationPath(blockchain: Blockchain, card: CardDTO): String? { @@ -64,12 +31,75 @@ internal fun getDerivationPath(blockchain: Blockchain, card: CardDTO): String? { } } -private fun getCustomTokenId(contractAddress: String, blockchain: Blockchain): Token.ID { - val value = "custom_${blockchain.id}_$contractAddress" +internal fun getBlockchain(networkId: Network.ID): Blockchain { + return Blockchain.fromId(networkId.value) +} - return Token.ID(value) +internal fun getNetworkId(blockchain: Blockchain): Network.ID { + val value = blockchain.id + + return Network.ID(value) +} + +internal fun getCoinId(blockchain: Blockchain): DomainToken.ID { + return getTokenOrCoinId(blockchain, token = null) +} + +internal fun getTokenId(blockchain: Blockchain, token: SdkToken): DomainToken.ID { + return getTokenOrCoinId(blockchain, token) +} + +internal fun getResponseTokenId(token: DomainToken): String? { + return token.id.value.substringAfter(TOKEN_ID_DELIMITER) + .takeUnless { token.isCustom } +} + +internal fun getTokenIconUrl(blockchain: Blockchain, token: SdkToken): String? { + val tokenId = token.id + + return if (tokenId == null) { + IconsUtil.getTokenIconUri(blockchain, token)?.toString() + } else { + getTokenIconUrlFromDefaultHost(tokenId) + } +} + +internal fun getCoinIconUrl(blockchain: Blockchain): String? { + val coinId = when (blockchain) { + Blockchain.Unknown -> null + Blockchain.TerraV1, Blockchain.TerraV2 -> blockchain.toCoinId() + else -> blockchain.toNetworkId() + } + + return coinId?.let(::getTokenIconUrlFromDefaultHost) +} + +private fun getTokenOrCoinId(blockchain: Blockchain, token: SdkToken?): DomainToken.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 + } + + val value = buildString { + append(prefix) + append(blockchain.id) + append(TOKEN_ID_DELIMITER) + append(suffix.lowercase()) + } + + return DomainToken.ID(value) } private fun getTokenIconUrlFromDefaultHost(tokenId: String): String { - return "$DEFAULT_TOKENS_ICONS_HOST/$TOKEN_ICON_SIZE/$tokenId.$TOKEN_ICON_EXT" + return buildString { + append(DEFAULT_TOKENS_ICONS_HOST) + append('/') + append(TOKEN_ICON_SIZE) + append('/') + append(tokenId) + append('.') + append(TOKEN_ICON_EXT) + } } \ No newline at end of file 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 721dc275f6..a7c85ba0d6 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 @@ -1,6 +1,5 @@ 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.toNetworkId import com.tangem.domain.tokens.model.Token @@ -28,10 +27,10 @@ internal class UserTokensResponseFactory { } private fun createResponseToken(domainToken: Token): UserTokensResponse.Token { - val blockchain = Blockchain.fromId(domainToken.networkId.value) + val blockchain = getBlockchain(domainToken.networkId) return UserTokensResponse.Token( - id = domainToken.id.value.takeUnless { domainToken.isCustom }, + id = getResponseTokenId(domainToken), networkId = blockchain.toNetworkId(), derivationPath = domainToken.derivationPath, name = domainToken.name,