Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-07 22:42:18 +08:00
parent 1b2583886d
commit 4a29162e11
7 changed files with 133 additions and 12 deletions

View file

@ -4,10 +4,7 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
import com.tangem.domain.transaction.usecase.GetFeeUseCase
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.walletmanager.WalletManagersFacade
import dagger.Module
import dagger.Provides
@ -54,4 +51,10 @@ internal object TransactionDomainModule {
fun provideIsFeeApproximateUseCase(feeRepository: FeeRepository): IsFeeApproximateUseCase {
return IsFeeApproximateUseCase(feeRepository)
}
@Provides
@ViewModelScoped
fun provideValidateTransactionUseCase(transactionRepository: TransactionRepository): ValidateTransactionUseCase {
return ValidateTransactionUseCase(transactionRepository)
}
}

View file

@ -16,6 +16,7 @@ dependencies {
implementation(deps.tangem.blockchain)
/** Core */
implementation(projects.core.datasource)
implementation(projects.core.utils)
/** Domain */
@ -28,4 +29,6 @@ dependencies {
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
implementation(deps.timber)
}

View file

@ -11,16 +11,19 @@ import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.TransactionRepository
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
internal class DefaultTransactionRepository(
private val walletManagersFacade: WalletManagersFacade,
private val walletManagersStore: WalletManagersStore,
private val coroutineDispatcherProvider: CoroutineDispatcherProvider,
) : TransactionRepository {
@ -41,17 +44,53 @@ internal class DefaultTransactionRepository(
derivationPath = network.derivationPath.value,
)
val txAmount = if (isSwap) {
createAmountForSwap(amount)
} else {
amount
}
return@withContext walletManager?.createTransaction(txAmount, fee, destination)?.copy(
return@withContext walletManager?.createTransactionInternal(
amount = amount,
fee = fee,
memo = memo,
destination = destination,
network = network,
isSwap = isSwap,
hash = hash,
extras = getMemoExtras(network.id.value, memo),
)
}
override suspend fun validateTransaction(
amount: Amount,
fee: Fee,
memo: String?,
destination: String,
userWalletId: UserWalletId,
network: Network,
isSwap: Boolean,
hash: String?,
): Result<Unit> {
val walletManager = walletManagersStore.getSyncOrNull(
userWalletId = userWalletId,
blockchain = Blockchain.fromId(network.id.value),
derivationPath = network.derivationPath.value,
)
val validator = walletManager as? TransactionValidator
return if (validator != null) {
val transaction = walletManager.createTransactionInternal(
amount = amount,
fee = fee,
memo = memo,
destination = destination,
network = network,
isSwap = isSwap,
hash = hash,
)
validator.validate(transaction = transaction)
} else {
Timber.e("${walletManager?.wallet?.blockchain} does not support transaction validation")
Result.success(Unit)
}
}
override suspend fun sendTransaction(
txData: TransactionData,
signer: CommonSigner,
@ -67,6 +106,28 @@ internal class DefaultTransactionRepository(
(walletManager as TransactionSender).send(txData, signer)
}
@Suppress("LongParameterList")
private fun WalletManager.createTransactionInternal(
amount: Amount,
fee: Fee,
memo: String?,
destination: String,
network: Network,
isSwap: Boolean,
hash: String?,
): TransactionData {
val txAmount = if (isSwap) {
createAmountForSwap(amount)
} else {
amount
}
return createTransaction(txAmount, fee, destination).copy(
hash = hash,
extras = getMemoExtras(network.id.value, memo),
)
}
private fun getMemoExtras(networkId: String, memo: String?): TransactionExtras? {
val blockchain = Blockchain.fromId(networkId)
if (memo == null) return null

View file

@ -2,6 +2,7 @@ package com.tangem.data.transaction.di
import com.tangem.data.transaction.DefaultFeeRepository
import com.tangem.data.transaction.DefaultTransactionRepository
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
@ -20,10 +21,12 @@ internal object TransactionDataModule {
@Singleton
fun providesTransactionRepository(
walletManagersFacade: WalletManagersFacade,
walletManagersStore: WalletManagersStore,
coroutineDispatcherProvider: CoroutineDispatcherProvider,
): TransactionRepository {
return DefaultTransactionRepository(
walletManagersFacade = walletManagersFacade,
walletManagersStore = walletManagersStore,
coroutineDispatcherProvider = coroutineDispatcherProvider,
)
}

View file

@ -22,6 +22,18 @@ interface TransactionRepository {
hash: String?,
): TransactionData?
@Suppress("LongParameterList")
suspend fun validateTransaction(
amount: Amount,
fee: Fee,
memo: String?,
destination: String,
userWalletId: UserWalletId,
network: Network,
isSwap: Boolean,
hash: String?,
): Result<Unit>
suspend fun sendTransaction(
txData: TransactionData,
signer: CommonSigner,

View file

@ -0,0 +1,39 @@
package com.tangem.domain.transaction.usecase
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.wallets.models.UserWalletId
class ValidateTransactionUseCase(
private val transactionRepository: TransactionRepository,
) {
@Suppress("LongParameterList")
suspend operator fun invoke(
amount: Amount,
fee: Fee,
memo: String?,
destination: String,
userWalletId: UserWalletId,
network: Network,
isSwap: Boolean = false,
hash: String? = null,
): Either<Throwable, Unit> {
return transactionRepository.validateTransaction(
amount = amount,
fee = fee,
memo = memo,
destination = destination,
userWalletId = userWalletId,
network = network,
isSwap = isSwap,
hash = hash,
)
.fold(onSuccess = { Unit.right() }, onFailure = { it.left() })
}
}

View file

@ -86,7 +86,7 @@ room = "2.6.1"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-621"
tangemBlockchainSdk = "develop-624"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-351"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^