Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-21 20:02:42 +05:00
parent 1e6d95e494
commit f947c7d620
9 changed files with 40 additions and 4 deletions

View file

@ -6,9 +6,11 @@ import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.express.ExpressRepository
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.utils.extensions.filterIf
import timber.log.Timber
internal class DefaultExpressRepository(
@ -16,7 +18,10 @@ internal class DefaultExpressRepository(
private val appPreferencesStore: AppPreferencesStore,
) : ExpressRepository {
override suspend fun getProviders(userWallet: UserWallet): List<ExpressProvider> {
override suspend fun getProviders(
userWallet: UserWallet,
filterProviderTypes: List<ExpressProviderType>,
): List<ExpressProvider> {
return safeApiCall(
call = {
tangemExpressApi.getProviders(
@ -26,6 +31,7 @@ internal class DefaultExpressRepository(
appPreferencesStore = appPreferencesStore,
),
).getOrThrow().map(ExpressProviderConverter()::convert)
.filterIf(filterProviderTypes.isNotEmpty()) { it.type in filterProviderTypes }
},
onError = {
Timber.w(it, "Unable to fetch express providers")

View file

@ -58,6 +58,7 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
filterProviderTypes: List<ExpressProviderType>,
): List<SwapPairModel> = withContext(coroutineDispatcher.io) {
val cryptoCurrencyList = cryptoCurrencyStatusList.map { it.currency }
@ -67,7 +68,10 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
cryptoCurrencyList = cryptoCurrencyList,
)
val providers = expressRepository.getProviders(userWallet = userWallet)
val providers = expressRepository.getProviders(
userWallet = userWallet,
filterProviderTypes = filterProviderTypes,
)
val mappedProviders = providers.associateBy(ExpressProvider::providerId)
allPairs.map { pair ->

View file

@ -1,6 +1,7 @@
package com.tangem.domain.express
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.wallets.models.UserWallet
/**
@ -12,6 +13,10 @@ interface ExpressRepository {
* Returns list of express providers
*
* @param userWallet selected user wallet info
* @param filterProviderTypes filters only specified provider types, if empty returns providers as is
*/
suspend fun getProviders(userWallet: UserWallet): List<ExpressProvider>
suspend fun getProviders(
userWallet: UserWallet,
filterProviderTypes: List<ExpressProviderType>,
): List<ExpressProvider>
}

View file

@ -1,6 +1,7 @@
package com.tangem.domain.swap
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.express.models.ExpressRateType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.models.SwapDataModel
@ -23,11 +24,13 @@ interface SwapRepositoryV2 {
* @param userWallet selected user wallet
* @param initialCurrency currency being swapped (either to or from)
* @param cryptoCurrencyStatusList list of currencies might be swapped
* @param filterProviderTypes filters only specified provider types, if empty returns providers as is
*/
suspend fun getPairs(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
filterProviderTypes: List<ExpressProviderType>,
): List<SwapPairModel>
/** Express getPairs request variant without providers request */

View file

@ -1,6 +1,7 @@
package com.tangem.domain.swap.usecase
import arrow.core.Either
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.SwapErrorResolver
import com.tangem.domain.swap.SwapRepositoryV2
@ -23,16 +24,19 @@ class GetSwapPairsUseCase(
* @param userWallet selected user wallet
* @param initialCurrency initial currency to swap (to or from)
* @param cryptoCurrencyStatusList list of added cryptocurrencies
* @param filterProviderTypes filters only specified provider types, if empty returns providers as is
*/
suspend operator fun invoke(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
filterProviderTypes: List<ExpressProviderType>,
) = Either.catch {
val pairs = swapRepositoryV2.getPairs(
userWallet = userWallet,
initialCurrency = initialCurrency,
cryptoCurrencyStatusList = cryptoCurrencyStatusList,
filterProviderTypes = filterProviderTypes,
)
val fromGroup = pairs.groupPairs(

View file

@ -1,6 +1,7 @@
package com.tangem.features.swap.v2.impl.amount
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -18,6 +19,7 @@ internal sealed class SwapAmountComponentParams {
abstract val isBalanceHidingFlow: StateFlow<Boolean>
abstract val primaryCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>
abstract val secondaryCryptoCurrency: CryptoCurrency?
abstract val filterProviderTypes: List<ExpressProviderType>
data class AmountParams(
override val amountUM: SwapAmountUM,
@ -27,6 +29,7 @@ internal sealed class SwapAmountComponentParams {
override val swapDirection: SwapDirection,
override val primaryCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
override val secondaryCryptoCurrency: CryptoCurrency?,
override val filterProviderTypes: List<ExpressProviderType> = emptyList(),
val title: TextReference,
val callback: SwapAmountComponent.ModelCallback,
val currentRoute: Flow<SwapAmountRoute>,
@ -40,6 +43,7 @@ internal sealed class SwapAmountComponentParams {
override val swapDirection: SwapDirection,
override val primaryCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
override val secondaryCryptoCurrency: CryptoCurrency?,
override val filterProviderTypes: List<ExpressProviderType> = emptyList(),
val blockClickEnableFlow: StateFlow<Boolean>,
) : SwapAmountComponentParams()
}

View file

@ -281,6 +281,7 @@ internal class SwapAmountModel @Inject constructor(
userWallet = userWallet,
initialCurrency = primaryCryptoCurrency,
cryptoCurrencyStatusList = cryptoCurrencyStatusListExceptPrimary,
filterProviderTypes = params.filterProviderTypes,
).fold(
ifRight = { swapCurrencies ->
val secondaryStatus = selectInitialPairUseCase(

View file

@ -18,6 +18,7 @@ import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.decompose.getEmptyComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.swap.models.R
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.features.send.v2.api.subcomponents.destination.DestinationRoute
@ -125,6 +126,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
swapDirection = SwapDirection.Direct,
callback = model,
userWallet = model.userWallet,
filterProviderTypes = SEND_WITH_SWAP_PROVIDER_TYPES,
),
)
}
@ -199,4 +201,9 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
params: SendWithSwapComponent.Params,
): DefaultSendWithSwapComponent
}
companion object {
/** List of supported provider types in Send with Swap */
internal val SEND_WITH_SWAP_PROVIDER_TYPES = listOf(ExpressProviderType.CEX)
}
}

View file

@ -24,6 +24,7 @@ import com.tangem.features.swap.v2.impl.amount.SwapAmountComponentParams
import com.tangem.features.swap.v2.impl.common.entity.ConfirmUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import com.tangem.features.swap.v2.impl.notifications.SwapNotificationsComponent
import com.tangem.features.swap.v2.impl.sendviaswap.DefaultSendWithSwapComponent.Companion.SEND_WITH_SWAP_PROVIDER_TYPES
import com.tangem.features.swap.v2.impl.sendviaswap.SendWithSwapRoute
import com.tangem.features.swap.v2.impl.sendviaswap.confirm.model.SendWithSwapConfirmModel
import com.tangem.features.swap.v2.impl.sendviaswap.confirm.ui.SendWithSwapConfirmContent
@ -57,6 +58,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
secondaryCryptoCurrency = model.secondaryCurrency,
isBalanceHidingFlow = params.isBalanceHidingFlow,
swapDirection = params.swapDirection,
filterProviderTypes = SEND_WITH_SWAP_PROVIDER_TYPES,
),
onResult = model::onAmountResult,
onClick = model::showEditAmount,