From c4b1dceb65107f96962cf42e785fc50856bdbea6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 22 Nov 2023 22:19:24 +0200 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/proxy/UserWalletManagerImpl.kt | 26 +++++++-- features/learn2earn/impl/build.gradle.kts | 1 + .../feature/swap/domain/SwapInteractorImpl.kt | 58 +++++++------------ .../swap/domain/di/SwapDomainModule.kt | 2 + libs/crypto/build.gradle.kts | 6 +- .../tangem/lib/crypto/UserWalletManager.kt | 3 +- 6 files changed, 50 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt index 74fce7b587..d53af693db 100644 --- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt @@ -6,10 +6,13 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.WalletManager import com.tangem.common.doOnFailure import com.tangem.common.extensions.guard +import com.tangem.data.tokens.utils.CryptoCurrencyFactory import com.tangem.domain.common.BlockchainNetwork import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.domain.common.util.derivationStyleProvider +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.lib.crypto.UserWalletManager @@ -20,6 +23,7 @@ import com.tangem.lib.crypto.models.ProxyAmount import com.tangem.lib.crypto.models.ProxyFiatCurrency import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.store import com.tangem.tap.userWalletsListManager import com.tangem.tap.walletCurrenciesManager import com.tangem.tap.walletStoresManager @@ -34,6 +38,8 @@ class UserWalletManagerImpl( private val walletFeatureToggles: WalletFeatureToggles, ) : UserWalletManager { + val cryptoCurrencyFactory = CryptoCurrencyFactory() + override suspend fun getUserTokens( networkId: String, derivationPath: String?, @@ -78,13 +84,21 @@ class UserWalletManagerImpl( } } - override fun getNativeTokenForNetwork(networkId: String): Currency { + override fun getNativeTokenForNetwork(networkId: String): CryptoCurrency { val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" } - return NativeToken( - id = blockchain.toCoinId(), - name = blockchain.fullName, - symbol = blockchain.currency, - networkId = networkId, + + return requireNotNull( + cryptoCurrencyFactory.createCoin( + blockchain = blockchain, + extraDerivationPath = null, + derivationStyleProvider = requireNotNull( + store.state.globalState + .userWalletsListManager + ?.selectedUserWalletSync + ?.scanResponse + ?.derivationStyleProvider, + ), + ) ) } diff --git a/features/learn2earn/impl/build.gradle.kts b/features/learn2earn/impl/build.gradle.kts index b9fb7f48a6..dcb142ae2d 100644 --- a/features/learn2earn/impl/build.gradle.kts +++ b/features/learn2earn/impl/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { implementation(project(":data:common")) implementation(project(":libs:auth")) implementation(project(":libs:crypto")) + implementation(projects.domain.tokens.models) implementation(deps.material) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 28de49180c..31e5dbaf5e 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -6,8 +6,10 @@ import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.Quote import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository +import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.feature.swap.domain.cache.SwapDataCache @@ -44,6 +46,7 @@ internal class SwapInteractorImpl @Inject constructor( private val walletFeatureToggles: WalletFeatureToggles, private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, + private val quotesRepository: QuotesRepository, ) : SwapInteractor { // TODO: Move to DI @@ -389,32 +392,6 @@ internal class SwapInteractorImpl @Inject constructor( } } - @Suppress("UnusedPrivateMember") - @Deprecated("used in old swap mechanism") - private fun getTokensWithBalance( - tokens: List, - balances: Map, - rates: Map, - appCurrency: ProxyFiatCurrency, - ): List { - return tokens.map { - val balance = balances[it.symbol] - TokenWithBalance( - token = it, - tokenBalanceData = TokenBalanceData( - amount = balance?.let { amount -> - amountFormatter.formatSwapAmountToUI(amount, it.symbol) - }, - amountEquivalent = balance?.value?.toFiatString( - rateValue = rates[it.id]?.toBigDecimal() ?: BigDecimal.ZERO, - fiatCurrencyName = appCurrency.symbol, - formatWithSpaces = true, - ), - ), - ) - } - } - private suspend fun isAllowedToSpend(networkId: String, fromToken: CryptoCurrency, amount: SwapAmount): Boolean { if (fromToken is CryptoCurrency.Coin) return true return getSelectedWalletSyncUseCase().fold( @@ -538,8 +515,8 @@ internal class SwapInteractorImpl @Inject constructor( private suspend fun getFormattedFiatFees(networkId: String, vararg fees: BigDecimal): List { val appCurrency = userWalletManager.getUserAppCurrency() val nativeToken = userWalletManager.getNativeTokenForNetwork(networkId) - val rates = repository.getRates(appCurrency.code, listOf(nativeToken.id)) - return rates[nativeToken.id]?.toBigDecimal()?.let { rate -> + val rates = getQuotes(nativeToken.id) + return rates[nativeToken.id]?.fiatRate?.let { rate -> fees.map { fee -> " (${fee.toFiatString(rate, appCurrency.symbol, true)})" } @@ -629,28 +606,26 @@ internal class SwapInteractorImpl @Inject constructor( val toToken = toTokenStatus.currency val appCurrency = userWalletManager.getUserAppCurrency() val nativeToken = userWalletManager.getNativeTokenForNetwork(networkId) - val rates = repository.getRates( - appCurrency.code, - listOf(fromToken.network.backendId, toToken.network.backendId, nativeToken.id), - ) + + val rates = getQuotes(fromToken.id, toToken.id, nativeToken.id) return SwapState.QuotesLoadedState( fromTokenInfo = TokenSwapInfo( tokenAmount = fromTokenAmount, cryptoCurrencyStatus = fromTokenStatus, - amountFiat = rates[fromToken.network.backendId]?.toBigDecimal()?.multiply(fromTokenAmount.value) + amountFiat = rates[fromToken.id]?.fiatRate?.multiply(fromTokenAmount.value) ?: BigDecimal.ZERO, ), toTokenInfo = TokenSwapInfo( tokenAmount = toTokenAmount, cryptoCurrencyStatus = toTokenStatus, - amountFiat = rates[toToken.network.backendId]?.toBigDecimal()?.multiply(toTokenAmount.value) + amountFiat = rates[toToken.id]?.fiatRate?.multiply(toTokenAmount.value) ?: BigDecimal.ZERO, ), priceImpact = calculatePriceImpact( fromTokenAmount = fromTokenAmount.value, - fromRate = rates[fromToken.network.backendId] ?: 0.0, + fromRate = rates[fromToken.id]?.fiatRate?.toDouble() ?: 0.0, toTokenAmount = toTokenAmount.value, - toRate = rates[toToken.network.backendId] ?: 0.0, + toRate = rates[toToken.id]?.fiatRate?.toDouble() ?: 0.0, ), networkCurrency = userWalletManager.getNetworkCurrency(networkId), swapDataModel = swapStateData, @@ -687,7 +662,7 @@ internal class SwapInteractorImpl @Inject constructor( val feeData = transactionManager.getFee( networkId = networkId, amountToSend = BigDecimal.ZERO, - currencyToSend = userWalletManager.getNativeTokenForNetwork(networkId), + currencyToSend = swapCurrencyConverter.convert(userWalletManager.getNativeTokenForNetwork(networkId)), destinationAddress = getTokenAddress(fromToken), increaseBy = INCREASE_GAS_LIMIT_BY, data = transactionData, @@ -863,6 +838,15 @@ internal class SwapInteractorImpl @Inject constructor( ) } + private suspend fun getQuotes(vararg ids: CryptoCurrency.ID) : Map { + val set = quotesRepository.getQuotesSync(ids.toSet(), false) + + return ids + .mapNotNull { id -> set.find { it.rawCurrencyId == id.rawCurrencyId }?.let { id to it } } + .toMap() + } + + companion object { private const val DEFAULT_SLIPPAGE = 2 diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt index 8845c68949..bdcfad48f9 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt @@ -35,6 +35,7 @@ class SwapDomainModule { walletFeatureToggles: WalletFeatureToggles, @SwapScope getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, @SwapScope getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, + quotesRepository: QuotesRepository, ): SwapInteractor { return SwapInteractorImpl( transactionManager = transactionManager, @@ -47,6 +48,7 @@ class SwapDomainModule { walletFeatureToggles = walletFeatureToggles, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getMultiCryptoCurrencyStatusUseCase = getCryptoCurrencyStatusUseCase, + quotesRepository = quotesRepository, ) } diff --git a/libs/crypto/build.gradle.kts b/libs/crypto/build.gradle.kts index 248cc20bd1..f8a413d31d 100644 --- a/libs/crypto/build.gradle.kts +++ b/libs/crypto/build.gradle.kts @@ -1,10 +1,12 @@ plugins { - alias(deps.plugins.kotlin.jvm) + alias(deps.plugins.android.library) + alias(deps.plugins.kotlin.android) id("configuration") } dependencies { - /** Coroutines */ implementation(deps.kotlin.coroutines) + implementation(projects.domain.tokens.models) + } \ No newline at end of file diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt index 0a489b3498..c18bc06e73 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt @@ -1,5 +1,6 @@ package com.tangem.lib.crypto +import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.lib.crypto.models.Currency import com.tangem.lib.crypto.models.ProxyAmount import com.tangem.lib.crypto.models.ProxyFiatCurrency @@ -16,7 +17,7 @@ interface UserWalletManager { suspend fun getUserTokens(networkId: String, derivationPath: String?, isExcludeCustom: Boolean): List @Throws(IllegalStateException::class) - fun getNativeTokenForNetwork(networkId: String): Currency + fun getNativeTokenForNetwork(networkId: String): CryptoCurrency /** * Returns user walletId or empty string