From cf6ee347b85788b52f6104fdea941c79f365ef19 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 27 Jun 2024 15:48:07 +0100 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TransactionDomainModule.kt | 8 ++ .../tap/proxy/TransactionManagerImpl.kt | 134 ------------------ .../com/tangem/tap/proxy/di/ProxyModule.kt | 10 +- data/transaction/build.gradle.kts | 2 + .../DefaultTransactionRepository.kt | 40 ++++++ domain/transaction/build.gradle.kts | 1 + .../transaction/models/TransactionType.kt | 5 + .../transaction/TransactionRepository.kt | 10 ++ .../CreateTransactionDataExtrasUseCase.kt | 30 ++++ features/swap/domain/build.gradle.kts | 1 + .../feature/swap/domain/SwapInteractorImpl.kt | 100 +++++++------ .../swap/domain/di/SwapDomainModule.kt | 7 +- gradle/dependencies.toml | 2 +- .../tangem/lib/crypto/TransactionManager.kt | 8 -- 14 files changed, 161 insertions(+), 197 deletions(-) create mode 100644 domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/TransactionType.kt create mode 100644 domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionDataExtrasUseCase.kt 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 849209811f..8ce98f292d 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 @@ -64,6 +64,14 @@ internal object TransactionDomainModule { return CreateTransactionUseCase(transactionRepository) } + @Provides + @Singleton + fun provideCreateTransactionExtrasUseCase( + transactionRepository: TransactionRepository, + ): CreateTransactionDataExtrasUseCase { + return CreateTransactionDataExtrasUseCase(transactionRepository) + } + @Provides @Singleton fun provideEstimateFeeUseCase(walletManagersFacade: WalletManagersFacade): EstimateFeeUseCase { diff --git a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt index 587924aa8a..c199b92e7b 100644 --- a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt @@ -1,28 +1,17 @@ package com.tangem.tap.proxy -import com.google.firebase.crashlytics.FirebaseCrashlytics -import com.tangem.Message -import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager import com.tangem.blockchain.blockchains.optimism.EthereumOptimisticRollupWalletManager import com.tangem.blockchain.common.* import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee -import com.tangem.blockchain.common.transaction.TransactionSendResult import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.externallinkprovider.TxExploreState -import com.tangem.blockchain.network.ResultChecker import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.common.core.TangemSdkError -import com.tangem.common.extensions.hexToBytes -import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.lib.crypto.TransactionManager import com.tangem.lib.crypto.models.* -import com.tangem.lib.crypto.models.transactions.SendTxResult -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.domain.TangemSigner import java.math.BigDecimal import java.math.BigInteger import java.math.MathContext @@ -30,59 +19,10 @@ import java.math.RoundingMode @Suppress("LargeClass") class TransactionManagerImpl( - private val appStateHolder: AppStateHolder, - private val cardSdkConfigRepository: CardSdkConfigRepository, private val walletManagersFacade: WalletManagersFacade, private val userWalletsListManager: UserWalletsListManager, ) : TransactionManager { - override suspend fun sendApproveTransaction( - txData: ApproveTxData, - derivationPath: String?, - analyticsData: AnalyticsData, - ): SendTxResult { - val blockchain = requireNotNull(Blockchain.fromNetworkId(txData.networkId)) { "blockchain not found" } - val walletManager = getActualWalletManager(blockchain, derivationPath) - walletManager.update() - val amount = Amount(value = BigDecimal.ZERO, blockchain = blockchain) - return sendTransactionInternal( - walletManager = walletManager, - amount = amount, - blockchain = blockchain, - feeAmount = txData.feeAmount, - gasLimit = txData.gasLimit, - destinationAddress = txData.destinationAddress, - dataToSign = txData.dataToSign, - ) - } - - @Suppress("LongParameterList") - private suspend fun sendTransactionInternal( - walletManager: WalletManager, - amount: Amount, - blockchain: Blockchain, - feeAmount: BigDecimal, - gasLimit: Int, - destinationAddress: String, - dataToSign: String, - ): SendTxResult { - val txData = walletManager.createTransaction( - amount = amount, - fee = Fee.Common(Amount(value = feeAmount, blockchain = blockchain)), - destination = destinationAddress, - ).copy(hash = dataToSign, extras = createExtras(walletManager, gasLimit, dataToSign)) - - val signer = transactionSigner(walletManager) - - val sendResult = try { - (walletManager as? TransactionSender)?.send(txData, signer) ?: error("Cannot cast to TransactionSender") - } catch (ex: Exception) { - FirebaseCrashlytics.getInstance().recordException(ex) - return SendTxResult.UnknownError(ex) - } - return handleSendResult(result = sendResult) - } - override fun getExplorerTransactionLink(networkId: String, txAddress: String): String { val blockchain = Blockchain.fromNetworkId(networkId) ?: error("blockchain not found") return when (val txUrlState = blockchain.getExploreTxUrl(txAddress)) { @@ -301,60 +241,6 @@ class TransactionManagerImpl( } } - private fun handleSendResult(result: Result): SendTxResult { - when (result) { - is Result.Success -> { - return SendTxResult.Success - } - is Result.Failure -> { - if (ResultChecker.isNetworkError(result)) return SendTxResult.NetworkError(result.error) - val error = result.error as? BlockchainSdkError ?: return SendTxResult.UnknownError() - when (error) { - is BlockchainSdkError.WrappedTangemError -> { - val errorByCode = mapErrorByCode(error) - if (errorByCode != null) { - return errorByCode - } - val tangemSdkError = error.tangemError as? TangemSdkError ?: return SendTxResult.UnknownError() - if (tangemSdkError is TangemSdkError.UserCancelled) return SendTxResult.UserCancelledError - return SendTxResult.TangemSdkError(tangemSdkError.code, tangemSdkError.cause) - } - else -> { - return SendTxResult.TangemSdkError(error.code, error.cause) - } - } - } - } - } - - private fun mapErrorByCode(error: BlockchainSdkError.WrappedTangemError): SendTxResult? { - return when (error.code) { - USER_CANCELLED_ERROR_CODE -> { - return SendTxResult.UserCancelledError - } - else -> { - null - } - } - } - - private fun transactionSigner(walletManager: WalletManager): TransactionSigner { - val actualCard = requireNotNull(appStateHolder.getActualCard()) { "no card found" } - return TangemSigner( - card = actualCard, - tangemSdk = cardSdkConfigRepository.sdk, - initialMessage = Message(), - ) { signResponse -> - appStateHolder.mainStore?.dispatch( - GlobalAction.UpdateWalletSignedHashes( - walletSignedHashes = signResponse.totalSignedHashes, - walletPublicKey = walletManager.wallet.publicKey.seedKey, - remainingSignatures = signResponse.remainingSignatures, - ), - ) - } - } - private suspend fun getActualWalletManager(blockchain: Blockchain, derivationPath: String?): WalletManager { val selectedUserWallet = requireNotNull( userWalletsListManager.selectedUserWalletSync, @@ -368,24 +254,6 @@ class TransactionManagerImpl( return requireNotNull(walletManager) { "no wallet manager found" } } - private fun createExtras( - walletManager: WalletManager, - gasLimit: Int, - transactionHash: String, - ): TransactionExtras? { - return when (walletManager) { - is EthereumWalletManager -> { - return EthereumTransactionExtras( - data = transactionHash.removePrefix(HEX_PREFIX).hexToBytes(), - gasLimit = gasLimit.toBigInteger(), - ) - } - else -> { - null - } - } - } - /** * Create proxy fees * @@ -483,8 +351,6 @@ class TransactionManagerImpl( } companion object { - private const val HEX_PREFIX = "0x" - private const val USER_CANCELLED_ERROR_CODE = 50002 private const val MULTIPLIER_GAS_PRICE_FOR_NORMAL_FEE = 150 // 50% private const val MULTIPLIER_GAS_PRICE_FOR_PRIORITY_FEE = 200 // 50% } diff --git a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt index 37fc1060b4..5c9c990ba5 100644 --- a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt +++ b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt @@ -1,16 +1,16 @@ package com.tangem.tap.proxy.di -import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.lib.crypto.TransactionManager import com.tangem.lib.crypto.UserWalletManager -import com.tangem.tap.proxy.* +import com.tangem.tap.proxy.AppStateHolder +import com.tangem.tap.proxy.TransactionManagerImpl +import com.tangem.tap.proxy.UserWalletManagerImpl import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.flow.* import javax.inject.Singleton @Module @@ -38,14 +38,10 @@ internal object ProxyModule { @Provides @Singleton fun provideTransactionManager( - appStateHolder: AppStateHolder, - cardSdkConfigRepository: CardSdkConfigRepository, walletManagersFacade: WalletManagersFacade, userWalletsListManager: UserWalletsListManager, ): TransactionManager { return TransactionManagerImpl( - appStateHolder = appStateHolder, - cardSdkConfigRepository = cardSdkConfigRepository, walletManagersFacade = walletManagersFacade, userWalletsListManager = userWalletsListManager, ) diff --git a/data/transaction/build.gradle.kts b/data/transaction/build.gradle.kts index 615758dcf6..41baa4a4ba 100644 --- a/data/transaction/build.gradle.kts +++ b/data/transaction/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { /** Tangem SDKs */ implementation(deps.tangem.blockchain) + implementation(deps.tangem.card.core) /** Core */ implementation(projects.core.datasource) @@ -25,6 +26,7 @@ dependencies { implementation(projects.libs.blockchainSdk) implementation(projects.domain.wallets.models) implementation(projects.domain.tokens.models) + implementation(projects.domain.transaction.models) /** DI */ implementation(deps.hilt.android) diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt index a69275891f..caffe5aca9 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt @@ -4,22 +4,29 @@ import androidx.core.text.isDigitsOnly import com.tangem.blockchain.blockchains.algorand.AlgorandTransactionExtras import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras +import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras import com.tangem.blockchain.blockchains.hedera.HederaTransactionExtras import com.tangem.blockchain.blockchains.stellar.StellarMemo import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras import com.tangem.blockchain.blockchains.ton.TonTransactionExtras +import com.tangem.blockchain.blockchains.tron.TronTransactionExtras import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder import com.tangem.blockchain.common.* import com.tangem.blockchain.common.transaction.Fee +import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.common.extensions.hexToBytes import com.tangem.datasource.local.walletmanager.WalletManagersStore import com.tangem.domain.tokens.model.Network import com.tangem.domain.transaction.TransactionRepository +import com.tangem.domain.transaction.models.TransactionType import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import timber.log.Timber import java.math.BigDecimal +import java.math.BigInteger +import com.tangem.blockchain.blockchains.tron.TransactionType as SdkTransactionType internal class DefaultTransactionRepository( private val walletManagersFacade: WalletManagersFacade, @@ -111,6 +118,39 @@ internal class DefaultTransactionRepository( (walletManager as TransactionSender).send(txData, signer) } + override fun createTransactionDataExtras( + data: String, + network: Network, + transactionType: TransactionType, + nonce: BigInteger?, + gasLimit: BigInteger?, + ): TransactionExtras { + val blockchain = Blockchain.fromNetworkId(networkId = network.backendId) + ?: error("Blockchain not found") + return when { + blockchain.isEvm() -> { + EthereumTransactionExtras( + data = data.hexToBytes(), + gasLimit = gasLimit, + nonce = nonce, + ) + } + blockchain == Blockchain.Tron -> { + TronTransactionExtras( + data = data.hexToBytes(), + txType = convertToSdkTransactionType(transactionType), + ) + } + else -> error("Data extras not supported for $blockchain") + } + } + + private fun convertToSdkTransactionType(transactionType: TransactionType): SdkTransactionType { + return when (transactionType) { + TransactionType.APPROVE -> SdkTransactionType.APPROVE + } + } + @Suppress("LongParameterList") private fun WalletManager.createTransactionDataInternal( amount: Amount, diff --git a/domain/transaction/build.gradle.kts b/domain/transaction/build.gradle.kts index d4014c6f47..b54aeca082 100644 --- a/domain/transaction/build.gradle.kts +++ b/domain/transaction/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { implementation(projects.domain.wallets.models) implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) + implementation(projects.domain.transaction.models) implementation(projects.domain.demo) implementation(projects.domain.card) } \ No newline at end of file diff --git a/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/TransactionType.kt b/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/TransactionType.kt new file mode 100644 index 0000000000..fdd9a7ec17 --- /dev/null +++ b/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/TransactionType.kt @@ -0,0 +1,5 @@ +package com.tangem.domain.transaction.models + +enum class TransactionType { + APPROVE, +} \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt index 02240d9dc1..2228ec19e5 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt @@ -4,7 +4,9 @@ import com.tangem.blockchain.common.* import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionSendResult import com.tangem.domain.tokens.model.Network +import com.tangem.domain.transaction.models.TransactionType import com.tangem.domain.wallets.models.UserWalletId +import java.math.BigInteger interface TransactionRepository { @@ -40,4 +42,12 @@ interface TransactionRepository { userWalletId: UserWalletId, network: Network, ): com.tangem.blockchain.extensions.Result + + fun createTransactionDataExtras( + data: String, + network: Network, + transactionType: TransactionType, + nonce: BigInteger?, + gasLimit: BigInteger?, + ): TransactionExtras } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionDataExtrasUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionDataExtrasUseCase.kt new file mode 100644 index 0000000000..52d686e403 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionDataExtrasUseCase.kt @@ -0,0 +1,30 @@ +package com.tangem.domain.transaction.usecase + +import arrow.core.Either +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.transaction.TransactionRepository +import com.tangem.domain.transaction.models.TransactionType +import java.math.BigInteger + +class CreateTransactionDataExtrasUseCase( + private val transactionRepository: TransactionRepository, +) { + + operator fun invoke( + data: String, + network: Network, + transactionType: TransactionType, + gasLimit: BigInteger? = null, + nonce: BigInteger? = null, + ) = Either.catch { + requireNotNull( + transactionRepository.createTransactionDataExtras( + data = data, + network = network, + transactionType = transactionType, + nonce = nonce, + gasLimit = gasLimit, + ), + ) { "Failed to create transaction" } + } +} \ No newline at end of file diff --git a/features/swap/domain/build.gradle.kts b/features/swap/domain/build.gradle.kts index c40cbbcc83..55f5e6eea3 100644 --- a/features/swap/domain/build.gradle.kts +++ b/features/swap/domain/build.gradle.kts @@ -32,6 +32,7 @@ dependencies { implementation(projects.domain.card) implementation(projects.domain.appCurrency.models) implementation(projects.domain.txhistory.models) + implementation(projects.domain.transaction.models) implementation(projects.features.swap.domain.api) implementation(projects.features.swap.domain.models) implementation(projects.domain.staking) 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 87c2e5d142..68521fe254 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 @@ -2,12 +2,12 @@ package com.tangem.feature.swap.domain import arrow.core.Either import arrow.core.getOrElse -import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.blockchainsdk.utils.minimalAmount -import com.tangem.common.extensions.hexToBytes import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.core.ui.utils.parseBigDecimal import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase @@ -15,20 +15,16 @@ import com.tangem.domain.appcurrency.extenstions.unwrap import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.demo.DemoConfig 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.* import com.tangem.domain.tokens.model.FeePaidCurrency -import com.tangem.domain.tokens.model.Quote import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.CurrencyChecksRepository import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.tokens.utils.convertToAmount import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.transaction.error.SendTransactionError -import com.tangem.domain.transaction.usecase.CreateTransactionUseCase -import com.tangem.domain.transaction.usecase.EstimateFeeUseCase -import com.tangem.domain.transaction.usecase.SendTransactionUseCase -import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase +import com.tangem.domain.transaction.models.TransactionType +import com.tangem.domain.transaction.usecase.* import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -42,8 +38,9 @@ import com.tangem.feature.swap.domain.models.ui.* import com.tangem.lib.crypto.BlockchainUtils import com.tangem.lib.crypto.TransactionManager import com.tangem.lib.crypto.UserWalletManager -import com.tangem.lib.crypto.models.* -import com.tangem.lib.crypto.models.transactions.SendTxResult +import com.tangem.lib.crypto.models.ProxyAmount +import com.tangem.lib.crypto.models.ProxyFee +import com.tangem.lib.crypto.models.ProxyFees import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.firstOrNull import timber.log.Timber @@ -62,6 +59,7 @@ internal class SwapInteractorImpl @Inject constructor( private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, private val sendTransactionUseCase: SendTransactionUseCase, private val createTransactionUseCase: CreateTransactionUseCase, + private val createTransactionExtrasUseCase: CreateTransactionDataExtrasUseCase, private val quotesRepository: QuotesRepository, private val swapTransactionRepository: SwapTransactionRepository, private val currencyChecksRepository: CurrencyChecksRepository, @@ -214,35 +212,51 @@ internal class SwapInteractorImpl @Inject constructor( } else { permissionOptions.approveData.approveData } - val result = transactionManager.sendApproveTransaction( - txData = ApproveTxData( - networkId = networkId, - feeAmount = permissionOptions.txFee.feeValue, - gasLimit = permissionOptions.txFee.gasLimit, - destinationAddress = getTokenAddress(permissionOptions.fromToken), - dataToSign = dataToSign, + val approveTransaction = createTransactionUseCase( + amount = BigDecimal.ZERO.convertToAmount(permissionOptions.fromToken), + fee = getFeeForTransaction( + fee = permissionOptions.txFee, + blockchain = Blockchain.fromId(permissionOptions.fromToken.network.id.value), ), - derivationPath = derivationPath, - analyticsData = AnalyticsData( - feeType = permissionOptions.txFee.feeType.getNameForAnalytics(), - tokenSymbol = permissionOptions.fromToken.symbol, - permissionType = permissionOptions.approveType.getNameForAnalytics(), + memo = null, + destination = getTokenAddress(permissionOptions.fromToken), + network = permissionOptions.fromToken.network, + userWalletId = requireNotNull(getSelectedWallet()).walletId, + txExtras = createDexTxExtras( + dataToSign, + permissionOptions.fromToken.network, + permissionOptions.txFee.gasLimit, ), + isSwap = false, + ).getOrElse { + Timber.e(it, "Failed to create approveTransaction") + return SwapTransactionState.UnknownError + } + + val result = sendTransactionUseCase( + txData = approveTransaction, + userWallet = requireNotNull(getSelectedWallet()), + network = permissionOptions.fromToken.network, ) - return when (result) { - is SendTxResult.Success -> { + return result.fold( + ifRight = { hash -> allowPermissionsHandler.addAddressToInProgress(permissionOptions.forTokenContractAddress) SwapTransactionState.TxSent( - txHash = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(), + txHash = hash, timestamp = System.currentTimeMillis(), ) - } - SendTxResult.UserCancelledError -> SwapTransactionState.UserCancelled - is SendTxResult.BlockchainSdkError -> SwapTransactionState.BlockchainError - is SendTxResult.TangemSdkError -> SwapTransactionState.TangemSdkError - is SendTxResult.NetworkError -> SwapTransactionState.NetworkError - is SendTxResult.UnknownError -> SwapTransactionState.UnknownError - } + }, + ifLeft = { + when (it) { + SendTransactionError.UserCancelledError -> SwapTransactionState.UserCancelled + is SendTransactionError.BlockchainSdkError -> SwapTransactionState.BlockchainError + is SendTransactionError.TangemSdkError -> SwapTransactionState.TangemSdkError + is SendTransactionError.NetworkError -> SwapTransactionState.NetworkError + is SendTransactionError.DemoCardError -> SwapTransactionState.DemoMode + else -> SwapTransactionState.UnknownError + } + }, + ) } override suspend fun findBestQuote( @@ -647,11 +661,11 @@ internal class SwapInteractorImpl @Inject constructor( destination = swapData.transaction.txTo, userWalletId = userWalletId, network = currencyToSendStatus.currency.network, - txExtras = createDexTxExtras(fee.gasLimit, dataToSign), + txExtras = createDexTxExtras(dataToSign, currencyToSendStatus.currency.network, fee.gasLimit), hash = dataToSign, isSwap = true, ).getOrElse { - Timber.e(it) + Timber.e(it, "Failed to create swap dex tx data") return SwapTransactionState.UnknownError } @@ -699,13 +713,13 @@ internal class SwapInteractorImpl @Inject constructor( ) } - private fun createDexTxExtras(gasLimit: Int, data: String): TransactionExtras { - // for now we support only Ethereum like DEX - // need to be extended if we support other blockchains in DEX - return EthereumTransactionExtras( - gasLimit = gasLimit.toBigInteger(), - data = data.removePrefix(HEX_PREFIX).hexToBytes(), - ) + private fun createDexTxExtras(data: String, network: Network, gasLimit: Int?): TransactionExtras { + return createTransactionExtrasUseCase( + data = data, + network = network, + transactionType = TransactionType.APPROVE, + gasLimit = gasLimit?.toBigInteger(), + ).getOrNull() ?: error("failed to create extras") } @Suppress("LongMethod") @@ -750,7 +764,7 @@ internal class SwapInteractorImpl @Inject constructor( userWalletId = userWalletId, network = currencyToSend.currency.network, ).getOrElse { - Timber.e(it) + Timber.e(it, "Failed to create swap CEX tx data") return SwapTransactionState.UnknownError } 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 76f5998502..3e42fef158 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 @@ -12,10 +12,7 @@ import com.tangem.domain.tokens.repository.CurrencyChecksRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.transaction.TransactionRepository -import com.tangem.domain.transaction.usecase.CreateTransactionUseCase -import com.tangem.domain.transaction.usecase.EstimateFeeUseCase -import com.tangem.domain.transaction.usecase.SendTransactionUseCase -import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase +import com.tangem.domain.transaction.usecase.* import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -45,6 +42,7 @@ class SwapDomainModule { getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase, @SwapScope sendTransactionUseCase: SendTransactionUseCase, @SwapScope createTransactionUseCase: CreateTransactionUseCase, + createTransactionDataExtrasUseCase: CreateTransactionDataExtrasUseCase, quotesRepository: QuotesRepository, swapTransactionRepository: SwapTransactionRepository, appCurrencyRepository: AppCurrencyRepository, @@ -63,6 +61,7 @@ class SwapDomainModule { getMultiCryptoCurrencyStatusUseCase = getCryptoCurrencyStatusUseCase, sendTransactionUseCase = sendTransactionUseCase, createTransactionUseCase = createTransactionUseCase, + createTransactionExtrasUseCase = createTransactionDataExtrasUseCase, quotesRepository = quotesRepository, swapTransactionRepository = swapTransactionRepository, appCurrencyRepository = appCurrencyRepository, diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 9836ee2b61..8cecca280d 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -88,7 +88,7 @@ markdown = "0.7.2" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-688" +tangemBlockchainSdk = "develop-690" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-366" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt index 6a3ab8f374..f114465769 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt @@ -1,18 +1,10 @@ package com.tangem.lib.crypto import com.tangem.lib.crypto.models.* -import com.tangem.lib.crypto.models.transactions.SendTxResult import java.math.BigDecimal interface TransactionManager { - @Throws(IllegalStateException::class) - suspend fun sendApproveTransaction( - txData: ApproveTxData, - derivationPath: String?, - analyticsData: AnalyticsData, - ): SendTxResult - /** * Get fee *