Updated on 2026-08-14
This commit is contained in:
parent
f916d7394b
commit
cf6ee347b8
14 changed files with 161 additions and 197 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<TransactionSendResult>): 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%
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.tangem.domain.transaction.models
|
||||
|
||||
enum class TransactionType {
|
||||
APPROVE,
|
||||
}
|
||||
|
|
@ -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<TransactionSendResult>
|
||||
|
||||
fun createTransactionDataExtras(
|
||||
data: String,
|
||||
network: Network,
|
||||
transactionType: TransactionType,
|
||||
nonce: BigInteger?,
|
||||
gasLimit: BigInteger?,
|
||||
): TransactionExtras
|
||||
}
|
||||
|
|
@ -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" }
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 ^
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue