From 807233e9097e5a183d7516d0e852946308326d54 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 28 Nov 2023 11:32:59 +0200 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TransactionDomainModule.kt | 1 - features/swap/domain/build.gradle.kts | 2 + .../feature/swap/domain/SwapInteractor.kt | 9 +- .../feature/swap/domain/SwapInteractorImpl.kt | 83 ++++++++++++++++--- .../swap/domain/di/SwapDomainModule.kt | 21 +++++ .../feature/swap/viewmodels/SwapViewModel.kt | 10 ++- 6 files changed, 106 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index 8dfb19bd16..ead5fca293 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -36,7 +36,6 @@ internal object TransactionDomainModule { isDemoCardUseCase = isDemoCardUseCase, cardSdkConfigRepository = cardSdkConfigRepository, walletManagersFacade = walletManagersFacade, - ) } } \ No newline at end of file diff --git a/features/swap/domain/build.gradle.kts b/features/swap/domain/build.gradle.kts index 00bcf936c1..4f4d42fe13 100644 --- a/features/swap/domain/build.gradle.kts +++ b/features/swap/domain/build.gradle.kts @@ -25,6 +25,8 @@ dependencies { implementation(projects.domain.wallets.models) implementation(projects.domain.transaction) implementation(projects.domain.legacy) + implementation(projects.domain.demo) + implementation(projects.domain.card) /** Core modules */ implementation(projects.core.utils) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt index 1057373c25..aa76195519 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt @@ -4,6 +4,7 @@ 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.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.swap.domain.models.SwapAmount import com.tangem.feature.swap.domain.models.domain.* import com.tangem.feature.swap.domain.models.ui.* @@ -68,11 +69,11 @@ interface SwapInteractor { @Suppress("LongParameterList") @Throws(IllegalStateException::class) suspend fun onSwap( - exchangeProviderType: ExchangeProviderType, + swapProvider: SwapProvider, networkId: String, - swapData: SwapDataModel, - currencyToSend: CryptoCurrency, - currencyToGet: CryptoCurrency, + swapData: SwapDataModel?, + currencyToSend: CryptoCurrencyStatus, + currencyToGet: CryptoCurrencyStatus, amountToSwap: String, fee: TxFee, ): TxState 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 7b8944fe0a..9d8e7109d5 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 @@ -1,6 +1,7 @@ package com.tangem.feature.swap.domain import arrow.core.getOrElse +import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase @@ -12,9 +13,13 @@ 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.tokens.utils.convertToAmount +import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.usecase.GetFeeUseCase +import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.feature.swap.domain.cache.SwapDataCache import com.tangem.feature.swap.domain.converters.SwapCurrencyConverter @@ -50,6 +55,7 @@ internal class SwapInteractorImpl @Inject constructor( private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, private val walletManagersFacade: WalletManagersFacade, + private val sendTransactionUseCase: SendTransactionUseCase, private val quotesRepository: QuotesRepository, private val dispatcher: CoroutineDispatcherProvider, ) : SwapInteractor { @@ -359,24 +365,34 @@ internal class SwapInteractorImpl @Inject constructor( @Deprecated("used in old swap mechanism") override suspend fun onSwap( - exchangeProviderType: ExchangeProviderType, + swapProvider: SwapProvider, networkId: String, - swapData: SwapDataModel, - currencyToSend: CryptoCurrency, - currencyToGet: CryptoCurrency, + swapData: SwapDataModel?, + currencyToSend: CryptoCurrencyStatus, + currencyToGet: CryptoCurrencyStatus, amountToSwap: String, fee: TxFee, ): TxState { - return when (exchangeProviderType) { + return when (swapProvider.type) { ExchangeProviderType.CEX -> { - onSwapCex() + val amountDecimal = toBigDecimalOrNull(amountToSwap) + val amount = SwapAmount(requireNotNull(amountDecimal), getTokenDecimals(currencyToSend.currency)) + + onSwapCex( + currencyToSend = currencyToSend, + currencyToGet = currencyToGet, + amount = amount, + fee = fee, + providerId = swapProvider.providerId, + userWalletId = requireNotNull(getSelectedWallet()).walletId + ) } ExchangeProviderType.DEX -> { onSwapDex( networkId = networkId, - swapData = swapData, - currencyToSend = currencyToSend, - currencyToGet = currencyToGet, + swapData = requireNotNull(swapData), + currencyToSend = currencyToSend.currency, + currencyToGet = currencyToGet.currency, amountToSwap = amountToSwap, fee = fee, ) @@ -468,8 +484,53 @@ internal class SwapInteractorImpl @Inject constructor( } } - private fun onSwapCex(): TxState { - TODO() + private suspend fun onSwapCex( + currencyToSend: CryptoCurrencyStatus, + currencyToGet: CryptoCurrencyStatus, + amount: SwapAmount, + fee: TxFee, + providerId: String, + userWalletId: UserWalletId + ): TxState { + val exchangeData = repository.getExchangeData( + fromContractAddress = currencyToSend.currency.getContractAddress(), + fromNetwork = currencyToSend.currency.network.backendId, + toContractAddress = currencyToGet.currency.getContractAddress(), + toNetwork = currencyToGet.currency.network.backendId, + fromAmount = amount.toStringWithRightOffset(), + fromDecimals = amount.decimals, + providerId = providerId, + rateType = RateType.FLOAT, + toAddress = currencyToGet.value.networkAddress?.defaultAddress ?: "", + ) + + // val amountDecimal = requireNotNull(toBigDecimalOrNull(amountToSwap)) { "wrong amount format" } + + val txData = walletManagersFacade.createTransaction( + amount = amount.value.convertToAmount(currencyToSend.currency), + fee = Fee.Common(fee.feeValue.convertToAmount(currencyToSend.currency)), + memo = null, + destination = (exchangeData.dataModel?.transaction as ExpressTransactionModel.CEX).txTo, + userWalletId = userWalletId, + network = currencyToSend.currency.network, + ) + + val result = sendTransactionUseCase( + requireNotNull(txData), + userWallet = requireNotNull(getSelectedWallet()), + network = currencyToSend.currency.network + ) + + return result.fold(ifLeft = { + TxState.UnknownError + }, ifRight = { + TxState.TxSent( + txAddress = userWalletManager.getLastTransactionHash( + networkId = currencyToSend.currency.network.backendId, + derivationPath = derivationPath + ) ?: "" + ) + }) } @Deprecated("used in old swap mechanism") 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 4be138a37f..58eec2d29c 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 @@ -1,10 +1,14 @@ package com.tangem.feature.swap.domain.di +import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.demo.DemoConfig +import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.tokens.GetCardTokensListUseCase import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase 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.transaction.usecase.SendTransactionUseCase import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.WalletsStateHolder import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -36,6 +40,7 @@ class SwapDomainModule { walletFeatureToggles: WalletFeatureToggles, @SwapScope getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, @SwapScope getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, + @SwapScope sendTransactionUseCase: SendTransactionUseCase, quotesRepository: QuotesRepository, walletManagersFacade: WalletManagersFacade, coroutineDispatcherProvider: CoroutineDispatcherProvider, @@ -51,6 +56,7 @@ class SwapDomainModule { walletFeatureToggles = walletFeatureToggles, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getMultiCryptoCurrencyStatusUseCase = getCryptoCurrencyStatusUseCase, + sendTransactionUseCase = sendTransactionUseCase, quotesRepository = quotesRepository, walletManagersFacade = walletManagersFacade, dispatcher = coroutineDispatcherProvider, @@ -105,6 +111,21 @@ class SwapDomainModule { dispatchers = dispatchers, ) } + + @SwapScope + @Provides + @Singleton + fun provideSendTransactionUseCase( + walletManagersFacade: WalletManagersFacade, + cardSdkConfigRepository: CardSdkConfigRepository, + ): SendTransactionUseCase { + return SendTransactionUseCase( + isDemoCardUseCase = IsDemoCardUseCase(DemoConfig()), + cardSdkConfigRepository = cardSdkConfigRepository, + walletManagersFacade = walletManagersFacade + ) + } + } @Qualifier diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index 50c84c5b47..d3121006ab 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -17,6 +17,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.feature.swap.analytics.SwapEvents import com.tangem.feature.swap.domain.BlockchainInteractor import com.tangem.feature.swap.domain.SwapInteractor +import com.tangem.feature.swap.domain.models.SwapAmount import com.tangem.feature.swap.domain.models.domain.PermissionOptions import com.tangem.feature.swap.domain.models.domain.SwapDataModel import com.tangem.feature.swap.domain.models.domain.SwapProvider @@ -346,11 +347,11 @@ internal class SwapViewModel @Inject constructor( viewModelScope.launch(dispatchers.main) { runCatching(dispatchers.io) { swapInteractor.onSwap( - exchangeProviderType = requireNotNull(dataState.selectedProvider?.type), + swapProvider = requireNotNull(dataState.selectedProvider), networkId = dataState.networkId, - swapData = requireNotNull(dataState.swapDataModel), - currencyToSend = requireNotNull(dataState.fromCryptoCurrency?.currency), - currencyToGet = requireNotNull(dataState.toCryptoCurrency?.currency), + swapData = dataState.swapDataModel, + currencyToSend = requireNotNull(dataState.fromCryptoCurrency), + currencyToGet = requireNotNull(dataState.toCryptoCurrency), amountToSwap = requireNotNull(dataState.amount), fee = requireNotNull(dataState.selectedFee), ) @@ -389,6 +390,7 @@ internal class SwapViewModel @Inject constructor( } } .onFailure { + Timber.e(it) startLoadingQuotesFromLastState() makeDefaultAlert() }