Updated on 2026-08-14
This commit is contained in:
parent
ede97572e3
commit
4c720113f9
11 changed files with 95 additions and 20 deletions
|
|
@ -484,4 +484,10 @@ internal object TokensDomainModule {
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetAssetRequirementsUseCase(walletManagersFacade: WalletManagersFacade): GetAssetRequirementsUseCase {
|
||||
return GetAssetRequirementsUseCase(walletManagersFacade)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.domain.tokens
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.transaction.models.AssetRequirementsCondition
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
||||
class GetAssetRequirementsUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
): Either<Throwable, AssetRequirementsCondition?> {
|
||||
return Either.Companion.catch {
|
||||
walletManagersFacade.getAssetRequirements(userWalletId, currency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,15 +56,24 @@ internal open class BaseActionsFactory(
|
|||
*
|
||||
* @param userWallet the user's cold wallet
|
||||
* @param currency the cryptocurrency to check
|
||||
* @param requirementsDeferred a deferred object containing the asset requirements condition
|
||||
*/
|
||||
protected suspend fun getOnrampUnavailabilityReason(
|
||||
userWallet: UserWallet,
|
||||
currency: CryptoCurrency,
|
||||
requirementsDeferred: Deferred<AssetRequirementsCondition?>?,
|
||||
): ScenarioUnavailabilityReason {
|
||||
return rampStateManager.availableForBuy(
|
||||
val onrampUnavailabilityReason = rampStateManager.availableForBuy(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = currency,
|
||||
)
|
||||
val shouldCheckAssetRequirements =
|
||||
onrampUnavailabilityReason == ScenarioUnavailabilityReason.None && requirementsDeferred != null
|
||||
return if (shouldCheckAssetRequirements) {
|
||||
getReceiveScenario(requirementsDeferred.await())
|
||||
} else {
|
||||
onrampUnavailabilityReason
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,7 +52,11 @@ internal class CommonActionsFactory(
|
|||
}
|
||||
|
||||
val onrampUnavailabilityReasonDeferred = async {
|
||||
getOnrampUnavailabilityReason(userWallet = userWallet, currency = cryptoCurrencyStatus.currency)
|
||||
getOnrampUnavailabilityReason(
|
||||
userWallet = userWallet,
|
||||
currency = cryptoCurrencyStatus.currency,
|
||||
requirementsDeferred = requirementsDeferred,
|
||||
)
|
||||
}
|
||||
|
||||
val sendUnavailabilityReasonDeferred = async {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ package com.tangem.domain.tokens.actions
|
|||
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||
import com.tangem.domain.tokens.model.TokenActionsState.ActionState
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
|
@ -50,7 +50,11 @@ internal class OutdatedDataActionsFactory(
|
|||
}
|
||||
|
||||
val onrampUnavailabilityReasonDeferred = async {
|
||||
getOnrampUnavailabilityReason(userWallet = userWallet, currency = cryptoCurrencyStatus.currency)
|
||||
getOnrampUnavailabilityReason(
|
||||
userWallet = userWallet,
|
||||
currency = cryptoCurrencyStatus.currency,
|
||||
requirementsDeferred = requirementsDeferred,
|
||||
)
|
||||
}
|
||||
|
||||
val sendUnavailabilityReasonDeferred = if (sources.networkSource == StatusSource.ACTUAL) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.domain.tokens.actions
|
||||
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||
import com.tangem.domain.tokens.model.TokenActionsState.ActionState
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
||||
|
|
@ -36,7 +36,11 @@ internal class UnreachableActionsFactory(
|
|||
}
|
||||
|
||||
val onrampUnavailabilityReasonDeferred = async {
|
||||
getOnrampUnavailabilityReason(userWallet = userWallet, currency = cryptoCurrencyStatus.currency)
|
||||
getOnrampUnavailabilityReason(
|
||||
userWallet = userWallet,
|
||||
currency = cryptoCurrencyStatus.currency,
|
||||
requirementsDeferred = requirementsDeferred,
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ dependencies {
|
|||
implementation(projects.domain.wallets)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.settings)
|
||||
implementation(projects.domain.transaction.models)
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ import com.tangem.domain.models.TotalFiatBalance
|
|||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
|
||||
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.transaction.models.AssetRequirementsCondition
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
|
|
@ -54,6 +56,7 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val getUserCountryUseCase: GetUserCountryUseCase,
|
||||
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<TokenListUM> = tokenListUMController.state
|
||||
|
|
@ -206,17 +209,28 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
return coroutineScope {
|
||||
map { status ->
|
||||
async {
|
||||
val isAvailable = checkAvailabilityByOperation(status = status)
|
||||
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 isNotUnreachable = when (params.filterOperation) {
|
||||
OnrampOperation.BUY -> true // unreachable state is available for Buy operation
|
||||
OnrampOperation.SELL -> status.value !is CryptoCurrencyStatus.Unreachable
|
||||
OnrampOperation.SWAP -> status.value !is CryptoCurrencyStatus.Unreachable
|
||||
val isNotTrustlineRequired = requirements !is AssetRequirementsCondition.RequiredTrustline
|
||||
val isNotUnreachable = status.value !is CryptoCurrencyStatus.Unreachable
|
||||
|
||||
val isAvailable = when (params.filterOperation) {
|
||||
OnrampOperation.BUY -> {
|
||||
isNotTrustlineRequired
|
||||
} // unreachable state is available for Buy operation
|
||||
OnrampOperation.SELL -> isNotUnreachable
|
||||
OnrampOperation.SWAP -> {
|
||||
isNotUnreachable && isNotTrustlineRequired
|
||||
}
|
||||
}
|
||||
|
||||
status to (isAvailable && isNotMissedDerivation && isNotLoading && isNotUnreachable)
|
||||
status to (isOperationAvailable && isNotMissedDerivation && isNotLoading && isAvailable)
|
||||
}
|
||||
}
|
||||
.awaitAll()
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ dependencies {
|
|||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.wallets)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.transaction.models)
|
||||
|
||||
/** Data */
|
||||
implementation(projects.data.common)
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import com.tangem.datasource.crypto.DataSignatureVerifier
|
|||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
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.*
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.ExpressDataError
|
||||
|
|
@ -134,7 +135,12 @@ internal class DefaultSwapRepository(
|
|||
contractAddress = initialCurrency.contractAddress,
|
||||
network = initialCurrency.network,
|
||||
)
|
||||
val currenciesList = currencyList.map { leastTokenInfoConverter.convert(it) }
|
||||
val currenciesList = currencyList
|
||||
.filter {
|
||||
val requirements = walletManagersFacade.getAssetRequirements(userWallet.walletId, it)
|
||||
requirements !is AssetRequirementsCondition.RequiredTrustline
|
||||
}
|
||||
.map { leastTokenInfoConverter.convert(it) }
|
||||
|
||||
val pairsDeferred = async {
|
||||
getPairsInternal(
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import com.tangem.domain.demo.IsDemoCardUseCase
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.quotes.QuotesRepository
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
||||
import com.tangem.domain.tokens.*
|
||||
|
|
@ -29,10 +31,9 @@ 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.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.ExpressDataError
|
||||
|
|
@ -79,6 +80,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
private val getEthSpecificFeeUseCase: GetEthSpecificFeeUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
|
||||
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
|
||||
private val amountFormatter: AmountFormatter,
|
||||
@Assisted private val userWalletId: UserWalletId,
|
||||
) : SwapInteractor {
|
||||
|
|
@ -139,7 +141,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getToCurrenciesGroup(
|
||||
private suspend fun getToCurrenciesGroup(
|
||||
currency: CryptoCurrency,
|
||||
leastPairs: List<SwapPairLeast>,
|
||||
cryptoCurrenciesList: List<CryptoCurrencyStatus>,
|
||||
|
|
@ -171,15 +173,18 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun findProvidersForPair(
|
||||
private suspend fun findProvidersForPair(
|
||||
cryptoCurrencyStatuses: CryptoCurrencyStatus,
|
||||
swapPairsLeastList: List<SwapPairLeast>,
|
||||
tokenInfoForAvailable: (SwapPairLeast) -> LeastTokenInfo,
|
||||
): List<SwapProvider>? {
|
||||
val requirements = getAssetRequirementsUseCase.invoke(userWalletId, cryptoCurrencyStatuses.currency).getOrNull()
|
||||
|
||||
return swapPairsLeastList.firstNotNullOfOrNull {
|
||||
val listTokenInfo = tokenInfoForAvailable(it)
|
||||
if (cryptoCurrencyStatuses.currency.network.backendId == listTokenInfo.network &&
|
||||
cryptoCurrencyStatuses.currency.getContractAddress() == listTokenInfo.contractAddress
|
||||
cryptoCurrencyStatuses.currency.getContractAddress() == listTokenInfo.contractAddress &&
|
||||
requirements !is AssetRequirementsCondition.RequiredTrustline
|
||||
) {
|
||||
it.providers
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue