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 adc63cbd3d..55d35c9244 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 @@ -147,4 +147,22 @@ internal object TransactionDomainModule { fun provideGetAllowanceUseCase(transactionRepository: TransactionRepository): GetAllowanceUseCase { return GetAllowanceUseCase(transactionRepository) } + + @Provides + @Singleton + fun providePrepareForSendUseCase( + transactionRepository: TransactionRepository, + cardSdkConfigRepository: CardSdkConfigRepository, + ): PrepareForSendUseCase { + return PrepareForSendUseCase(transactionRepository, cardSdkConfigRepository) + } + + @Provides + @Singleton + fun provideSignUseCase( + walletManagersFacade: WalletManagersFacade, + cardSdkConfigRepository: CardSdkConfigRepository, + ): SignUseCase { + return SignUseCase(cardSdkConfigRepository, walletManagersFacade) + } } \ No newline at end of file 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 07f16b38b8..6d3ddca431 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 @@ -280,4 +280,27 @@ internal class DefaultTransactionRepository( else -> null } } + + override suspend fun prepareForSend( + transactionData: TransactionData, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ): Result = withContext(coroutineDispatcherProvider.io) { + val blockchain = Blockchain.fromId(network.id.value) + val walletManager = walletManagersFacade.getOrCreateWalletManager( + userWalletId = userWalletId, + blockchain = blockchain, + derivationPath = network.derivationPath.value, + ) + val preparer = walletManager as? TransactionPreparer ?: kotlin.run { + Timber.e("${walletManager?.wallet?.blockchain} does not support TransactionBuilder") + error("Wallet manager does not support TransactionPreparer") + } + + when (val prepareForSend = preparer.prepareForSend(transactionData, signer)) { + is com.tangem.blockchain.extensions.Result.Failure -> Result.failure(prepareForSend.error) + is com.tangem.blockchain.extensions.Result.Success -> Result.success(prepareForSend.data) + } + } } \ No newline at end of file diff --git a/data/wallet-connect/build.gradle.kts b/data/wallet-connect/build.gradle.kts index d1da51e0b0..e130216844 100644 --- a/data/wallet-connect/build.gradle.kts +++ b/data/wallet-connect/build.gradle.kts @@ -14,9 +14,9 @@ dependencies { /* Project - Domain */ implementation(projects.domain.walletConnect) implementation(projects.domain.walletConnect.models) + implementation(projects.domain.transaction) implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) - implementation(projects.domain.card) implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) implementation(projects.domain.models) diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/DefaultWcPersonalEthSignUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/DefaultWcPersonalEthSignUseCase.kt index d6d7cd9c1f..98e6f2db49 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/DefaultWcPersonalEthSignUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/DefaultWcPersonalEthSignUseCase.kt @@ -1,12 +1,10 @@ package com.tangem.data.walletconnect.network.ethereum import arrow.core.left -import arrow.core.right import com.tangem.blockchain.blockchains.ethereum.EthereumUtils import com.tangem.blockchain.blockchains.ethereum.EthereumUtils.toKeccak import com.tangem.blockchain.common.HEX_PREFIX import com.tangem.blockchain.extensions.isAscii -import com.tangem.common.CompletionResult import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toDecompressedPublicKey import com.tangem.data.walletconnect.respond.WcRespondService @@ -14,9 +12,7 @@ import com.tangem.data.walletconnect.sign.BaseWcSignUseCase import com.tangem.data.walletconnect.sign.OnSign import com.tangem.data.walletconnect.sign.SignStateConverter.toResult import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext -import com.tangem.domain.card.models.TwinKey -import com.tangem.domain.card.repository.CardSdkConfigRepository -import com.tangem.domain.common.TapWorkarounds.isTangemTwins +import com.tangem.domain.transaction.usecase.SignUseCase import com.tangem.domain.walletconnect.model.WcEthMethod import com.tangem.domain.walletconnect.usecase.ethereum.WcPersonalEthSignUseCase import com.tangem.domain.walletconnect.usecase.sign.WcSignState @@ -30,29 +26,17 @@ internal class DefaultWcPersonalEthSignUseCase( override val context: WcMethodUseCaseContext, private val method: WcEthMethod.PersonalEthSign, private val walletManagersFacade: WalletManagersFacade, - private val cardRepository: CardSdkConfigRepository, + private val signUseCase: SignUseCase, ) : BaseWcSignUseCase(), WcPersonalEthSignUseCase { override val onSign: OnSign = collector@{ state -> val hashToSign = LegacySdkHelper.createMessageData(state.signModel.rawMsg) val userWallet = session.wallet - val card = userWallet.scanResponse.card - val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins val walletManager = walletManagersFacade.getOrCreateWalletManager(userWallet.walletId, network) ?: return@collector - val signer = cardRepository.getCommonSigner( - cardId = card.cardId.takeIf { isCardNotBackedUp }, - twinKey = TwinKey.getOrNull(scanResponse = userWallet.scanResponse), - ) - - val signResult = when (val signResult = signer.sign(hashToSign, walletManager.wallet.publicKey)) { - is CompletionResult.Failure -> signResult.error.left() - is CompletionResult.Success -> signResult.data.right() - } - - val signedHash = signResult + val signedHash = signUseCase(hashToSign, userWallet, network) .onLeft { emit(state.toResult(it.left())) } .getOrNull() ?: return@collector 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 61ac813b52..892fa06f78 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 @@ -78,4 +78,11 @@ interface TransactionRepository { cryptoCurrency: CryptoCurrency.Token, spenderAddress: String, ): BigDecimal + + suspend fun prepareForSend( + transactionData: TransactionData, + signer: TransactionSigner, + userWalletId: UserWalletId, + network: Network, + ): Result } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt new file mode 100644 index 0000000000..58d073be30 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt @@ -0,0 +1,38 @@ +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.domain.card.models.TwinKey +import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.common.TapWorkarounds.isTangemTwins +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.transaction.TransactionRepository +import com.tangem.domain.wallets.models.UserWallet + +class PrepareForSendUseCase( + private val transactionRepository: TransactionRepository, + private val cardSdkConfigRepository: CardSdkConfigRepository, +) { + suspend operator fun invoke( + transactionData: TransactionData, + userWallet: UserWallet, + network: Network, + ): Either { + 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 transactionRepository.prepareForSend( + transactionData = transactionData, + userWalletId = userWallet.walletId, + network = network, + signer = signer, + ) + .fold(onSuccess = { it.right() }, onFailure = { it.left() }) + } +} \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt new file mode 100644 index 0000000000..d5496faf38 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt @@ -0,0 +1,40 @@ +package com.tangem.domain.transaction.usecase + +import arrow.core.Either +import arrow.core.left +import arrow.core.right +import com.tangem.common.CompletionResult +import com.tangem.common.core.TangemError +import com.tangem.domain.card.models.TwinKey +import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.common.TapWorkarounds.isTangemTwins +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.models.UserWallet + +class SignUseCase( + private val cardSdkConfigRepository: CardSdkConfigRepository, + private val walletManagersFacade: WalletManagersFacade, +) { + suspend operator fun invoke( + hash: ByteArray, + userWallet: UserWallet, + network: Network, + ): Either { + 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), + ) + + val walletManager = walletManagersFacade.getOrCreateWalletManager(userWallet.walletId, network) + ?: error("WalletManager not found") + + return when (val signResult = signer.sign(hash, walletManager.wallet.publicKey)) { + is CompletionResult.Failure -> signResult.error.left() + is CompletionResult.Success -> signResult.data.right() + } + } +} \ No newline at end of file diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 55d8cba764..a32c8679a0 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 = "develop-1022" +tangemBlockchainSdk = "develop-1027" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-455" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^