From 30ba7411107ec1014f785d4d1d09bafe67d211c4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 4 Jan 2026 14:42:00 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../gasless/GetAvailableFeeTokensUseCase.kt | 84 +++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/GetAvailableFeeTokensUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/GetAvailableFeeTokensUseCase.kt index 7d57316d91..019d021363 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/GetAvailableFeeTokensUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/gasless/GetAvailableFeeTokensUseCase.kt @@ -1,15 +1,89 @@ package com.tangem.domain.transaction.usecase.gasless import arrow.core.Either -import arrow.core.left +import arrow.core.raise.Raise +import arrow.core.raise.catch +import arrow.core.raise.either +import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.network.Network -import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase +import com.tangem.domain.tokens.repository.CurrenciesRepository +import com.tangem.domain.transaction.GaslessTransactionRepository import com.tangem.domain.transaction.error.GetFeeError +import java.math.BigDecimal -class GetAvailableFeeTokensUseCase { +class GetAvailableFeeTokensUseCase( + private val gaslessTransactionRepository: GaslessTransactionRepository, + private val currenciesRepository: CurrenciesRepository, + private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase, +) { - operator fun invoke(userWalletId: UserWalletId, network: Network): Either> { - return GetFeeError.UnknownError.left() + /** + * Retrieves available tokens for gasless fee payment. + * + * @return List where first element is always native currency (for fallback) + */ + suspend operator fun invoke( + userWallet: UserWallet, + network: Network, + ): Either> { + return either { + catch( + block = { + val userCurrenciesStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync( + userWallet.walletId, + ).getOrNull() + ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}") + + val nativeCurrencyStatus = getNativeCurrencyStatus(userWallet, network, userCurrenciesStatuses) + + if (!gaslessTransactionRepository.isNetworkSupported(network)) { + return@either listOf(nativeCurrencyStatus) + } + + val gaslessTokens = getGaslessTokens(userCurrenciesStatuses) + buildList { + add(nativeCurrencyStatus) + addAll(gaslessTokens) + } + }, + catch = { + raise(GetFeeError.DataError(it)) + }, + ) + } + } + + private suspend fun Raise.getNativeCurrencyStatus( + userWallet: UserWallet, + network: Network, + userCurrenciesStatuses: List, + ): CryptoCurrencyStatus { + val nativeCurrency = currenciesRepository.getNetworkCoin( + userWalletId = userWallet.walletId, + networkId = network.id, + derivationPath = network.derivationPath, + ) + return userCurrenciesStatuses.find { + it.currency.id == nativeCurrency.id + } ?: raiseIllegalStateError("no native currency found") + } + + private fun getGaslessTokens(userCurrenciesStatuses: List): List { + val supportedGaslessTokens = gaslessTransactionRepository.getSupportedTokens() + return userCurrenciesStatuses + .asSequence() + .filter { currencyStatus -> + currencyStatus.currency is CryptoCurrency.Token && + currencyStatus.value.amount?.let { amount -> amount > BigDecimal.ZERO } == true && + supportedGaslessTokens.contains(currencyStatus.currency) + } + .toList() + } + + private fun Raise.raiseIllegalStateError(error: String): Nothing { + raise(GetFeeError.DataError(IllegalStateException(error))) } } \ No newline at end of file