Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-15 19:30:17 +05:00
parent 9ebc1ac551
commit 25664700f6
20 changed files with 1261 additions and 17 deletions

View file

@ -10,6 +10,10 @@ android {
namespace = "com.tangem.data.transaction"
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
dependencies {
/** Tangem SDKs */
@ -21,13 +25,14 @@ dependencies {
implementation(projects.core.utils)
/** Domain */
implementation(projects.domain.transaction)
implementation(projects.libs.blockchainSdk)
implementation(projects.domain.legacy)
implementation(projects.domain.walletManager)
implementation(projects.libs.blockchainSdk)
implementation(projects.domain.wallets.models)
implementation(projects.domain.tokens.models)
implementation(projects.domain.transaction.models)
implementation(projects.domain.transaction)
implementation(projects.domain.demo)
/** DI */
implementation(deps.hilt.android)
@ -35,4 +40,12 @@ dependencies {
/** Other */
implementation(deps.timber)
/** tests */
testImplementation(projects.common.test)
testImplementation(deps.test.junit5)
testRuntimeOnly(deps.test.junit5.engine)
testImplementation(deps.test.coroutine)
testImplementation(deps.test.truth)
testImplementation(deps.test.mockk)
}

View file

@ -1,13 +1,57 @@
package com.tangem.data.transaction
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchainsdk.utils.toBlockchain
import com.tangem.domain.demo.DemoTransactionSender
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
internal class DefaultFeeRepository : FeeRepository {
internal class DefaultFeeRepository(
private val walletManagersFacade: WalletManagersFacade,
private val demoConfig: DemoConfig,
) : FeeRepository {
override fun isFeeApproximate(networkId: Network.ID, amountType: AmountType): Boolean {
return networkId.toBlockchain().isFeeApproximate(amountType)
}
override suspend fun calculateFee(
userWallet: UserWallet,
cryptoCurrency: CryptoCurrency,
transactionData: TransactionData,
): TransactionFee {
val transactionSender = if (userWallet is UserWallet.Cold &&
demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)
) {
demoTransactionSender(userWallet, cryptoCurrency)
} else {
walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWallet.walletId,
network = cryptoCurrency.network,
) ?: error("WalletManager is null")
}
return when (val result = transactionSender.getFee(transactionData)) {
is Result.Success -> result.data
is Result.Failure -> throw result.error
}
}
private suspend fun demoTransactionSender(
userWallet: UserWallet,
cryptoCurrency: CryptoCurrency,
): DemoTransactionSender {
return DemoTransactionSender(
walletManagersFacade
.getOrCreateWalletManager(userWallet.walletId, cryptoCurrency.network)
?: error("WalletManager is null"),
)
}
}

View file

@ -3,10 +3,13 @@ package com.tangem.data.transaction.di
import com.tangem.data.transaction.DefaultFeeRepository
import com.tangem.data.transaction.DefaultTransactionRepository
import com.tangem.data.transaction.DefaultWalletAddressServiceRepository
import com.tangem.data.transaction.error.DefaultFeeErrorResolver
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.WalletAddressServiceRepository
import com.tangem.domain.transaction.error.FeeErrorResolver
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
@ -35,8 +38,11 @@ internal object TransactionDataModule {
@Provides
@Singleton
fun providesFeeRepository(): FeeRepository {
return DefaultFeeRepository()
fun providesFeeRepository(walletManagersFacade: WalletManagersFacade): FeeRepository {
return DefaultFeeRepository(
walletManagersFacade,
demoConfig = DemoConfig(),
)
}
@Provides
@ -50,4 +56,10 @@ internal object TransactionDataModule {
dispatchers = coroutineDispatcherProvider,
)
}
@Provides
@Singleton
fun providerFeeErrorResolver(): FeeErrorResolver {
return DefaultFeeErrorResolver()
}
}

View file

@ -0,0 +1,22 @@
package com.tangem.data.transaction.error
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.domain.transaction.error.FeeErrorResolver
import com.tangem.domain.transaction.error.GetFeeError
internal class DefaultFeeErrorResolver : FeeErrorResolver {
override fun resolve(throwable: Throwable): GetFeeError {
return when (throwable) {
is BlockchainSdkError.Tron.AccountActivationError -> {
GetFeeError.BlockchainErrors.TronActivationError
}
is BlockchainSdkError.Kaspa.ZeroUtxoError -> {
GetFeeError.BlockchainErrors.KaspaZeroUtxo
}
is BlockchainSdkError.Sui.OneSuiRequired -> {
GetFeeError.BlockchainErrors.SuiOneCoinRequired
}
else -> GetFeeError.DataError(throwable)
}
}
}