Updated on 2026-08-14
This commit is contained in:
parent
396760e61f
commit
40cbbfaa41
11 changed files with 243 additions and 182 deletions
|
|
@ -22,6 +22,7 @@ import com.tangem.domain.common.extensions.fromNetworkId
|
|||
import com.tangem.lib.crypto.TransactionManager
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.ProxyAmount
|
||||
import com.tangem.lib.crypto.models.ProxyFee
|
||||
import com.tangem.lib.crypto.models.ProxyNetworkInfo
|
||||
import com.tangem.lib.crypto.models.transactions.SendTxResult
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
|
|
@ -31,7 +32,11 @@ import com.tangem.tap.domain.TangemSigner
|
|||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.tangemSdk
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import java.math.MathContext
|
||||
import java.math.RoundingMode
|
||||
|
||||
@Suppress("LargeClass")
|
||||
class TransactionManagerImpl(
|
||||
private val appStateHolder: AppStateHolder,
|
||||
private val analytics: AnalyticsHandler,
|
||||
|
|
@ -40,7 +45,7 @@ class TransactionManagerImpl(
|
|||
override suspend fun sendApproveTransaction(
|
||||
networkId: String,
|
||||
feeAmount: BigDecimal,
|
||||
estimatedGas: Int,
|
||||
gasLimit: Int,
|
||||
destinationAddress: String,
|
||||
dataToSign: String,
|
||||
): SendTxResult {
|
||||
|
|
@ -53,7 +58,7 @@ class TransactionManagerImpl(
|
|||
amount = amount,
|
||||
blockchain = blockchain,
|
||||
feeAmount = feeAmount,
|
||||
estimatedGas = estimatedGas,
|
||||
gasLimit = gasLimit,
|
||||
destinationAddress = destinationAddress,
|
||||
dataToSign = dataToSign,
|
||||
)
|
||||
|
|
@ -63,7 +68,7 @@ class TransactionManagerImpl(
|
|||
networkId: String,
|
||||
amountToSend: BigDecimal,
|
||||
feeAmount: BigDecimal,
|
||||
estimatedGas: Int,
|
||||
gasLimit: Int,
|
||||
destinationAddress: String,
|
||||
dataToSign: String,
|
||||
isSwap: Boolean,
|
||||
|
|
@ -82,7 +87,7 @@ class TransactionManagerImpl(
|
|||
amount = amount,
|
||||
blockchain = blockchain,
|
||||
feeAmount = feeAmount,
|
||||
estimatedGas = estimatedGas,
|
||||
gasLimit = gasLimit,
|
||||
destinationAddress = destinationAddress,
|
||||
dataToSign = dataToSign,
|
||||
)
|
||||
|
|
@ -94,7 +99,7 @@ class TransactionManagerImpl(
|
|||
amount: Amount,
|
||||
blockchain: Blockchain,
|
||||
feeAmount: BigDecimal,
|
||||
estimatedGas: Int,
|
||||
gasLimit: Int,
|
||||
destinationAddress: String,
|
||||
dataToSign: String,
|
||||
): SendTxResult {
|
||||
|
|
@ -102,12 +107,12 @@ class TransactionManagerImpl(
|
|||
amount = amount,
|
||||
fee = Amount(value = feeAmount, blockchain = blockchain),
|
||||
destination = destinationAddress,
|
||||
).copy(hash = dataToSign, extras = createExtras(walletManager, estimatedGas, dataToSign))
|
||||
).copy(hash = dataToSign, extras = createExtras(walletManager, gasLimit, dataToSign))
|
||||
|
||||
val signer = transactionSigner(walletManager)
|
||||
|
||||
val sendResult = try {
|
||||
(walletManager as TransactionSender).send(txData, signer)
|
||||
(walletManager as? TransactionSender)?.send(txData, signer) ?: error("Cannot cast to TransactionSender")
|
||||
} catch (ex: Exception) {
|
||||
FirebaseCrashlytics.getInstance().recordException(ex)
|
||||
return SendTxResult.UnknownError(ex)
|
||||
|
|
@ -141,19 +146,54 @@ class TransactionManagerImpl(
|
|||
amountToSend: BigDecimal,
|
||||
currencyToSend: Currency,
|
||||
destinationAddress: String,
|
||||
): ProxyAmount {
|
||||
data: String?,
|
||||
): ProxyFee {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
val walletManager = getActualWalletManager(blockchain)
|
||||
val fee = (walletManager as TransactionSender).getFee(
|
||||
amount = createAmount(amountToSend, currencyToSend, blockchain),
|
||||
destination = destinationAddress,
|
||||
)
|
||||
when (fee) {
|
||||
is Result.Success -> {
|
||||
return convertToProxyAmount(fee.data.firstOrNull() ?: error("no fee found"))
|
||||
if (walletManager is EthereumWalletManager) {
|
||||
val gasLimit = getGasLimit(
|
||||
evmWalletManager = walletManager,
|
||||
blockchain = blockchain,
|
||||
amount = amountToSend,
|
||||
currency = currencyToSend,
|
||||
destinationAddress = destinationAddress,
|
||||
data = data,
|
||||
)
|
||||
return when (val gasPrice = walletManager.getGasPrice()) {
|
||||
is Result.Success -> {
|
||||
val fee = gasLimit.multiply(gasPrice.data).toBigDecimal(
|
||||
scale = blockchain.decimals(),
|
||||
mathContext = MathContext(blockchain.decimals(), RoundingMode.HALF_EVEN),
|
||||
)
|
||||
ProxyFee(
|
||||
gasLimit = gasLimit,
|
||||
fee = ProxyAmount(
|
||||
currencySymbol = blockchain.currency,
|
||||
value = fee,
|
||||
decimals = blockchain.decimals(),
|
||||
),
|
||||
)
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(gasPrice.error.message ?: gasPrice.error.customMessage)
|
||||
}
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(fee.error.message ?: fee.error.customMessage)
|
||||
} else {
|
||||
val fee = (walletManager as? TransactionSender)?.getFee(
|
||||
amount = createAmount(amountToSend, currencyToSend, blockchain),
|
||||
destination = destinationAddress,
|
||||
) ?: error("Cannot cast to TransactionSender")
|
||||
when (fee) {
|
||||
is Result.Success -> {
|
||||
// for not EVM blockchains set gasLimit ZERO for now
|
||||
return ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(fee.data.firstOrNull() ?: error("no fee found")),
|
||||
)
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(fee.error.message ?: fee.error.customMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,6 +207,37 @@ class TransactionManagerImpl(
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
private suspend fun getGasLimit(
|
||||
evmWalletManager: EthereumWalletManager,
|
||||
blockchain: Blockchain,
|
||||
amount: BigDecimal,
|
||||
currency: Currency,
|
||||
destinationAddress: String,
|
||||
data: String?,
|
||||
): BigInteger {
|
||||
val result = if (data.isNullOrEmpty()) {
|
||||
evmWalletManager.getGasLimit(
|
||||
amount = createAmount(amount, currency, blockchain),
|
||||
destination = destinationAddress,
|
||||
)
|
||||
} else {
|
||||
evmWalletManager.getGasLimit(
|
||||
amount = createAmount(amount, currency, blockchain),
|
||||
destination = destinationAddress,
|
||||
data = data,
|
||||
)
|
||||
}
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
return result.data
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(result.error.message ?: result.error.customMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSendResult(result: SimpleResult): SendTxResult {
|
||||
when (result) {
|
||||
is SimpleResult.Success -> {
|
||||
|
|
@ -239,14 +310,14 @@ class TransactionManagerImpl(
|
|||
|
||||
private fun createExtras(
|
||||
walletManager: WalletManager,
|
||||
estimatedGas: Int,
|
||||
gasLimit: Int,
|
||||
transactionHash: String,
|
||||
): TransactionExtras? {
|
||||
return when (walletManager) {
|
||||
is EthereumWalletManager -> {
|
||||
return EthereumTransactionExtras(
|
||||
data = transactionHash.removePrefix(HEX_PREFIX).hexToBytes(),
|
||||
gasLimit = estimatedGas.toBigInteger(),
|
||||
gasLimit = gasLimit.toBigInteger(),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue