Updated on 2026-08-14

This commit is contained in:
Tangem 2023-12-12 17:38:17 +03:00
parent fb11527b5b
commit b8fc09d6bf
6 changed files with 97 additions and 7 deletions

View file

@ -21,6 +21,10 @@ class DemoTransactionSender(private val walletManager: WalletManager) : Transact
)
}
override suspend fun estimateFee(amount: Amount): Result<TransactionFee> {
return getFee(amount, walletManager.wallet.address)
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
val signerResponse = signer.sign(
hash = getDataToSign(),

View file

@ -38,7 +38,7 @@ import timber.log.Timber
import java.math.BigDecimal
import java.util.EnumSet
@Suppress("LargeClass")
@Suppress("LargeClass", "TooManyFunctions")
// FIXME: Move to its own module and make internal
@Deprecated("Inject the WalletManagerFacade interface using DI instead")
class DefaultWalletManagersFacade(
@ -433,6 +433,20 @@ class DefaultWalletManagersFacade(
)
}
override suspend fun estimateFee(
amount: Amount,
userWalletId: UserWalletId,
network: Network,
): Result<TransactionFee>? {
val blockchain = Blockchain.fromId(network.id.value)
val walletManager = getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
)
return (walletManager as? TransactionSender)?.estimateFee(amount = amount)
}
override suspend fun validateTransaction(
amount: Amount,
fee: Amount?,

View file

@ -25,6 +25,7 @@ import java.util.EnumSet
/**
* A facade for managing wallets.
*/
@Suppress("TooManyFunctions")
interface WalletManagersFacade {
/**
@ -166,6 +167,15 @@ interface WalletManagersFacade {
network: Network,
): Result<TransactionFee>?
/**
* Returns estimated fee for transaction
*
* @param amount of transaction
* @param userWalletId selected wallet id
* @param network network of currency
*/
suspend fun estimateFee(amount: Amount, userWalletId: UserWalletId, network: Network): Result<TransactionFee>?
/**
* Validates transaction
*

View file

@ -0,0 +1,63 @@
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.AmountType
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.extensions.Result
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import java.math.BigDecimal
/**
* Use case to estimate transaction fee
*/
class EstimateFeeUseCase(
private val walletManagersFacade: WalletManagersFacade,
private val dispatcher: CoroutineDispatcherProvider,
) {
suspend operator fun invoke(
amount: BigDecimal,
userWalletId: UserWalletId,
cryptoCurrency: CryptoCurrency,
): Flow<Either<GetFeeError.DataError, TransactionFee>> {
return flow {
val result = walletManagersFacade.estimateFee(
amount = convertCryptoCurrencyToAmount(cryptoCurrency, amount),
userWalletId = userWalletId,
network = cryptoCurrency.network,
)
val maybeFee = when (result) {
is Result.Success -> result.data.right()
else -> GetFeeError.DataError.left()
}
emit(maybeFee)
}.flowOn(dispatcher.io)
}
private fun convertCryptoCurrencyToAmount(cryptoCurrency: CryptoCurrency, amount: BigDecimal) = Amount(
currencySymbol = cryptoCurrency.symbol,
value = amount,
decimals = cryptoCurrency.decimals,
type = when (cryptoCurrency) {
is CryptoCurrency.Coin -> AmountType.Coin
is CryptoCurrency.Token -> AmountType.Token(
token = Token(
symbol = cryptoCurrency.symbol,
contractAddress = cryptoCurrency.contractAddress,
decimals = cryptoCurrency.decimals,
),
)
},
)
}

View file

@ -13,7 +13,7 @@ import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.utils.convertToAmount
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.usecase.GetFeeUseCase
import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWallet
@ -54,8 +54,8 @@ internal class SwapInteractorImpl @Inject constructor(
private val initialToCurrencyResolver: InitialToCurrencyResolver,
) : SwapInteractor {
private val getFeeUseCase by lazy(LazyThreadSafetyMode.NONE) {
GetFeeUseCase(walletManagersFacade, dispatcher)
private val estimateFeeUseCase by lazy(LazyThreadSafetyMode.NONE) {
EstimateFeeUseCase(walletManagersFacade, dispatcher)
}
private val swapCurrencyConverter = SwapCurrencyConverter()
@ -999,9 +999,8 @@ internal class SwapInteractorImpl @Inject constructor(
networkId: String,
): TxFeeState {
getSelectedWalletSyncUseCase().getOrNull()?.walletId?.let { userWalletId ->
val txFeeResult = getFeeUseCase(
val txFeeResult = estimateFeeUseCase(
amount = amount.value,
destination = fromToken.value.networkAddress?.defaultAddress?.value ?: "",
userWalletId = userWalletId,
cryptoCurrency = fromToken.currency,
).firstOrNull()

View file

@ -88,7 +88,7 @@ spr-client = "3.6.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "release-app_5.4-416"
tangemBlockchainSdk = "release-app_5.4-417"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "release-app_5.4-315"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^