Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-07 11:39:32 +05:00
parent d38b62a559
commit 069ff2f4e1
7 changed files with 36 additions and 8 deletions

View file

@ -98,6 +98,7 @@ dependencies {
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
implementation(projects.domain.transaction)
implementation(projects.domain.transaction.models)
implementation(projects.domain.analytics)
implementation(projects.domain.visa)
implementation(projects.domain.onboarding)

View file

@ -18,6 +18,7 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runCatching
@ -130,6 +131,18 @@ internal class DefaultRampManager(
}
}
override fun checkAssetRequirements(requirements: AssetRequirementsCondition?): Boolean {
return when (requirements) {
AssetRequirementsCondition.PaidTransaction,
is AssetRequirementsCondition.PaidTransactionWithFee,
is AssetRequirementsCondition.RequiredTrustline,
-> false
is AssetRequirementsCondition.IncompleteTransaction,
null,
-> true
}
}
private suspend fun getExchangeableState(
userWalletId: UserWalletId,
cryptoCurrency: CryptoCurrency,

View file

@ -7,11 +7,13 @@ import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import kotlinx.coroutines.flow.Flow
/**
* Manager that holds info about available actions as Sell and Buy
*/
@Deprecated("Move to express domain layer")
interface RampStateManager {
suspend fun availableForBuy(userWallet: UserWallet, cryptoCurrency: CryptoCurrency): ScenarioUnavailabilityReason
@ -50,4 +52,9 @@ interface RampStateManager {
userWalletId: UserWalletId,
cryptoCurrencyStatus: CryptoCurrencyStatus,
): ScenarioUnavailabilityReason
/**
* Returns whether asset requirements are full filled to be able use express services
*/
fun checkAssetRequirements(requirements: AssetRequirementsCondition?): Boolean
}

View file

@ -22,7 +22,6 @@ import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
@ -212,21 +211,22 @@ internal class OnrampTokenListModel @Inject constructor(
val isOperationAvailable = checkAvailabilityByOperation(status = status)
val isNotMissedDerivation = status.value !is CryptoCurrencyStatus.MissedDerivation
val isNotLoading = status.value !is CryptoCurrencyStatus.Loading
val requirements = getAssetRequirementsUseCase(
userWalletId = userWallet.walletId,
currency = status.currency,
).getOrNull()
val isNotTrustlineRequired = requirements !is AssetRequirementsCondition.RequiredTrustline
val isAvailableForBuy = rampStateManager.checkAssetRequirements(requirements)
val isNotUnreachable = status.value !is CryptoCurrencyStatus.Unreachable
val isAvailable = when (params.filterOperation) {
OnrampOperation.BUY -> {
isNotTrustlineRequired
isAvailableForBuy
} // unreachable state is available for Buy operation
OnrampOperation.SELL -> isNotUnreachable
OnrampOperation.SWAP -> {
isNotUnreachable && isNotTrustlineRequired
isNotUnreachable && isAvailableForBuy
}
}

View file

@ -25,10 +25,10 @@ import com.tangem.datasource.api.express.models.response.TxDetails
import com.tangem.datasource.crypto.DataSignatureVerifier
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.swap.converters.*
@ -55,6 +55,7 @@ internal class DefaultSwapRepository(
private val errorsDataConverter: ErrorsDataConverter,
private val dataSignatureVerifier: DataSignatureVerifier,
private val appPreferencesStore: AppPreferencesStore,
private val rampStateManager: RampStateManager,
moshi: Moshi,
excludedBlockchains: ExcludedBlockchains,
) : SwapRepository {
@ -138,7 +139,8 @@ internal class DefaultSwapRepository(
val currenciesList = currencyList
.filter {
val requirements = walletManagersFacade.getAssetRequirements(userWallet.walletId, it)
requirements !is AssetRequirementsCondition.RequiredTrustline
val isAvailableForSwap = rampStateManager.checkAssetRequirements(requirements)
isAvailableForSwap
}
.map { leastTokenInfoConverter.convert(it) }

View file

@ -8,6 +8,7 @@ import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
import com.tangem.datasource.crypto.DataSignatureVerifier
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.swap.DefaultSwapRepository
@ -38,6 +39,7 @@ internal class SwapDataModule {
@NetworkMoshi moshi: Moshi,
excludedBlockchains: ExcludedBlockchains,
appPreferencesStore: AppPreferencesStore,
rampStateManager: RampStateManager,
): SwapRepository {
return DefaultSwapRepository(
tangemExpressApi = tangemExpressApi,
@ -49,6 +51,7 @@ internal class SwapDataModule {
moshi = moshi,
excludedBlockchains = excludedBlockchains,
appPreferencesStore = appPreferencesStore,
rampStateManager = rampStateManager,
)
}

View file

@ -17,6 +17,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.extenstions.unwrap
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.quote.QuoteStatus
@ -31,7 +32,6 @@ import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
@ -82,6 +82,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
private val getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
private val amountFormatter: AmountFormatter,
private val rampStateManager: RampStateManager,
@Assisted private val userWalletId: UserWalletId,
) : SwapInteractor {
@ -179,12 +180,13 @@ internal class SwapInteractorImpl @AssistedInject constructor(
tokenInfoForAvailable: (SwapPairLeast) -> LeastTokenInfo,
): List<SwapProvider>? {
val requirements = getAssetRequirementsUseCase.invoke(userWalletId, cryptoCurrencyStatuses.currency).getOrNull()
val isAvailableForSwap = rampStateManager.checkAssetRequirements(requirements)
return swapPairsLeastList.firstNotNullOfOrNull {
val listTokenInfo = tokenInfoForAvailable(it)
if (cryptoCurrencyStatuses.currency.network.backendId == listTokenInfo.network &&
cryptoCurrencyStatuses.currency.getContractAddress() == listTokenInfo.contractAddress &&
requirements !is AssetRequirementsCondition.RequiredTrustline
isAvailableForSwap
) {
it.providers
} else {