diff --git a/app/src/main/java/com/tangem/tap/di/ActivityModule.kt b/app/src/main/java/com/tangem/tap/di/ActivityModule.kt index 85d5a6630b..368216c920 100644 --- a/app/src/main/java/com/tangem/tap/di/ActivityModule.kt +++ b/app/src/main/java/com/tangem/tap/di/ActivityModule.kt @@ -2,7 +2,6 @@ package com.tangem.tap.di import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader -import com.tangem.datasource.local.token.ExpressAssetsStore import com.tangem.domain.card.ScanCardUseCase import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.exchange.RampStateManager @@ -55,7 +54,6 @@ internal object ActivityModule { excludedBlockchains: ExcludedBlockchains, dispatchers: CoroutineDispatcherProvider, onrampFeatureToggles: OnrampFeatureToggles, - expressAssetsStore: ExpressAssetsStore, ): RampStateManager { return DefaultRampManager( exchangeService = appStateHolder.exchangeService, @@ -67,7 +65,6 @@ internal object ActivityModule { excludedBlockchains = excludedBlockchains, dispatchers = dispatchers, onrampFeatureToggles = onrampFeatureToggles, - expressAssetsStore = expressAssetsStore, ) } diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt index d53b637ce1..2671d88af8 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt @@ -9,9 +9,8 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE import com.tangem.datasource.api.express.models.response.Asset import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader -import com.tangem.datasource.local.token.ExpressAssetsStore import com.tangem.domain.core.lce.Lce -import com.tangem.domain.exchange.ExchangeableState +import com.tangem.domain.exchange.ExpressAvailabilityState import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase @@ -27,7 +26,6 @@ import com.tangem.utils.coroutines.runCatching import com.tangem.utils.isNullOrZero import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.withContext @Suppress("LongParameterList") internal class DefaultRampManager( @@ -39,7 +37,6 @@ internal class DefaultRampManager( private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase, private val dispatchers: CoroutineDispatcherProvider, private val onrampFeatureToggles: OnrampFeatureToggles, - private val expressAssetsStore: ExpressAssetsStore, excludedBlockchains: ExcludedBlockchains, ) : RampStateManager { @@ -49,19 +46,12 @@ internal class DefaultRampManager( scanResponse: ScanResponse, userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - ): Boolean { - return runCatching { - when { - onrampFeatureToggles.isFeatureEnabled -> getOnrampAvailable(userWalletId, cryptoCurrency) - exchangeService != null -> exchangeService.availableForBuy( - scanResponse = scanResponse, - currency = cryptoCurrencyConverter.convertBack(cryptoCurrency), - ) - else -> false - } - } - .getOrNull() - ?: false + ): ScenarioUnavailabilityReason { + val availabilityState = runCatching { + getOnrampAvailableState(scanResponse, userWalletId, cryptoCurrency) + }.getOrNull() ?: ExpressAvailabilityState.Error + + return availabilityState.toReason(cryptoCurrency.name) } override suspend fun availableForSell( @@ -103,8 +93,11 @@ internal class DefaultRampManager( override suspend fun availableForSwap( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - ): ExchangeableState { - return runCatching { getExchangeableState(userWalletId, cryptoCurrency) }.getOrNull() ?: ExchangeableState.Error + ): ScenarioUnavailabilityReason { + val availabilityState = runCatching { + getExchangeableState(userWalletId, cryptoCurrency) + }.getOrNull() ?: ExpressAvailabilityState.Error + return availabilityState.toReason(cryptoCurrency.name) } override fun getBuyInitializationStatus(): Flow { @@ -134,33 +127,76 @@ internal class DefaultRampManager( private suspend fun getExchangeableState( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - ): ExchangeableState { - return withContext(dispatchers.io) { - val asset = expressServiceLoader.getInitializationStatus(userWalletId).firstOrNull() - ?: return@withContext ExchangeableState.Loading - when (asset) { - is Lce.Error -> ExchangeableState.Error - is Lce.Loading -> ExchangeableState.Loading - is Lce.Content -> { - val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(it) } - foundAsset?.exchangeAvailable?.toExchangeableState() ?: ExchangeableState.AssetNotFound - } + ): ExpressAvailabilityState { + val asset = expressServiceLoader.getInitializationStatus(userWalletId).firstOrNull() + ?: return ExpressAvailabilityState.Loading + return when (asset) { + is Lce.Error -> ExpressAvailabilityState.Error + is Lce.Loading -> ExpressAvailabilityState.Loading + is Lce.Content -> { + val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(it) } + foundAsset?.exchangeAvailable?.toSwapAvailabilityState() + ?: ExpressAvailabilityState.AssetNotFound } } } - private fun Boolean.toExchangeableState(): ExchangeableState { - return if (this) { - ExchangeableState.Exchangeable - } else { - ExchangeableState.NotExchangeable + private suspend fun getOnrampAvailableState( + scanResponse: ScanResponse, + userWalletId: UserWalletId, + cryptoCurrency: CryptoCurrency, + ): ExpressAvailabilityState { + return when { + onrampFeatureToggles.isFeatureEnabled -> { + val asset = expressServiceLoader.getInitializationStatus(userWalletId).firstOrNull() + ?: return ExpressAvailabilityState.Loading + return when (asset) { + is Lce.Error -> ExpressAvailabilityState.Error + is Lce.Loading -> ExpressAvailabilityState.Loading + is Lce.Content -> { + val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(it) } + foundAsset?.onrampAvailable?.toOnrampAvailabilityState() + ?: ExpressAvailabilityState.AssetNotFound + } + } + } + exchangeService != null -> { + exchangeService.availableForBuy( + scanResponse = scanResponse, + currency = cryptoCurrencyConverter.convertBack(cryptoCurrency), + ).toOnrampAvailabilityState() + } + else -> ExpressAvailabilityState.Error } } - private suspend fun getOnrampAvailable(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean { - val asset = expressAssetsStore.getSyncOrNull(userWalletId)?.find { cryptoCurrency.findAssetPredicate(it) } + private fun ExpressAvailabilityState.toReason(currencyName: String): ScenarioUnavailabilityReason { + return when (this) { + ExpressAvailabilityState.Available -> { + ScenarioUnavailabilityReason.None + } + ExpressAvailabilityState.AssetNotFound -> ScenarioUnavailabilityReason.AssetNotFound(currencyName) + ExpressAvailabilityState.Error -> ScenarioUnavailabilityReason.ExpressUnreachable(currencyName) + ExpressAvailabilityState.Loading -> ScenarioUnavailabilityReason.ExpressLoading(currencyName) + ExpressAvailabilityState.NotOnrampable -> ScenarioUnavailabilityReason.BuyUnavailable(currencyName) + ExpressAvailabilityState.NotExchangeable -> ScenarioUnavailabilityReason.NotExchangeable(currencyName) + } + } - return asset?.onrampAvailable ?: false + private fun Boolean.toSwapAvailabilityState(): ExpressAvailabilityState { + return if (this) { + ExpressAvailabilityState.Available + } else { + ExpressAvailabilityState.NotExchangeable + } + } + + private fun Boolean.toOnrampAvailabilityState(): ExpressAvailabilityState { + return if (this) { + ExpressAvailabilityState.Available + } else { + ExpressAvailabilityState.NotOnrampable + } } private fun CryptoCurrency.findAssetPredicate(asset: Asset): Boolean { diff --git a/domain/legacy/src/main/java/com/tangem/domain/exchange/ExchangeableState.kt b/domain/legacy/src/main/java/com/tangem/domain/exchange/ExchangeableState.kt deleted file mode 100644 index 9a4f140cf1..0000000000 --- a/domain/legacy/src/main/java/com/tangem/domain/exchange/ExchangeableState.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.domain.exchange - -sealed interface ExchangeableState { - data object Exchangeable : ExchangeableState - data object NotExchangeable : ExchangeableState - data object Loading : ExchangeableState - data object Error : ExchangeableState - data object AssetNotFound : ExchangeableState -} \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/exchange/ExpressAvailabilityState.kt b/domain/legacy/src/main/java/com/tangem/domain/exchange/ExpressAvailabilityState.kt new file mode 100644 index 0000000000..a0e960f17e --- /dev/null +++ b/domain/legacy/src/main/java/com/tangem/domain/exchange/ExpressAvailabilityState.kt @@ -0,0 +1,10 @@ +package com.tangem.domain.exchange + +sealed interface ExpressAvailabilityState { + data object Available : ExpressAvailabilityState + data object NotExchangeable : ExpressAvailabilityState + data object NotOnrampable : ExpressAvailabilityState + data object Loading : ExpressAvailabilityState + data object Error : ExpressAvailabilityState + data object AssetNotFound : ExpressAvailabilityState +} \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/exchange/RampStateManager.kt b/domain/legacy/src/main/java/com/tangem/domain/exchange/RampStateManager.kt index 180a8b16b5..e8a8f3a363 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/exchange/RampStateManager.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/exchange/RampStateManager.kt @@ -18,7 +18,7 @@ interface RampStateManager { scanResponse: ScanResponse, userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - ): Boolean + ): ScenarioUnavailabilityReason /** * Check if [CryptoCurrency] is available for sell @@ -31,7 +31,10 @@ interface RampStateManager { status: CryptoCurrencyStatus, ): Either - suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): ExchangeableState + suspend fun availableForSwap( + userWalletId: UserWalletId, + cryptoCurrency: CryptoCurrency, + ): ScenarioUnavailabilityReason suspend fun fetchBuyServiceData() diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index 7e2b95240b..315c353ae8 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -1,7 +1,6 @@ package com.tangem.domain.tokens import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.exchange.ExchangeableState import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.models.StatusSource import com.tangem.domain.promo.PromoRepository @@ -168,12 +167,11 @@ class GetCryptoCurrencyActionsUseCase( } // buy - if (rampManager.availableForBuy(userWallet.scanResponse, userWallet.walletId, cryptoCurrency)) { - activeList.add(TokenActionsState.ActionState.Buy(ScenarioUnavailabilityReason.None)) + val onrampActionState = getOnrampUnavailabilityReason(userWallet, cryptoCurrencyStatus) + if (onrampActionState.unavailabilityReason == ScenarioUnavailabilityReason.None) { + activeList.add(onrampActionState) } else { - disabledList.add( - TokenActionsState.ActionState.Buy(ScenarioUnavailabilityReason.BuyUnavailable(cryptoCurrency.symbol)), - ) + disabledList.add(onrampActionState) } // region sell @@ -229,38 +227,37 @@ class GetCryptoCurrencyActionsUseCase( cryptoCurrencyStatus: CryptoCurrencyStatus, requirements: AssetRequirementsCondition?, ): List { - val actionsList = mutableListOf() + val activeList = mutableListOf() + val disabledList = mutableListOf() if (isAddressAvailable(cryptoCurrencyStatus.value.networkAddress)) { - actionsList.add(TokenActionsState.ActionState.CopyAddress(ScenarioUnavailabilityReason.None)) + activeList.add(TokenActionsState.ActionState.CopyAddress(ScenarioUnavailabilityReason.None)) } - if (rampManager.availableForBuy(userWallet.scanResponse, userWallet.walletId, cryptoCurrencyStatus.currency)) { - actionsList.add(TokenActionsState.ActionState.Buy(ScenarioUnavailabilityReason.None)) + + // buy (is not depend on cache) + val onrampActionState = getOnrampUnavailabilityReason(userWallet, cryptoCurrencyStatus) + if (onrampActionState.unavailabilityReason == ScenarioUnavailabilityReason.None) { + activeList.add(onrampActionState) } else { - actionsList.add( - TokenActionsState.ActionState.Buy( - ScenarioUnavailabilityReason.BuyUnavailable( - cryptoCurrencyName = cryptoCurrencyStatus.currency.name, - ), - ), - ) + disabledList.add(onrampActionState) } - actionsList.add(TokenActionsState.ActionState.Send(ScenarioUnavailabilityReason.Unreachable)) - actionsList.add( + + disabledList.add(TokenActionsState.ActionState.Send(ScenarioUnavailabilityReason.Unreachable)) + disabledList.add( TokenActionsState.ActionState.Swap( unavailabilityReason = ScenarioUnavailabilityReason.Unreachable, showBadge = false, ), ) - actionsList.add(TokenActionsState.ActionState.Sell(ScenarioUnavailabilityReason.Unreachable)) + disabledList.add(TokenActionsState.ActionState.Sell(ScenarioUnavailabilityReason.Unreachable)) if (isAddressAvailable(cryptoCurrencyStatus.value.networkAddress)) { val scenario = getReceiveScenario(requirements) - actionsList.add(TokenActionsState.ActionState.Receive(scenario)) + activeList.add(TokenActionsState.ActionState.Receive(scenario)) } - actionsList.add(TokenActionsState.ActionState.Stake(ScenarioUnavailabilityReason.Unreachable, null)) - actionsList.add(TokenActionsState.ActionState.HideToken(ScenarioUnavailabilityReason.None)) + disabledList.add(TokenActionsState.ActionState.Stake(ScenarioUnavailabilityReason.Unreachable, null)) + activeList.add(TokenActionsState.ActionState.HideToken(ScenarioUnavailabilityReason.None)) - return actionsList + return activeList + disabledList } @Suppress("LongMethod") @@ -313,17 +310,12 @@ class GetCryptoCurrencyActionsUseCase( disabledList.add(swapAction) } - // buy - if (rampManager.availableForBuy(userWallet.scanResponse, userWallet.walletId, cryptoCurrency)) { - activeList.add(TokenActionsState.ActionState.Buy(ScenarioUnavailabilityReason.None)) + // buy (is not depend on cache) + val onrampActionState = getOnrampUnavailabilityReason(userWallet, cryptoCurrencyStatus) + if (onrampActionState.unavailabilityReason == ScenarioUnavailabilityReason.None) { + activeList.add(onrampActionState) } else { - disabledList.add( - TokenActionsState.ActionState.Buy( - ScenarioUnavailabilityReason.BuyUnavailable( - cryptoCurrencyName = cryptoCurrencyStatus.currency.name, - ), - ), - ) + disabledList.add(onrampActionState) } // staking @@ -415,21 +407,7 @@ class GetCryptoCurrencyActionsUseCase( showBadge = false, ) } - val exchangeableState = withTimeoutOrNull(REQUEST_EXCHANGE_DATA_TIMEOUT) { - rampManager.availableForSwap(userWallet.walletId, cryptoCurrency) - } ?: ExchangeableState.Loading - val currencyName = cryptoCurrency.name - - val reason = when (exchangeableState) { - ExchangeableState.Exchangeable -> { - ScenarioUnavailabilityReason.None - } - ExchangeableState.AssetNotFound -> ScenarioUnavailabilityReason.AssetNotFound(currencyName) - ExchangeableState.Error -> ScenarioUnavailabilityReason.ExpressUnreachable(currencyName) - ExchangeableState.Loading -> ScenarioUnavailabilityReason.ExpressLoading(currencyName) - ExchangeableState.NotExchangeable -> ScenarioUnavailabilityReason.NotExchangeable(currencyName) - } - + val reason = rampManager.availableForSwap(userWallet.walletId, cryptoCurrency) val isShowBadge = reason == ScenarioUnavailabilityReason.None && shouldShowSwapStories TokenActionsState.ActionState.Swap( unavailabilityReason = reason, @@ -443,6 +421,15 @@ class GetCryptoCurrencyActionsUseCase( } } + private suspend fun getOnrampUnavailabilityReason( + userWallet: UserWallet, + cryptoCurrencyStatus: CryptoCurrencyStatus, + ): TokenActionsState.ActionState { + val cryptoCurrency = cryptoCurrencyStatus.currency + val reason = rampManager.availableForBuy(userWallet.scanResponse, userWallet.walletId, cryptoCurrency) + return TokenActionsState.ActionState.Buy(unavailabilityReason = reason) + } + private fun isAddressAvailable(networkAddress: NetworkAddress?): Boolean { return networkAddress != null && networkAddress.defaultAddress.value.isNotEmpty() } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt index f51e0f6df5..15c4a85353 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt @@ -20,6 +20,7 @@ import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.model.NetworkAddress +import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.analytics.TokenReceiveAnalyticsEvent import com.tangem.domain.wallets.builder.UserWalletBuilder import com.tangem.domain.wallets.models.UserWallet @@ -171,22 +172,18 @@ internal class OnboardingNoteTopUpModel @Inject constructor( _uiState.update { it.copy( amountToCreateAccount = amountToCreateAccount - ?.format( - { - crypto( - symbol = status.currency.symbol, - decimals = status.currency.decimals, - ) - }, - ), - balance = amount?.format( - { + ?.format { crypto( symbol = status.currency.symbol, decimals = status.currency.decimals, ) }, - ).orEmpty(), + balance = amount?.format { + crypto( + symbol = status.currency.symbol, + decimals = status.currency.decimals, + ) + }.orEmpty(), isTopUpDataLoading = status.value.networkAddress == null, ) } @@ -209,7 +206,7 @@ internal class OnboardingNoteTopUpModel @Inject constructor( ) _uiState.update { it.copy( - availableForBuy = availableForBuy, + availableForBuy = availableForBuy == ScenarioUnavailabilityReason.None, availableForBuyLoading = false, ) } diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt index 770e77d257..e2f4d63942 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt @@ -20,6 +20,7 @@ import com.tangem.domain.onramp.model.OnrampSource import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.features.onramp.impl.R @@ -79,13 +80,13 @@ internal class OnrampOperationModel @Inject constructor( fun onHotTokenClick(status: CryptoCurrencyStatus) { modelScope.launch { - val isAvailable = rampStateManager.availableForBuy( + val unavailabilityReason = rampStateManager.availableForBuy( scanResponse = selectedUserWallet.scanResponse, userWalletId = params.userWalletId, cryptoCurrency = status.currency, ) - if (isAvailable) { + if (unavailabilityReason == ScenarioUnavailabilityReason.None) { analyticsEventHandler.send( event = MainScreenAnalyticsEvent.HotTokenClicked(currencySymbol = status.currency.symbol), ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt index 666236c87f..ee6457f6af 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt @@ -11,13 +11,13 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.core.lce.Lce import com.tangem.domain.core.utils.getOrElse -import com.tangem.domain.exchange.ExchangeableState import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.tokens.GetTokenListUseCase 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.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.usecase.GetWalletsUseCase @@ -230,7 +230,7 @@ internal class OnrampTokenListModel @Inject constructor( scanResponse = scanResponse, userWalletId = params.userWalletId, cryptoCurrency = status.currency, - ) + ).isAvailable() } OnrampOperation.SELL -> { rampStateManager.availableForSell( @@ -242,21 +242,14 @@ internal class OnrampTokenListModel @Inject constructor( val isAvailable = rampStateManager.availableForSwap( userWalletId = params.userWalletId, cryptoCurrency = status.currency, - ).isSwapAvailable() && !status.currency.isCustom + ).isAvailable() && !status.currency.isCustom isAvailable && status.value !is CryptoCurrencyStatus.NoQuote } } } - private fun ExchangeableState.isSwapAvailable(): Boolean { - return when (this) { - ExchangeableState.AssetNotFound, - ExchangeableState.Error, - ExchangeableState.Loading, - ExchangeableState.NotExchangeable, - -> false - ExchangeableState.Exchangeable -> true - } + private fun ScenarioUnavailabilityReason.isAvailable(): Boolean { + return this == ScenarioUnavailabilityReason.None } } \ No newline at end of file