Updated on 2026-08-14

This commit is contained in:
Tangem 2024-06-27 15:48:07 +01:00
parent f916d7394b
commit cf6ee347b8
14 changed files with 161 additions and 197 deletions

View file

@ -64,6 +64,14 @@ internal object TransactionDomainModule {
return CreateTransactionUseCase(transactionRepository)
}
@Provides
@Singleton
fun provideCreateTransactionExtrasUseCase(
transactionRepository: TransactionRepository,
): CreateTransactionDataExtrasUseCase {
return CreateTransactionDataExtrasUseCase(transactionRepository)
}
@Provides
@Singleton
fun provideEstimateFeeUseCase(walletManagersFacade: WalletManagersFacade): EstimateFeeUseCase {

View file

@ -1,28 +1,17 @@
package com.tangem.tap.proxy
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.Message
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
import com.tangem.blockchain.blockchains.optimism.EthereumOptimisticRollupWalletManager
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.common.transaction.TransactionSendResult
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.externallinkprovider.TxExploreState
import com.tangem.blockchain.network.ResultChecker
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.hexToBytes
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.models.*
import com.tangem.lib.crypto.models.transactions.SendTxResult
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TangemSigner
import java.math.BigDecimal
import java.math.BigInteger
import java.math.MathContext
@ -30,59 +19,10 @@ import java.math.RoundingMode
@Suppress("LargeClass")
class TransactionManagerImpl(
private val appStateHolder: AppStateHolder,
private val cardSdkConfigRepository: CardSdkConfigRepository,
private val walletManagersFacade: WalletManagersFacade,
private val userWalletsListManager: UserWalletsListManager,
) : TransactionManager {
override suspend fun sendApproveTransaction(
txData: ApproveTxData,
derivationPath: String?,
analyticsData: AnalyticsData,
): SendTxResult {
val blockchain = requireNotNull(Blockchain.fromNetworkId(txData.networkId)) { "blockchain not found" }
val walletManager = getActualWalletManager(blockchain, derivationPath)
walletManager.update()
val amount = Amount(value = BigDecimal.ZERO, blockchain = blockchain)
return sendTransactionInternal(
walletManager = walletManager,
amount = amount,
blockchain = blockchain,
feeAmount = txData.feeAmount,
gasLimit = txData.gasLimit,
destinationAddress = txData.destinationAddress,
dataToSign = txData.dataToSign,
)
}
@Suppress("LongParameterList")
private suspend fun sendTransactionInternal(
walletManager: WalletManager,
amount: Amount,
blockchain: Blockchain,
feeAmount: BigDecimal,
gasLimit: Int,
destinationAddress: String,
dataToSign: String,
): SendTxResult {
val txData = walletManager.createTransaction(
amount = amount,
fee = Fee.Common(Amount(value = feeAmount, blockchain = blockchain)),
destination = destinationAddress,
).copy(hash = dataToSign, extras = createExtras(walletManager, gasLimit, dataToSign))
val signer = transactionSigner(walletManager)
val sendResult = try {
(walletManager as? TransactionSender)?.send(txData, signer) ?: error("Cannot cast to TransactionSender")
} catch (ex: Exception) {
FirebaseCrashlytics.getInstance().recordException(ex)
return SendTxResult.UnknownError(ex)
}
return handleSendResult(result = sendResult)
}
override fun getExplorerTransactionLink(networkId: String, txAddress: String): String {
val blockchain = Blockchain.fromNetworkId(networkId) ?: error("blockchain not found")
return when (val txUrlState = blockchain.getExploreTxUrl(txAddress)) {
@ -301,60 +241,6 @@ class TransactionManagerImpl(
}
}
private fun handleSendResult(result: Result<TransactionSendResult>): SendTxResult {
when (result) {
is Result.Success -> {
return SendTxResult.Success
}
is Result.Failure -> {
if (ResultChecker.isNetworkError(result)) return SendTxResult.NetworkError(result.error)
val error = result.error as? BlockchainSdkError ?: return SendTxResult.UnknownError()
when (error) {
is BlockchainSdkError.WrappedTangemError -> {
val errorByCode = mapErrorByCode(error)
if (errorByCode != null) {
return errorByCode
}
val tangemSdkError = error.tangemError as? TangemSdkError ?: return SendTxResult.UnknownError()
if (tangemSdkError is TangemSdkError.UserCancelled) return SendTxResult.UserCancelledError
return SendTxResult.TangemSdkError(tangemSdkError.code, tangemSdkError.cause)
}
else -> {
return SendTxResult.TangemSdkError(error.code, error.cause)
}
}
}
}
}
private fun mapErrorByCode(error: BlockchainSdkError.WrappedTangemError): SendTxResult? {
return when (error.code) {
USER_CANCELLED_ERROR_CODE -> {
return SendTxResult.UserCancelledError
}
else -> {
null
}
}
}
private fun transactionSigner(walletManager: WalletManager): TransactionSigner {
val actualCard = requireNotNull(appStateHolder.getActualCard()) { "no card found" }
return TangemSigner(
card = actualCard,
tangemSdk = cardSdkConfigRepository.sdk,
initialMessage = Message(),
) { signResponse ->
appStateHolder.mainStore?.dispatch(
GlobalAction.UpdateWalletSignedHashes(
walletSignedHashes = signResponse.totalSignedHashes,
walletPublicKey = walletManager.wallet.publicKey.seedKey,
remainingSignatures = signResponse.remainingSignatures,
),
)
}
}
private suspend fun getActualWalletManager(blockchain: Blockchain, derivationPath: String?): WalletManager {
val selectedUserWallet = requireNotNull(
userWalletsListManager.selectedUserWalletSync,
@ -368,24 +254,6 @@ class TransactionManagerImpl(
return requireNotNull(walletManager) { "no wallet manager found" }
}
private fun createExtras(
walletManager: WalletManager,
gasLimit: Int,
transactionHash: String,
): TransactionExtras? {
return when (walletManager) {
is EthereumWalletManager -> {
return EthereumTransactionExtras(
data = transactionHash.removePrefix(HEX_PREFIX).hexToBytes(),
gasLimit = gasLimit.toBigInteger(),
)
}
else -> {
null
}
}
}
/**
* Create proxy fees
*
@ -483,8 +351,6 @@ class TransactionManagerImpl(
}
companion object {
private const val HEX_PREFIX = "0x"
private const val USER_CANCELLED_ERROR_CODE = 50002
private const val MULTIPLIER_GAS_PRICE_FOR_NORMAL_FEE = 150 // 50%
private const val MULTIPLIER_GAS_PRICE_FOR_PRIORITY_FEE = 200 // 50%
}

View file

@ -1,16 +1,16 @@
package com.tangem.tap.proxy.di
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
import com.tangem.tap.proxy.*
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.TransactionManagerImpl
import com.tangem.tap.proxy.UserWalletManagerImpl
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.flow.*
import javax.inject.Singleton
@Module
@ -38,14 +38,10 @@ internal object ProxyModule {
@Provides
@Singleton
fun provideTransactionManager(
appStateHolder: AppStateHolder,
cardSdkConfigRepository: CardSdkConfigRepository,
walletManagersFacade: WalletManagersFacade,
userWalletsListManager: UserWalletsListManager,
): TransactionManager {
return TransactionManagerImpl(
appStateHolder = appStateHolder,
cardSdkConfigRepository = cardSdkConfigRepository,
walletManagersFacade = walletManagersFacade,
userWalletsListManager = userWalletsListManager,
)

View file

@ -14,6 +14,7 @@ dependencies {
/** Tangem SDKs */
implementation(deps.tangem.blockchain)
implementation(deps.tangem.card.core)
/** Core */
implementation(projects.core.datasource)
@ -25,6 +26,7 @@ dependencies {
implementation(projects.libs.blockchainSdk)
implementation(projects.domain.wallets.models)
implementation(projects.domain.tokens.models)
implementation(projects.domain.transaction.models)
/** DI */
implementation(deps.hilt.android)

View file

@ -4,22 +4,29 @@ import androidx.core.text.isDigitsOnly
import com.tangem.blockchain.blockchains.algorand.AlgorandTransactionExtras
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
import com.tangem.blockchain.blockchains.hedera.HederaTransactionExtras
import com.tangem.blockchain.blockchains.stellar.StellarMemo
import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras
import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
import com.tangem.blockchain.blockchains.tron.TronTransactionExtras
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.common.extensions.hexToBytes
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.models.TransactionType
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
import java.math.BigInteger
import com.tangem.blockchain.blockchains.tron.TransactionType as SdkTransactionType
internal class DefaultTransactionRepository(
private val walletManagersFacade: WalletManagersFacade,
@ -111,6 +118,39 @@ internal class DefaultTransactionRepository(
(walletManager as TransactionSender).send(txData, signer)
}
override fun createTransactionDataExtras(
data: String,
network: Network,
transactionType: TransactionType,
nonce: BigInteger?,
gasLimit: BigInteger?,
): TransactionExtras {
val blockchain = Blockchain.fromNetworkId(networkId = network.backendId)
?: error("Blockchain not found")
return when {
blockchain.isEvm() -> {
EthereumTransactionExtras(
data = data.hexToBytes(),
gasLimit = gasLimit,
nonce = nonce,
)
}
blockchain == Blockchain.Tron -> {
TronTransactionExtras(
data = data.hexToBytes(),
txType = convertToSdkTransactionType(transactionType),
)
}
else -> error("Data extras not supported for $blockchain")
}
}
private fun convertToSdkTransactionType(transactionType: TransactionType): SdkTransactionType {
return when (transactionType) {
TransactionType.APPROVE -> SdkTransactionType.APPROVE
}
}
@Suppress("LongParameterList")
private fun WalletManager.createTransactionDataInternal(
amount: Amount,

View file

@ -28,6 +28,7 @@ dependencies {
implementation(projects.domain.wallets.models)
implementation(projects.domain.tokens)
implementation(projects.domain.tokens.models)
implementation(projects.domain.transaction.models)
implementation(projects.domain.demo)
implementation(projects.domain.card)
}

View file

@ -0,0 +1,5 @@
package com.tangem.domain.transaction.models
enum class TransactionType {
APPROVE,
}

View file

@ -4,7 +4,9 @@ import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionSendResult
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.models.TransactionType
import com.tangem.domain.wallets.models.UserWalletId
import java.math.BigInteger
interface TransactionRepository {
@ -40,4 +42,12 @@ interface TransactionRepository {
userWalletId: UserWalletId,
network: Network,
): com.tangem.blockchain.extensions.Result<TransactionSendResult>
fun createTransactionDataExtras(
data: String,
network: Network,
transactionType: TransactionType,
nonce: BigInteger?,
gasLimit: BigInteger?,
): TransactionExtras
}

View file

@ -0,0 +1,30 @@
package com.tangem.domain.transaction.usecase
import arrow.core.Either
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.models.TransactionType
import java.math.BigInteger
class CreateTransactionDataExtrasUseCase(
private val transactionRepository: TransactionRepository,
) {
operator fun invoke(
data: String,
network: Network,
transactionType: TransactionType,
gasLimit: BigInteger? = null,
nonce: BigInteger? = null,
) = Either.catch {
requireNotNull(
transactionRepository.createTransactionDataExtras(
data = data,
network = network,
transactionType = transactionType,
nonce = nonce,
gasLimit = gasLimit,
),
) { "Failed to create transaction" }
}
}

View file

@ -32,6 +32,7 @@ dependencies {
implementation(projects.domain.card)
implementation(projects.domain.appCurrency.models)
implementation(projects.domain.txhistory.models)
implementation(projects.domain.transaction.models)
implementation(projects.features.swap.domain.api)
implementation(projects.features.swap.domain.models)
implementation(projects.domain.staking)

View file

@ -2,12 +2,12 @@ package com.tangem.feature.swap.domain
import arrow.core.Either
import arrow.core.getOrElse
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchainsdk.utils.minimalAmount
import com.tangem.common.extensions.hexToBytes
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
@ -15,20 +15,16 @@ import com.tangem.domain.appcurrency.extenstions.unwrap
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.*
import com.tangem.domain.tokens.model.FeePaidCurrency
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.utils.convertToAmount
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
import com.tangem.domain.transaction.models.TransactionType
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
@ -42,8 +38,9 @@ import com.tangem.feature.swap.domain.models.ui.*
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
import com.tangem.lib.crypto.models.*
import com.tangem.lib.crypto.models.transactions.SendTxResult
import com.tangem.lib.crypto.models.ProxyAmount
import com.tangem.lib.crypto.models.ProxyFee
import com.tangem.lib.crypto.models.ProxyFees
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.firstOrNull
import timber.log.Timber
@ -62,6 +59,7 @@ internal class SwapInteractorImpl @Inject constructor(
private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase,
private val sendTransactionUseCase: SendTransactionUseCase,
private val createTransactionUseCase: CreateTransactionUseCase,
private val createTransactionExtrasUseCase: CreateTransactionDataExtrasUseCase,
private val quotesRepository: QuotesRepository,
private val swapTransactionRepository: SwapTransactionRepository,
private val currencyChecksRepository: CurrencyChecksRepository,
@ -214,35 +212,51 @@ internal class SwapInteractorImpl @Inject constructor(
} else {
permissionOptions.approveData.approveData
}
val result = transactionManager.sendApproveTransaction(
txData = ApproveTxData(
networkId = networkId,
feeAmount = permissionOptions.txFee.feeValue,
gasLimit = permissionOptions.txFee.gasLimit,
destinationAddress = getTokenAddress(permissionOptions.fromToken),
dataToSign = dataToSign,
val approveTransaction = createTransactionUseCase(
amount = BigDecimal.ZERO.convertToAmount(permissionOptions.fromToken),
fee = getFeeForTransaction(
fee = permissionOptions.txFee,
blockchain = Blockchain.fromId(permissionOptions.fromToken.network.id.value),
),
derivationPath = derivationPath,
analyticsData = AnalyticsData(
feeType = permissionOptions.txFee.feeType.getNameForAnalytics(),
tokenSymbol = permissionOptions.fromToken.symbol,
permissionType = permissionOptions.approveType.getNameForAnalytics(),
memo = null,
destination = getTokenAddress(permissionOptions.fromToken),
network = permissionOptions.fromToken.network,
userWalletId = requireNotNull(getSelectedWallet()).walletId,
txExtras = createDexTxExtras(
dataToSign,
permissionOptions.fromToken.network,
permissionOptions.txFee.gasLimit,
),
isSwap = false,
).getOrElse {
Timber.e(it, "Failed to create approveTransaction")
return SwapTransactionState.UnknownError
}
val result = sendTransactionUseCase(
txData = approveTransaction,
userWallet = requireNotNull(getSelectedWallet()),
network = permissionOptions.fromToken.network,
)
return when (result) {
is SendTxResult.Success -> {
return result.fold(
ifRight = { hash ->
allowPermissionsHandler.addAddressToInProgress(permissionOptions.forTokenContractAddress)
SwapTransactionState.TxSent(
txHash = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(),
txHash = hash,
timestamp = System.currentTimeMillis(),
)
}
SendTxResult.UserCancelledError -> SwapTransactionState.UserCancelled
is SendTxResult.BlockchainSdkError -> SwapTransactionState.BlockchainError
is SendTxResult.TangemSdkError -> SwapTransactionState.TangemSdkError
is SendTxResult.NetworkError -> SwapTransactionState.NetworkError
is SendTxResult.UnknownError -> SwapTransactionState.UnknownError
}
},
ifLeft = {
when (it) {
SendTransactionError.UserCancelledError -> SwapTransactionState.UserCancelled
is SendTransactionError.BlockchainSdkError -> SwapTransactionState.BlockchainError
is SendTransactionError.TangemSdkError -> SwapTransactionState.TangemSdkError
is SendTransactionError.NetworkError -> SwapTransactionState.NetworkError
is SendTransactionError.DemoCardError -> SwapTransactionState.DemoMode
else -> SwapTransactionState.UnknownError
}
},
)
}
override suspend fun findBestQuote(
@ -647,11 +661,11 @@ internal class SwapInteractorImpl @Inject constructor(
destination = swapData.transaction.txTo,
userWalletId = userWalletId,
network = currencyToSendStatus.currency.network,
txExtras = createDexTxExtras(fee.gasLimit, dataToSign),
txExtras = createDexTxExtras(dataToSign, currencyToSendStatus.currency.network, fee.gasLimit),
hash = dataToSign,
isSwap = true,
).getOrElse {
Timber.e(it)
Timber.e(it, "Failed to create swap dex tx data")
return SwapTransactionState.UnknownError
}
@ -699,13 +713,13 @@ internal class SwapInteractorImpl @Inject constructor(
)
}
private fun createDexTxExtras(gasLimit: Int, data: String): TransactionExtras {
// for now we support only Ethereum like DEX
// need to be extended if we support other blockchains in DEX
return EthereumTransactionExtras(
gasLimit = gasLimit.toBigInteger(),
data = data.removePrefix(HEX_PREFIX).hexToBytes(),
)
private fun createDexTxExtras(data: String, network: Network, gasLimit: Int?): TransactionExtras {
return createTransactionExtrasUseCase(
data = data,
network = network,
transactionType = TransactionType.APPROVE,
gasLimit = gasLimit?.toBigInteger(),
).getOrNull() ?: error("failed to create extras")
}
@Suppress("LongMethod")
@ -750,7 +764,7 @@ internal class SwapInteractorImpl @Inject constructor(
userWalletId = userWalletId,
network = currencyToSend.currency.network,
).getOrElse {
Timber.e(it)
Timber.e(it, "Failed to create swap CEX tx data")
return SwapTransactionState.UnknownError
}

View file

@ -12,10 +12,7 @@ import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
@ -45,6 +42,7 @@ class SwapDomainModule {
getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase,
@SwapScope sendTransactionUseCase: SendTransactionUseCase,
@SwapScope createTransactionUseCase: CreateTransactionUseCase,
createTransactionDataExtrasUseCase: CreateTransactionDataExtrasUseCase,
quotesRepository: QuotesRepository,
swapTransactionRepository: SwapTransactionRepository,
appCurrencyRepository: AppCurrencyRepository,
@ -63,6 +61,7 @@ class SwapDomainModule {
getMultiCryptoCurrencyStatusUseCase = getCryptoCurrencyStatusUseCase,
sendTransactionUseCase = sendTransactionUseCase,
createTransactionUseCase = createTransactionUseCase,
createTransactionExtrasUseCase = createTransactionDataExtrasUseCase,
quotesRepository = quotesRepository,
swapTransactionRepository = swapTransactionRepository,
appCurrencyRepository = appCurrencyRepository,

View file

@ -88,7 +88,7 @@ markdown = "0.7.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-688"
tangemBlockchainSdk = "develop-690"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-366"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^

View file

@ -1,18 +1,10 @@
package com.tangem.lib.crypto
import com.tangem.lib.crypto.models.*
import com.tangem.lib.crypto.models.transactions.SendTxResult
import java.math.BigDecimal
interface TransactionManager {
@Throws(IllegalStateException::class)
suspend fun sendApproveTransaction(
txData: ApproveTxData,
derivationPath: String?,
analyticsData: AnalyticsData,
): SendTxResult
/**
* Get fee
*