Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-15 16:40:35 +07:00
parent 13a474b281
commit a42383430b
8 changed files with 131 additions and 21 deletions

View file

@ -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)
}
}

View file

@ -280,4 +280,27 @@ internal class DefaultTransactionRepository(
else -> null
}
}
override suspend fun prepareForSend(
transactionData: TransactionData,
signer: TransactionSigner,
userWalletId: UserWalletId,
network: Network,
): Result<ByteArray> = 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)
}
}
}

View file

@ -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)

View file

@ -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<Nothing, WcPersonalEthSignUseCase.SignModel>(),
WcPersonalEthSignUseCase {
override val onSign: OnSign<WcPersonalEthSignUseCase.SignModel> = 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

View file

@ -78,4 +78,11 @@ interface TransactionRepository {
cryptoCurrency: CryptoCurrency.Token,
spenderAddress: String,
): BigDecimal
suspend fun prepareForSend(
transactionData: TransactionData,
signer: TransactionSigner,
userWalletId: UserWalletId,
network: Network,
): Result<ByteArray>
}

View file

@ -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<Throwable, ByteArray> {
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() })
}
}

View file

@ -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<TangemError, ByteArray> {
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()
}
}
}

View file

@ -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 ^