Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-22 18:47:08 +05:00
parent 9860ecc4cb
commit 5c11931241
21 changed files with 541 additions and 63 deletions

View file

@ -12,6 +12,7 @@ android {
dependencies {
/* Project - Domain */
implementation(projects.data.common)
implementation(projects.domain.models)
implementation(projects.domain.blockaid)
implementation(projects.domain.blockaid.models)
@ -20,6 +21,7 @@ dependencies {
/* Project - Core */
implementation(projects.core.utils)
implementation(projects.libs.blockchainSdk)
/* DI */
implementation(deps.hilt.core)

View file

@ -0,0 +1,31 @@
package com.tangem.data.blockaid
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
import com.tangem.blockchain.common.Blockchain
import com.tangem.datasource.api.common.blockaid.models.request.BlockAidScanOptions
import com.tangem.datasource.api.common.blockaid.models.request.Data
import com.tangem.datasource.api.common.blockaid.models.request.EvmTransactionBulkScanRequest
import com.tangem.datasource.api.common.blockaid.models.response.TransactionMetadata
import com.tangem.utils.converter.Converter
import com.tangem.blockchain.common.TransactionData as SDKTransactionData
internal class BlockAidEvmScanTransactionConverter(
private val blockchain: Blockchain,
) : Converter<List<SDKTransactionData.Uncompiled>, EvmTransactionBulkScanRequest> {
override fun convert(value: List<SDKTransactionData.Uncompiled>): EvmTransactionBulkScanRequest {
return EvmTransactionBulkScanRequest(
chain = blockchain.getChainId().toString(),
options = listOf(BlockAidScanOptions.GasEstimation.value),
metadata = TransactionMetadata(domain = "https://tangem.com"),
data = value.map {
Data(
from = it.sourceAddress,
to = it.destinationAddress,
data = (it.extras as? EthereumTransactionExtras)?.callData?.dataHex.orEmpty(),
)
},
aggregated = false,
)
}
}

View file

@ -3,11 +3,19 @@ package com.tangem.data.blockaid
import com.domain.blockaid.models.dapp.CheckDAppResult
import com.domain.blockaid.models.dapp.DAppData
import com.domain.blockaid.models.transaction.CheckTransactionResult
import com.domain.blockaid.models.transaction.GasEstimationResult
import com.domain.blockaid.models.transaction.TransactionData
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.blockchain.common.TransactionData as SDKTransactionData
interface BlockAidRepository {
suspend fun verifyDAppDomain(data: DAppData): CheckDAppResult
suspend fun verifyTransaction(data: TransactionData): CheckTransactionResult
suspend fun getGasEstimation(
cryptoCurrency: CryptoCurrency,
transactionDataList: List<SDKTransactionData.Uncompiled>,
): GasEstimationResult
}

View file

@ -0,0 +1,19 @@
package com.tangem.data.blockaid
import arrow.core.Either
import com.domain.blockaid.models.transaction.GasEstimationResult
import com.tangem.blockchain.common.TransactionData
import com.tangem.domain.blockaid.BlockAidGasEstimate
import com.tangem.domain.models.currency.CryptoCurrency
import javax.inject.Inject
class DefaultBlockAidGasEstimate @Inject constructor(
private val repository: BlockAidRepository,
) : BlockAidGasEstimate {
override suspend fun getGasEstimation(
cryptoCurrency: CryptoCurrency,
transactionDataList: List<TransactionData.Uncompiled>,
): Either<Throwable, GasEstimationResult> = Either.catch {
repository.getGasEstimation(cryptoCurrency = cryptoCurrency, transactionDataList = transactionDataList)
}
}

View file

@ -3,12 +3,18 @@ package com.tangem.data.blockaid
import com.domain.blockaid.models.dapp.CheckDAppResult
import com.domain.blockaid.models.dapp.DAppData
import com.domain.blockaid.models.transaction.CheckTransactionResult
import com.domain.blockaid.models.transaction.GasEstimationResult
import com.domain.blockaid.models.transaction.TransactionData
import com.domain.blockaid.models.transaction.TransactionParams
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.toBlockchain
import com.tangem.data.blockaid.converters.GasEstimationResponseConverter
import com.tangem.datasource.api.common.blockaid.BlockAidApi
import com.tangem.datasource.api.common.blockaid.models.request.DomainScanRequest
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.withContext
import com.tangem.blockchain.common.TransactionData as SDKTransactionData
internal class DefaultBlockAidRepository(
private val api: BlockAidApi,
@ -30,6 +36,17 @@ internal class DefaultBlockAidRepository(
}
}
override suspend fun getGasEstimation(
cryptoCurrency: CryptoCurrency,
transactionDataList: List<SDKTransactionData.Uncompiled>,
): GasEstimationResult {
val blockchain = cryptoCurrency.network.toBlockchain()
return when {
blockchain.isEvm() -> scanEvmTransactionBulk(blockchain, transactionDataList)
else -> error("Gas estimation with BlockAid not supported by ${blockchain.fullName}")
}
}
private suspend fun scanEvmTransaction(data: TransactionData): CheckTransactionResult =
withContext(dispatchers.io) {
val response = api.scanJsonRpc(mapper.mapToEvmRequest(data))
@ -41,4 +58,15 @@ internal class DefaultBlockAidRepository(
val response = api.scanSolanaMessage(mapper.mapToSolanaRequest(data))
mapper.mapToDomain(response)
}
private suspend fun scanEvmTransactionBulk(
blockchain: Blockchain,
transactionDataList: List<SDKTransactionData.Uncompiled>,
): GasEstimationResult = withContext(dispatchers.io) {
val response = api.scanEvmTransactionBulk(
BlockAidEvmScanTransactionConverter(blockchain).convert(transactionDataList),
)
GasEstimationResponseConverter.convert(response)
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.data.blockaid.converters
import com.domain.blockaid.models.transaction.GasEstimationResult
import com.tangem.blockchain.extensions.hexToBigInteger
import com.tangem.datasource.api.common.blockaid.models.response.GasEstimationResponse
import com.tangem.utils.converter.Converter
internal object GasEstimationResponseConverter : Converter<List<GasEstimationResponse>, GasEstimationResult> {
override fun convert(value: List<GasEstimationResponse>): GasEstimationResult {
return GasEstimationResult(
estimatedGasList = value.map { it.gasEstimation.estimate.hexToBigInteger() },
)
}
}

View file

@ -1,6 +1,8 @@
package com.tangem.data.blockaid.di
import com.tangem.data.blockaid.DefaultBlockAidGasEstimate
import com.tangem.data.blockaid.DefaultBlockAidVerifier
import com.tangem.domain.blockaid.BlockAidGasEstimate
import com.tangem.domain.blockaid.BlockAidVerifier
import dagger.Binds
import dagger.Module
@ -15,4 +17,8 @@ interface BlockAidDataModule {
@Binds
@Singleton
fun bindVerifier(verifier: DefaultBlockAidVerifier): BlockAidVerifier
@Binds
@Singleton
fun bindBlockAidGasEstimate(gasEstimate: DefaultBlockAidGasEstimate): BlockAidGasEstimate
}