Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-27 17:22:49 +03:00
parent 891babfce6
commit 5938768ff7
5 changed files with 24 additions and 180 deletions

View file

@ -42,21 +42,6 @@ internal object TransactionDomainModule {
)
}
@Provides
@Singleton
fun provideSendMultipleTransactionUseCase(
cardSdkConfigRepository: CardSdkConfigRepository,
transactionRepository: TransactionRepository,
walletManagersFacade: WalletManagersFacade,
): SendMultipleTransactionUseCase {
return SendMultipleTransactionUseCase(
demoConfig = DemoConfig(),
cardSdkConfigRepository = cardSdkConfigRepository,
transactionRepository = transactionRepository,
walletManagersFacade = walletManagersFacade,
)
}
@Provides
@Singleton
fun provideAssociateAssetUseCase(

View file

@ -1,147 +0,0 @@
package com.tangem.domain.transaction.usecase
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.blockchain.common.transaction.TransactionsSendResult
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.network.ResultChecker
import com.tangem.common.core.TangemSdkError
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.demo.DemoTransactionSender
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.R
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.error.SendTransactionError.Companion.USER_CANCELLED_ERROR_CODE
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.sdk.extensions.localizedDescriptionRes
import com.tangem.utils.toFormattedString
// TODO [REDACTED_TASK_KEY] merge with SendTransactionUseCase
class SendMultipleTransactionUseCase(
private val demoConfig: DemoConfig,
private val cardSdkConfigRepository: CardSdkConfigRepository,
private val transactionRepository: TransactionRepository,
private val walletManagersFacade: WalletManagersFacade,
) {
suspend operator fun invoke(
txsData: List<TransactionData>,
userWallet: UserWallet,
network: Network,
): Either<SendTransactionError?, List<String>> {
val card = userWallet.scanResponse.card
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins
val signer = cardSdkConfigRepository.getCommonSigner(cardId = card.cardId.takeIf { isCardNotBackedUp })
val linkedTerminal = cardSdkConfigRepository.isLinkedTerminal()
if (userWallet.scanResponse.card.isStart2Coin) {
cardSdkConfigRepository.setLinkedTerminal(false)
}
val sendResult = try {
if (demoConfig.isDemoCardId(cardId = userWallet.cardId)) {
sendDemo(
userWallet = userWallet,
network = network,
transactionsData = txsData,
signer = signer,
)
} else {
val sendResult = transactionRepository.sendMultipleTransactions(
txsData = txsData,
signer = signer,
userWalletId = userWallet.walletId,
network = network,
)
when (sendResult) {
is Result.Failure -> handleError(sendResult).left()
is Result.Success -> sendResult.data.right()
}
}
} catch (ex: Exception) {
cardSdkConfigRepository.setLinkedTerminal(linkedTerminal)
SendTransactionError.DataError(ex.message).left()
}
cardSdkConfigRepository.setLinkedTerminal(linkedTerminal)
return sendResult.fold(
ifRight = { result -> result.hashes.right() },
ifLeft = { it.left() },
)
}
private suspend fun sendDemo(
userWallet: UserWallet,
network: Network,
transactionsData: List<TransactionData>,
signer: TransactionSigner,
): Either<SendTransactionError, TransactionsSendResult> {
val demoTransactionSender = DemoTransactionSender(
walletManagersFacade
.getOrCreateWalletManager(userWallet.walletId, network)
?: error("WalletManager is null"),
)
val result = demoTransactionSender.sendMultiple(transactionDataList = transactionsData, signer = signer)
return if (result is Result.Failure && result.error.customMessage.contains(DemoTransactionSender.ID)) {
SendTransactionError.DemoCardError.left()
} else {
TransactionsSendResult(listOf("hash")).right()
}
}
private fun handleError(result: Result.Failure): SendTransactionError {
if (ResultChecker.isNetworkError(result)) {
return SendTransactionError.NetworkError(
code = result.error.message,
message = result.error.customMessage,
)
}
val error = result.error as? BlockchainSdkError ?: return SendTransactionError.UnknownError()
return when (error) {
is BlockchainSdkError.WrappedTangemError -> parseWrappedError(error)
is BlockchainSdkError.CreateAccountUnderfunded -> {
val minAmount = error.minReserve
val minValue = minAmount.value?.toFormattedString(minAmount.decimals).orEmpty()
SendTransactionError.CreateAccountUnderfunded(minValue)
}
else -> {
SendTransactionError.BlockchainSdkError(
code = error.code,
message = error.customMessage,
)
}
}
}
private fun parseWrappedError(error: BlockchainSdkError.WrappedTangemError): SendTransactionError {
return if (error.code == USER_CANCELLED_ERROR_CODE) {
SendTransactionError.UserCancelledError
} else {
when (val tangemError = error.tangemError) {
is TangemSdkError -> {
val resource = tangemError.localizedDescriptionRes()
val resId = resource.resId ?: R.string.common_unknown_error
val resArgs = resource.args.map { it.value }
SendTransactionError.TangemSdkError(tangemError.code, resId, wrappedList(resArgs))
}
is BlockchainSdkError.WrappedTangemError -> {
parseWrappedError(tangemError) // todo remove when sdk errors are revised
}
else -> {
SendTransactionError.BlockchainSdkError(error.code, tangemError.customMessage)
}
}
}
}
}

View file

@ -6,7 +6,7 @@ import arrow.core.right
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.blockchain.common.transaction.TransactionSendResult
import com.tangem.blockchain.common.transaction.TransactionsSendResult
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.network.ResultChecker
import com.tangem.common.core.TangemSdkError
@ -33,10 +33,10 @@ class SendTransactionUseCase(
private val walletManagersFacade: WalletManagersFacade,
) {
suspend operator fun invoke(
txData: TransactionData,
txsData: List<TransactionData>,
userWallet: UserWallet,
network: Network,
): Either<SendTransactionError?, String> {
): Either<SendTransactionError?, List<String>> {
val card = userWallet.scanResponse.card
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins
@ -51,12 +51,12 @@ class SendTransactionUseCase(
sendDemo(
userWallet = userWallet,
network = network,
transactionData = txData,
transactionsData = txsData,
signer = signer,
)
} else {
val sendResult = transactionRepository.sendTransaction(
txData = txData,
val sendResult = transactionRepository.sendMultipleTransactions(
txsData = txsData,
signer = signer,
userWalletId = userWallet.walletId,
network = network,
@ -73,29 +73,38 @@ class SendTransactionUseCase(
cardSdkConfigRepository.setLinkedTerminal(linkedTerminal)
return sendResult.fold(
ifRight = { result -> result.hash.right() },
ifRight = { result -> result.hashes.right() },
ifLeft = { it.left() },
)
}
suspend operator fun invoke(
txData: TransactionData,
userWallet: UserWallet,
network: Network,
): Either<SendTransactionError?, String> {
return invoke(listOf(txData), userWallet, network)
.map { it.first() }
}
private suspend fun sendDemo(
userWallet: UserWallet,
network: Network,
transactionData: TransactionData,
transactionsData: List<TransactionData>,
signer: TransactionSigner,
): Either<SendTransactionError, TransactionSendResult> {
): Either<SendTransactionError, TransactionsSendResult> {
val demoTransactionSender = DemoTransactionSender(
walletManagersFacade
.getOrCreateWalletManager(userWallet.walletId, network)
?: error("WalletManager is null"),
)
val result = demoTransactionSender.send(transactionData = transactionData, signer = signer)
val result = demoTransactionSender.sendMultiple(transactionDataList = transactionsData, signer = signer)
return if (result is Result.Failure && result.error.customMessage.contains(DemoTransactionSender.ID)) {
SendTransactionError.DemoCardError.left()
} else {
TransactionSendResult("hash").right()
TransactionsSendResult(listOf("hash")).right()
}
}

View file

@ -19,7 +19,7 @@ import com.tangem.domain.staking.model.stakekit.transaction.StakingTransactionSt
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransactionType
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.usecase.SendMultipleTransactionUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.staking.impl.analytics.StakingAnalyticsEvents
@ -42,7 +42,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
private val stakingBalanceUpdater: StakingBalanceUpdater.Factory,
private val getStakingTransactionUseCase: GetStakingTransactionUseCase,
private val getConstructedStakingTransactionUseCase: GetConstructedStakingTransactionUseCase,
private val sendMultipleTransactionUseCase: SendMultipleTransactionUseCase,
private val sendTransactionUseCase: SendTransactionUseCase,
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
private val submitHashUseCase: SubmitHashUseCase,
private val saveUnsubmittedHashUseCase: SaveUnsubmittedHashUseCase,
@ -208,7 +208,7 @@ internal class StakingTransactionSender @AssistedInject constructor(
onSendSuccess: (txUrl: String) -> Unit,
onSendError: (SendTransactionError?) -> Unit,
) {
sendMultipleTransactionUseCase(
sendTransactionUseCase(
txsData = fullTransactionsData.map { it.tangemTransaction },
userWallet = userWallet,
network = cryptoCurrencyStatus.currency.network,

View file

@ -37,10 +37,7 @@ import com.tangem.domain.tokens.*
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.usecase.CreateApprovalTransactionUseCase
import com.tangem.domain.transaction.usecase.GetAllowanceUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId