diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/gasless/models/GaslessSignedTransactionResultDTO.kt b/core/datasource/src/main/java/com/tangem/datasource/api/gasless/models/GaslessSignedTransactionResultDTO.kt index c8bd1b89b4..8184f49c1c 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/gasless/models/GaslessSignedTransactionResultDTO.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/gasless/models/GaslessSignedTransactionResultDTO.kt @@ -9,15 +9,6 @@ import com.squareup.moshi.JsonClass */ @JsonClass(generateAdapter = true) data class GaslessSignedTransactionResultDTO( - @Json(name = "signedTransaction") - val signedTransaction: String, - - @Json(name = "gasLimit") - val gasLimit: String, - - @Json(name = "maxFeePerGas") - val maxFeePerGas: String, - - @Json(name = "maxPriorityFeePerGas") - val maxPriorityFeePerGas: String, + @Json(name = "txHash") + val txHash: String, ) \ No newline at end of file diff --git a/data/transaction/build.gradle.kts b/data/transaction/build.gradle.kts index cb26912c17..7becb2b968 100644 --- a/data/transaction/build.gradle.kts +++ b/data/transaction/build.gradle.kts @@ -37,6 +37,9 @@ dependencies { implementation(projects.domain.transaction) implementation(projects.domain.demo) + /** Api */ + implementation(projects.features.sendV2.api) + /** DI */ implementation(deps.hilt.android) kapt(deps.hilt.kapt) diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultGaslessTransactionRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultGaslessTransactionRepository.kt index d99d586e16..b4d16fbe7e 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultGaslessTransactionRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultGaslessTransactionRepository.kt @@ -13,6 +13,7 @@ import com.tangem.domain.transaction.GaslessTransactionRepository import com.tangem.domain.transaction.models.Eip7702Authorization import com.tangem.domain.transaction.models.GaslessSignedTransactionResult import com.tangem.domain.transaction.models.GaslessTransactionData +import com.tangem.features.send.v2.api.SendFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update @@ -25,6 +26,7 @@ class DefaultGaslessTransactionRepository( private val gaslessTxServiceApi: GaslessTxServiceApi, private val coroutineDispatcherProvider: CoroutineDispatcherProvider, private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, + private val sendFeatureToggles: SendFeatureToggles, ) : GaslessTransactionRepository { private val supportedTokensState = MutableStateFlow>>(hashMapOf()) @@ -120,6 +122,9 @@ class DefaultGaslessTransactionRepository( } override suspend fun getGaslessFeeAddresses(): Set { + if (!sendFeatureToggles.isGaslessTransactionsEnabled) { + return EMPTY_ADDRESSES + } return addressesMutex.withLock { allFeeRecipientAddress.ifEmpty { val allFeeAddresses = getAllFeeRecipientAddresses() @@ -136,5 +141,6 @@ class DefaultGaslessTransactionRepository( private companion object { val BASE_GAS_FOR_TRANSACTION: BigInteger = BigInteger("100000") + val EMPTY_ADDRESSES = emptySet() } } \ No newline at end of file diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/MockedGaslessTransactionRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/MockedGaslessTransactionRepository.kt index 0a52be64e3..be0a8b25f4 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/MockedGaslessTransactionRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/MockedGaslessTransactionRepository.kt @@ -49,10 +49,7 @@ class MockedGaslessTransactionRepository( network: Network, eip7702Auth: Eip7702Authorization?, ): GaslessSignedTransactionResult = GaslessSignedTransactionResult( - signedTransaction = "0x000", - gasLimit = 100000.toBigInteger(), - maxFeePerGas = 21000.toBigInteger(), - maxPriorityFeePerGas = 21000.toBigInteger(), + txHash = "0x000", ) override fun getBaseGasForTransaction(): BigInteger { diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/convertes/GaslessSignedTransactionResultConverter.kt b/data/transaction/src/main/java/com/tangem/data/transaction/convertes/GaslessSignedTransactionResultConverter.kt index 4c8a6e62ef..b4188cd05a 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/convertes/GaslessSignedTransactionResultConverter.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/convertes/GaslessSignedTransactionResultConverter.kt @@ -1,6 +1,6 @@ package com.tangem.data.transaction.convertes -import com.tangem.datasource.api.gasless.models.GaslessSignedTransactionResultDTO as GaslessSignedTransactionResultDTO +import com.tangem.datasource.api.gasless.models.GaslessSignedTransactionResultDTO import com.tangem.domain.transaction.models.GaslessSignedTransactionResult import com.tangem.utils.converter.Converter @@ -13,10 +13,7 @@ class GaslessSignedTransactionResultConverter : override fun convert(value: GaslessSignedTransactionResultDTO): GaslessSignedTransactionResult { return GaslessSignedTransactionResult( - signedTransaction = value.signedTransaction, - gasLimit = value.gasLimit.toBigInteger(), - maxFeePerGas = value.maxFeePerGas.toBigInteger(), - maxPriorityFeePerGas = value.maxPriorityFeePerGas.toBigInteger(), + txHash = value.txHash, ) } } \ No newline at end of file diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt index 731006b04d..8083f49496 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt @@ -16,6 +16,7 @@ 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.features.send.v2.api.SendFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module import dagger.Provides @@ -76,11 +77,13 @@ internal object TransactionDataModule { responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, gaslessTxServiceApi: GaslessTxServiceApi, coroutineDispatcherProvider: CoroutineDispatcherProvider, + sendFeatureToggles: SendFeatureToggles, ): GaslessTransactionRepository { return DefaultGaslessTransactionRepository( - gaslessTxServiceApi, - coroutineDispatcherProvider, - responseCryptoCurrenciesFactory, + gaslessTxServiceApi = gaslessTxServiceApi, + coroutineDispatcherProvider = coroutineDispatcherProvider, + responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory, + sendFeatureToggles = sendFeatureToggles, ) } } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/models/GaslessSignedTransactionResult.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/models/GaslessSignedTransactionResult.kt index 3d41d103dd..0bdb72570c 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/models/GaslessSignedTransactionResult.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/models/GaslessSignedTransactionResult.kt @@ -1,7 +1,5 @@ package com.tangem.domain.transaction.models -import java.math.BigInteger - /** * Result of gasless transaction signing from the gasless service. * Contains the fully signed transaction ready for broadcasting and gas parameters. @@ -12,26 +10,12 @@ import java.math.BigInteger * 3. Constructs the final transaction * 4. Returns this signed transaction with gas parameters * - * @property signedTransaction complete signed transaction in RLP-encoded hex format (0x...) - * ready to be broadcast to the blockchain network - * @property gasLimit maximum amount of gas units allocated for the transaction - * @property maxFeePerGas maximum total fee per gas unit (base fee + priority fee) in wei - * @property maxPriorityFeePerGas maximum priority fee (tip) per gas unit in wei for EIP-1559 + * @property txHash sent tx hash */ data class GaslessSignedTransactionResult( - val signedTransaction: String, - val gasLimit: BigInteger, - val maxFeePerGas: BigInteger, - val maxPriorityFeePerGas: BigInteger, + val txHash: String, ) { init { - require(signedTransaction.isNotBlank()) { "Signed transaction must not be blank" } - require(signedTransaction.startsWith("0x")) { "Signed transaction must be in hex format with 0x prefix" } - require(gasLimit > BigInteger.ZERO) { "Gas limit must be positive" } - require(maxFeePerGas > BigInteger.ZERO) { "Max fee per gas must be positive" } - require(maxPriorityFeePerGas >= BigInteger.ZERO) { "Max priority fee per gas must be non-negative" } - require(maxPriorityFeePerGas <= maxFeePerGas) { - "Max priority fee per gas cannot exceed max fee per gas" - } + require(txHash.isNotBlank()) { "Tx hash must not be blank" } } } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/CreateAndSendGaslessTransactionUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/CreateAndSendGaslessTransactionUseCase.kt index 853e9b55e2..4d2d4e9a0d 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/CreateAndSendGaslessTransactionUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/CreateAndSendGaslessTransactionUseCase.kt @@ -26,7 +26,6 @@ import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase import com.tangem.domain.transaction.GaslessTransactionRepository import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.models.Eip7702Authorization -import com.tangem.domain.transaction.models.GaslessSignedTransactionResult import com.tangem.domain.transaction.models.GaslessTransactionData import com.tangem.domain.transaction.models.TransactionFeeExtended import com.tangem.domain.walletmanager.WalletManagersFacade @@ -50,8 +49,7 @@ class CreateAndSendGaslessTransactionUseCase( val uncompiledTxData = validateTransactionData(transactionData) val context = prepareGaslessContext(userWallet, uncompiledTxData, fee) val signedData = signGaslessTransactionByUser(userWallet, context, uncompiledTxData) - val remoteSignedData = signTransactionOnBackend(context, signedData, uncompiledTxData) - broadcastSignedTransaction(context, remoteSignedData) + signAndSendTransactionOnBackend(context, signedData, uncompiledTxData) }, catch = { raise(SendTransactionError.DataError(it.message)) @@ -185,32 +183,18 @@ class CreateAndSendGaslessTransactionUseCase( /** * Sends gasless transaction to the service. */ - private suspend fun signTransactionOnBackend( + private suspend fun signAndSendTransactionOnBackend( context: GaslessContext, signedData: SignedGaslessData, transactionData: TransactionData.Uncompiled, - ): GaslessSignedTransactionResult { + ): String { return gaslessTransactionRepository.signGaslessTransaction( network = context.tokenForFeeStatus.currency.network, gaslessTransactionData = context.gaslessTransactionData, signature = signedData.eip712Signature, userAddress = transactionData.sourceAddress, eip7702Auth = signedData.eip7702Auth, - ) - } - - private suspend fun broadcastSignedTransaction( - context: GaslessContext, - remoteSignedData: GaslessSignedTransactionResult, - ): String { - val transactionSender = context.walletManager as? TransactionSender ?: error( - "WalletManager for network ${context.tokenForFeeStatus.currency.network.id} " + - "does not support transaction sending", - ) - return when (val result = transactionSender.broadcastTransaction(remoteSignedData.signedTransaction)) { - is Result.Failure -> throw result.error - is Result.Success -> result.data.hash - } + ).txHash } private suspend fun signHashes( diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index a83a0a796c..2479812b57 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -425,8 +425,8 @@ internal class SendConfirmModel @Inject constructor( ), ) }, - ifRight = { - updateTransactionStatus(txData) + ifRight = { txHash -> + updateTransactionStatus(txData, txHash) addTokenToWalletIfNeeded() sendBalanceUpdater.scheduleUpdates() sendAnalyticHelper.sendSuccessAnalytics( @@ -479,9 +479,9 @@ internal class SendConfirmModel @Inject constructor( } } - private fun updateTransactionStatus(txData: TransactionData.Uncompiled) { + private fun updateTransactionStatus(txData: TransactionData.Uncompiled, txHash: String) { val txUrl = getExplorerTransactionUrlUseCase( - txHash = txData.hash.orEmpty(), + txHash = txHash.ifEmpty { txData.hash.orEmpty() }, networkId = cryptoCurrency.network.id, ).getOrNull().orEmpty() _uiState.update(SendConfirmSentStateTransformer(txData, txUrl))