From e3a7ba0a777ba35f00f444e231cc412d8e80769e Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 14 Aug 2025 16:31:49 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TransactionDomainModule.kt | 10 +++ .../DefaultTransactionRepository.kt | 20 ++++++ .../ethereum/WcEthSignTransactionUseCase.kt | 2 +- .../WcSolanaSignAllTransactionUseCase.kt | 6 +- .../solana/WcSolanaSignTransactionUseCase.kt | 6 +- .../transaction/TransactionRepository.kt | 14 ++++ .../usecase/PrepareAndSignUseCase.kt | 70 +++++++++++++++++++ gradle/tangem_dependencies.toml | 2 +- 8 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareAndSignUseCase.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 eb56a8d16c..d9a7d2b4ad 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 @@ -18,6 +18,7 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import javax.inject.Singleton +@Suppress("TooManyFunctions") @Module @InstallIn(SingletonComponent::class) internal object TransactionDomainModule { @@ -184,6 +185,15 @@ internal object TransactionDomainModule { return PrepareForSendUseCase(transactionRepository, cardSdkConfigRepository) } + @Provides + @Singleton + fun providePrepareAndSignUseCase( + transactionRepository: TransactionRepository, + cardSdkConfigRepository: CardSdkConfigRepository, + ): PrepareAndSignUseCase { + return PrepareAndSignUseCase(transactionRepository, cardSdkConfigRepository) + } + @Provides @Singleton fun provideSignUseCase( 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 a9d3b05d9b..7179221efb 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 @@ -381,6 +381,26 @@ internal class DefaultTransactionRepository( preparer.prepareForSendMultiple(transactionData, signer) } + override suspend fun prepareAndSign( + transactionData: TransactionData, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ) = withContext(dispatchers.io) { + val preparer = getPreparer(network, userWalletId) + preparer.prepareAndSign(transactionData, signer) + } + + override suspend fun prepareAndSignMultiple( + transactionData: List, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ) = withContext(dispatchers.io) { + val preparer = getPreparer(network, userWalletId) + preparer.prepareAndSignMultiple(transactionData, signer) + } + private suspend fun getPreparer(network: Network, userWalletId: UserWalletId): TransactionPreparer { val blockchain = network.toBlockchain() val walletManager = walletManagersFacade.getOrCreateWalletManager( diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSignTransactionUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSignTransactionUseCase.kt index b6795bf29b..8cfe678df0 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSignTransactionUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSignTransactionUseCase.kt @@ -30,7 +30,7 @@ import com.tangem.blockchain.common.Amount as BlockchainAmount internal class WcEthSignTransactionUseCase @AssistedInject constructor( override val respondService: WcRespondService, override val analytics: AnalyticsEventHandler, - private val prepareForSend: PrepareForSendUseCase, + private val prepareForSend: PrepareForSendUseCase, // TODO: TODO("[REDACTED_JIRA]") private val ethTxHelper: WcEthTxHelper, @Assisted override val context: WcMethodUseCaseContext, @Assisted override val method: WcEthMethod.SignTransaction, diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignAllTransactionUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignAllTransactionUseCase.kt index 8e91c2c8dd..d8b9e39468 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignAllTransactionUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignAllTransactionUseCase.kt @@ -10,7 +10,7 @@ import com.tangem.data.walletconnect.sign.SignCollector import com.tangem.data.walletconnect.sign.SignStateConverter.toResult import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext import com.tangem.data.walletconnect.utils.BlockAidVerificationDelegate -import com.tangem.domain.transaction.usecase.PrepareForSendUseCase +import com.tangem.domain.transaction.usecase.PrepareAndSignUseCase import com.tangem.domain.walletconnect.error.parseSendError import com.tangem.domain.walletconnect.model.WcSolanaMethod import com.tangem.domain.walletconnect.usecase.method.BlockAidTransactionCheck @@ -29,7 +29,7 @@ import org.json.JSONObject internal class WcSolanaSignAllTransactionUseCase @AssistedInject constructor( override val respondService: WcRespondService, override val analytics: AnalyticsEventHandler, - private val prepareForSend: PrepareForSendUseCase, + private val prepareAndSign: PrepareAndSignUseCase, @Assisted override val context: WcMethodUseCaseContext, @Assisted override val method: WcSolanaMethod.SignAllTransaction, blockAidDelegate: BlockAidVerificationDelegate, @@ -46,7 +46,7 @@ internal class WcSolanaSignAllTransactionUseCase @AssistedInject constructor( ).map { lce -> lce.map { result -> BlockAidTransactionCheck.Result.Plain(result) } } override suspend fun SignCollector>.onSign(state: WcSignState>) { - val hash = prepareForSend.invoke(transactionData = state.signModel, userWallet = wallet, network = network) + val hash = prepareAndSign.invoke(transactionData = state.signModel, userWallet = wallet, network = network) .onLeft { error -> emit(state.toResult(parseSendError(error).left())) } diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt index 282125a721..c1d301135a 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt @@ -10,7 +10,7 @@ import com.tangem.data.walletconnect.sign.SignCollector import com.tangem.data.walletconnect.sign.SignStateConverter.toResult import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext import com.tangem.data.walletconnect.utils.BlockAidVerificationDelegate -import com.tangem.domain.transaction.usecase.PrepareForSendUseCase +import com.tangem.domain.transaction.usecase.PrepareAndSignUseCase import com.tangem.domain.walletconnect.error.parseSendError import com.tangem.domain.walletconnect.model.WcSolanaMethod import com.tangem.domain.walletconnect.usecase.method.BlockAidTransactionCheck @@ -27,7 +27,7 @@ import okio.ByteString.Companion.decodeBase64 internal class WcSolanaSignTransactionUseCase @AssistedInject constructor( override val respondService: WcRespondService, override val analytics: AnalyticsEventHandler, - private val prepareForSend: PrepareForSendUseCase, + private val prepareAndSign: PrepareAndSignUseCase, @Assisted override val context: WcMethodUseCaseContext, @Assisted override val method: WcSolanaMethod.SignTransaction, blockAidDelegate: BlockAidVerificationDelegate, @@ -44,7 +44,7 @@ internal class WcSolanaSignTransactionUseCase @AssistedInject constructor( ).map { lce -> lce.map { result -> BlockAidTransactionCheck.Result.Plain(result) } } override suspend fun SignCollector.onSign(state: WcSignState) { - val hash = prepareForSend.invoke(transactionData = state.signModel, userWallet = wallet, network = network) + val hash = prepareAndSign.invoke(transactionData = state.signModel, userWallet = wallet, network = network) .onLeft { error -> emit(state.toResult(parseSendError(error).left())) } 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 62feb67e90..f6171137cd 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 @@ -109,4 +109,18 @@ interface TransactionRepository { userWalletId: UserWalletId, network: Network, ): com.tangem.blockchain.extensions.Result> + + suspend fun prepareAndSign( + transactionData: TransactionData, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ): com.tangem.blockchain.extensions.Result + + suspend fun prepareAndSignMultiple( + transactionData: List, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ): com.tangem.blockchain.extensions.Result> } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareAndSignUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareAndSignUseCase.kt new file mode 100644 index 0000000000..4fecd3147f --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareAndSignUseCase.kt @@ -0,0 +1,70 @@ +package com.tangem.domain.transaction.usecase + +import arrow.core.Either +import arrow.core.left +import arrow.core.right +import com.tangem.blockchain.common.TransactionData +import com.tangem.blockchain.common.TransactionSigner +import com.tangem.blockchain.extensions.Result +import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins +import com.tangem.domain.card.models.TwinKey +import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.models.wallet.requireColdWallet +import com.tangem.domain.transaction.TransactionRepository +import com.tangem.domain.transaction.error.SendTransactionError + +class PrepareAndSignUseCase( + private val transactionRepository: TransactionRepository, + private val cardSdkConfigRepository: CardSdkConfigRepository, +) { + + suspend operator fun invoke( + transactionData: TransactionData, + userWallet: UserWallet, + network: Network, + ): Either { + val signer = createSigner(userWallet) + val result = transactionRepository.prepareAndSign( + transactionData = transactionData, + userWalletId = userWallet.walletId, + network = network, + signer = signer, + ) + return when (result) { + is Result.Failure -> SendTransactionUseCase.handleError(result).left() + is Result.Success -> result.data.right() + } + } + + suspend operator fun invoke( + transactionData: List, + userWallet: UserWallet, + network: Network, + ): Either> { + val signer = createSigner(userWallet) + val result = transactionRepository.prepareAndSignMultiple( + transactionData = transactionData, + userWalletId = userWallet.walletId, + network = network, + signer = signer, + ) + return when (result) { + is Result.Failure -> SendTransactionUseCase.handleError(result).left() + is Result.Success -> result.data.right() + } + } + + private fun createSigner(userWallet: UserWallet): TransactionSigner { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + val card = userWallet.scanResponse.card + val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins + + val signer = cardSdkConfigRepository.getCommonSigner( + cardId = card.cardId.takeIf { isCardNotBackedUp }, + twinKey = TwinKey.getOrNull(scanResponse = userWallet.scanResponse), + ) + return signer + } +} \ No newline at end of file diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 1018ab6255..03c2b9d8b5 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,7 +5,7 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.27.0-1142" +tangemBlockchainSdk = "releases-5.27.0-1147" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "releases-5.27.0-513" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^