From c95c3abe5f64c4edaffcb41f91b3c6bb8b70c69e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 4 Jun 2024 15:40:45 +0100 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/datasource/di/NetworkModule.kt | 3 ++- .../DefaultTransactionRepository.kt | 13 +++++++++++- .../transaction/TransactionRepository.kt | 3 +++ .../usecase/CreateTransactionUseCase.kt | 3 +++ .../usecase/ValidateTransactionUseCase.kt | 1 + .../feature/swap/domain/SwapInteractorImpl.kt | 21 ++++++++++++++----- 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt index 05de135483..52c92e43e6 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt @@ -39,7 +39,7 @@ class NetworkModule { appVersionProvider: AppVersionProvider, ): TangemExpressApi { val url = if (BuildConfig.ENVIRONMENT == "dev") { - DEV_EXPRESS_BASE_URL + STAGE_EXPRESS_BASE_URL } else { PROD_EXPRESS_BASE_URL } @@ -162,6 +162,7 @@ class NetworkModule { private companion object { const val STAKEKIT_BASE_URL = "https://api.stakek.it/v1/" const val PROD_EXPRESS_BASE_URL = "https://express.tangem.com/v1/" + const val STAGE_EXPRESS_BASE_URL = "[REDACTED_ENV_URL]" const val DEV_EXPRESS_BASE_URL = "[REDACTED_ENV_URL]" const val DEV_V1_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/" 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 96b20e9c0c..c148e295dd 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 @@ -35,6 +35,7 @@ internal class DefaultTransactionRepository( userWalletId: UserWalletId, network: Network, isSwap: Boolean, + txExtras: TransactionExtras?, hash: String?, ): TransactionData? = withContext(coroutineDispatcherProvider.io) { val blockchain = Blockchain.fromId(network.id.value) @@ -51,6 +52,7 @@ internal class DefaultTransactionRepository( destination = destination, network = network, isSwap = isSwap, + txExtras = txExtras, hash = hash, ) } @@ -63,6 +65,7 @@ internal class DefaultTransactionRepository( userWalletId: UserWalletId, network: Network, isSwap: Boolean, + txExtras: TransactionExtras?, hash: String?, ): Result { val blockchain = Blockchain.fromId(network.id.value) @@ -82,6 +85,7 @@ internal class DefaultTransactionRepository( destination = destination, network = network, isSwap = isSwap, + txExtras = txExtras, hash = hash, ) @@ -115,17 +119,24 @@ internal class DefaultTransactionRepository( destination: String, network: Network, isSwap: Boolean, + txExtras: TransactionExtras?, hash: String?, ): TransactionData { + // TODO: refactor workaround to use general mechanism in bsdk for build tx for DEX val txAmount = if (isSwap) { createAmountForSwap(amount) } else { amount } + if (txExtras != null && memo != null) { + // throw error for now to avoid programmers errors when use extras + error("Both txExtras and memo provided, use only one of them") + } + val extras = txExtras ?: getMemoExtras(network.id.value, memo) return createTransaction(txAmount, fee, destination).copy( hash = hash, - extras = getMemoExtras(network.id.value, memo), + extras = extras, ) } 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 156e2bb0fa..63e71f429b 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 @@ -3,6 +3,7 @@ package com.tangem.domain.transaction import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.CommonSigner import com.tangem.blockchain.common.TransactionData +import com.tangem.blockchain.common.TransactionExtras import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.extensions.SimpleResult import com.tangem.domain.tokens.model.Network @@ -19,6 +20,7 @@ interface TransactionRepository { userWalletId: UserWalletId, network: Network, isSwap: Boolean, + txExtras: TransactionExtras?, hash: String?, ): TransactionData? @@ -31,6 +33,7 @@ interface TransactionRepository { userWalletId: UserWalletId, network: Network, isSwap: Boolean = false, + txExtras: TransactionExtras?, hash: String? = null, ): Result diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionUseCase.kt index 9fea02c12f..056dfc0f0c 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateTransactionUseCase.kt @@ -2,6 +2,7 @@ package com.tangem.domain.transaction.usecase import arrow.core.Either import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.TransactionExtras import com.tangem.blockchain.common.transaction.Fee import com.tangem.domain.tokens.model.Network import com.tangem.domain.transaction.TransactionRepository @@ -22,6 +23,7 @@ class CreateTransactionUseCase( destination: String, userWalletId: UserWalletId, network: Network, + txExtras: TransactionExtras? = null, isSwap: Boolean = false, hash: String? = null, ) = Either.catch { @@ -34,6 +36,7 @@ class CreateTransactionUseCase( userWalletId = userWalletId, network = network, isSwap = isSwap, + txExtras = txExtras, hash = hash, ), ) { "Failed to create transaction" } diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateTransactionUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateTransactionUseCase.kt index 56c89954a4..8be00045ba 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateTransactionUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateTransactionUseCase.kt @@ -32,6 +32,7 @@ class ValidateTransactionUseCase( userWalletId = userWalletId, network = network, isSwap = isSwap, + txExtras = null, hash = hash, ) .fold(onSuccess = { Unit.right() }, onFailure = { it.left() }) 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 9babfe5a73..401b772024 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,13 +2,12 @@ package com.tangem.feature.swap.domain import arrow.core.Either import arrow.core.getOrElse -import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.AmountType -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.BlockchainSdkError +import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras +import com.tangem.blockchain.common.* 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 @@ -479,6 +478,7 @@ internal class SwapInteractorImpl @Inject constructor( amount = amount.value.convertToAmount(fromToken), fee = null, memo = null, + txExtras = null, destination = getTokenAddress(fromToken), userWalletId = userWalletId, network = fromToken.network, @@ -625,6 +625,7 @@ internal class SwapInteractorImpl @Inject constructor( val amountDecimal = requireNotNull(toBigDecimalOrNull(amountToSwap)) { "wrong amount format" } val amount = SwapAmount(amountDecimal, currencyToSend.decimals) val derivationPath = currencyToSend.network.derivationPath.value + val dataToSign = (swapData.transaction as ExpressTransactionModel.DEX).txData val txData = createTransactionUseCase( amount = amount.value.convertToAmount(currencyToSend), fee = getFeeForTransaction( @@ -635,7 +636,8 @@ internal class SwapInteractorImpl @Inject constructor( destination = swapData.transaction.txTo, userWalletId = userWalletId, network = currencyToSend.network, - hash = (swapData.transaction as ExpressTransactionModel.DEX).txData, + txExtras = createDexTxExtras(fee.gasLimit, dataToSign), + hash = dataToSign, isSwap = true, ).getOrElse { Timber.e(it) @@ -678,6 +680,15 @@ 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(), + ) + } + @Suppress("LongMethod") private suspend fun onSwapCex( currencyToSend: CryptoCurrencyStatus,