Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-29 15:52:04 +04:00
parent 292b6e93e5
commit e40ba1ab1e
3 changed files with 88 additions and 91 deletions

View file

@ -76,54 +76,39 @@ internal class DefaultCurrenciesRepository(
}
override suspend fun saveNewCurrenciesList(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
val savedResponse = requireNotNull(
value = getSavedUserTokensResponseSync(key = userWalletId),
lazyMessage = { "Saved tokens empty. Can not perform add currencies action" },
)
val newCoins = createCoinsForNewTokenList(
userWalletId = userWalletId,
newTokens = currencies.filterIsInstance<CryptoCurrency.Token>(),
)
val newCurrencies = (newCoins + currencies).distinct()
val updatedResponse = savedResponse.copy(
tokens = newCurrencies.map(userTokensResponseFactory::createResponseToken),
)
storeAndPushTokens(
userWalletId = userWalletId,
response = updatedResponse,
)
fetchExchangeableUserMarketCoinsByIds(userWalletId, updatedResponse)
withContext(dispatchers.io) {
val savedResponse = requireNotNull(
value = getSavedUserTokensResponseSync(key = userWalletId),
lazyMessage = { "Saved tokens empty. Can not perform add currencies action." },
)
val newCurrencies = populateCurrenciesWithMissedCoins(currencies)
val updatedResponse = savedResponse.copy(
tokens = newCurrencies.map(userTokensResponseFactory::createResponseToken),
)
storeAndPushTokens(
userWalletId = userWalletId,
response = updatedResponse,
)
fetchExchangeableUserMarketCoinsByIds(userWalletId, updatedResponse)
}
}
override suspend fun addCurrencies(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
return withContext(dispatchers.io) {
withContext(dispatchers.io) {
val savedCurrencies = requireNotNull(
value = getSavedUserTokensResponseSync(key = userWalletId),
lazyMessage = { "Saved tokens empty. Can not perform add currencies action" },
)
val filteredCurrencies = currencies.toMutableList()
filteredCurrencies.filterNot { currency ->
val blockchain = getBlockchain(networkId = currency.network.id)
val networkId = blockchain.toNetworkId()
val contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress
savedCurrencies.tokens.firstOrNull { token ->
token.contractAddress == contractAddress &&
token.networkId == networkId &&
token.derivationPath == currency.network.derivationPath.value
} != null
}
val newCoins = createCoinsForNewTokens(
userWalletId = userWalletId,
newTokens = filteredCurrencies.filterIsInstance<CryptoCurrency.Token>(),
savedCurrencies = savedCurrencies.tokens,
val currenciesToAdd = populateCurrenciesWithMissedCoins(
currencies = filterAlreadyAddedCurrencies(savedCurrencies.tokens, currencies),
)
val newCurrencies = (newCoins + filteredCurrencies).distinct()
val updatedResponse = savedCurrencies.copy(
tokens = savedCurrencies.tokens + newCurrencies.map(userTokensResponseFactory::createResponseToken),
tokens = savedCurrencies.tokens + currenciesToAdd.map(userTokensResponseFactory::createResponseToken),
)
storeAndPushTokens(
userWalletId = userWalletId,
@ -133,34 +118,47 @@ internal class DefaultCurrenciesRepository(
}
}
private suspend fun createCoinsForNewTokenList(
userWalletId: UserWalletId,
newTokens: List<CryptoCurrency.Token>,
): List<CryptoCurrency.Coin> {
return newTokens.mapNotNull {
cryptoCurrencyFactory.createCoin(
blockchain = getBlockchain(networkId = it.network.id),
extraDerivationPath = it.network.derivationPath.value,
scanResponse = getUserWallet(userWalletId).scanResponse,
)
}.distinct()
private fun filterAlreadyAddedCurrencies(
savedCurrencies: List<UserTokensResponse.Token>,
currenciesToAdd: List<CryptoCurrency>,
): List<CryptoCurrency> {
return currenciesToAdd.filter { currency ->
val blockchain = getBlockchain(networkId = currency.network.id)
val networkId = blockchain.toNetworkId()
val contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress
savedCurrencies.none { token ->
token.contractAddress == contractAddress &&
token.networkId == networkId &&
token.derivationPath == currency.network.derivationPath.value
}
}
}
private suspend fun createCoinsForNewTokens(
userWalletId: UserWalletId,
newTokens: List<CryptoCurrency.Token>,
savedCurrencies: List<UserTokensResponse.Token>,
): List<CryptoCurrency.Coin> {
return newTokens
.filterNot { savedCurrencies.hasCoinForToken(it.network) } // tokens without coins
.mapNotNull {
cryptoCurrencyFactory.createCoin(
blockchain = getBlockchain(networkId = it.network.id),
extraDerivationPath = it.network.derivationPath.value,
scanResponse = getUserWallet(userWalletId).scanResponse,
)
private fun populateCurrenciesWithMissedCoins(currencies: List<CryptoCurrency>): List<CryptoCurrency> {
val networkToCoin = mutableMapOf<Network, CryptoCurrency.Coin>()
val networkToTokens = mutableMapOf<Network, List<CryptoCurrency.Token>>()
currencies.forEach { currency ->
when (currency) {
is CryptoCurrency.Coin -> {
networkToCoin[currency.network] = currency
}
is CryptoCurrency.Token -> {
val tokens = networkToTokens.getOrElse(currency.network, ::emptyList)
networkToTokens[currency.network] = tokens + currency
}
}
.distinct()
}
return buildList {
networkToTokens.forEach { (network, networkTokens) ->
val networkCoin = networkToCoin[network] ?: cryptoCurrencyFactory.createCoin(network)
add(networkCoin)
addAll(networkTokens)
}
}
}
override suspend fun removeCurrency(userWalletId: UserWalletId, currency: CryptoCurrency) =