Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-18 18:38:24 +05:00
parent 6f64d550cb
commit a692abaffb
11 changed files with 475 additions and 2 deletions

View file

@ -0,0 +1,20 @@
package com.tangem.domain.swap.models
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
data class SwapCurrencies(
val fromGroup: SwapCurrenciesGroup,
val toGroup: SwapCurrenciesGroup,
)
data class SwapCurrenciesGroup(
val available: List<SwapCryptoCurrency>,
val unavailable: List<SwapCryptoCurrency>,
val afterSearch: Boolean,
)
data class SwapCryptoCurrency(
val currencyStatus: CryptoCurrencyStatus,
val providers: List<ExpressProvider>,
)

View file

@ -0,0 +1,17 @@
package com.tangem.domain.swap.models
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
/**
* Domain layer representation of SwapPair data network model.
*
* @property from Short information about the token we want to change
* @property to Short information about the token we want to exchange for
* @property providers Exchange providers
*/
data class SwapPairModel(
val from: CryptoCurrencyStatus,
val to: CryptoCurrencyStatus,
val providers: List<ExpressProvider>,
)

View file

@ -0,0 +1,6 @@
package com.tangem.domain.swap.models
data class TokenInfo(
val contractAddress: String,
val network: String,
)

View file

@ -0,0 +1,7 @@
package com.tangem.domain.swap
import com.tangem.domain.express.models.ExpressError
interface SwapErrorResolver {
fun resolve(throwable: Throwable): ExpressError
}

View file

@ -0,0 +1,29 @@
package com.tangem.domain.swap
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.models.SwapPairModel
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
interface SwapRepositoryV2 {
/**
* Express swap pairs, both direct and reversed
*
* @param userWallet selected user wallet
* @param initialCurrency currency being swapped (either to or from)
* @param cryptoCurrencyStatusList list of currencies might be swapped
*/
suspend fun getPairs(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
): List<SwapPairModel>
/** Express getPairs request variant without providers request */
suspend fun getPairsOnly(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyList: List<CryptoCurrency>,
): List<SwapPairModel>
}

View file

@ -0,0 +1,85 @@
package com.tangem.domain.swap.usecase
import arrow.core.Either
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.SwapErrorResolver
import com.tangem.domain.swap.SwapRepositoryV2
import com.tangem.domain.swap.models.SwapCryptoCurrency
import com.tangem.domain.swap.models.SwapCurrencies
import com.tangem.domain.swap.models.SwapCurrenciesGroup
import com.tangem.domain.swap.models.SwapPairModel
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
/**
* Returns pais
*/
class GetSwapSupportedPairsUseCase(
private val swapRepositoryV2: SwapRepositoryV2,
private val swapErrorResolver: SwapErrorResolver,
) {
suspend operator fun invoke(
userWallet: UserWallet,
initialCurrency: CryptoCurrency,
cryptoCurrencyList: List<CryptoCurrency>,
) = Either.catch {
val pairs = swapRepositoryV2.getPairsOnly(
userWallet = userWallet,
initialCurrency = initialCurrency,
cryptoCurrencyList = cryptoCurrencyList,
)
val filteredOutInitial = cryptoCurrencyList.filterNot { it.id == initialCurrency.id }
val fromGroup = pairs.groupPairs(
initialCurrency = initialCurrency,
filteringCurrency = { it.from },
groupingCurrency = { it.to },
cryptoCurrencyList = filteredOutInitial,
)
val toGroup = pairs.groupPairs(
initialCurrency = initialCurrency,
filteringCurrency = { it.to },
groupingCurrency = { it.from },
cryptoCurrencyList = filteredOutInitial,
)
SwapCurrencies(
fromGroup = fromGroup,
toGroup = toGroup,
)
}.mapLeft(swapErrorResolver::resolve)
private fun List<SwapPairModel>.groupPairs(
initialCurrency: CryptoCurrency,
filteringCurrency: (SwapPairModel) -> CryptoCurrencyStatus,
groupingCurrency: (SwapPairModel) -> CryptoCurrencyStatus,
cryptoCurrencyList: List<CryptoCurrency>,
): SwapCurrenciesGroup {
val availableCryptoCurrencies = filter { pair -> filteringCurrency(pair).currency.id == initialCurrency.id }
// Search available to swap currency
.filter { pair ->
cryptoCurrencyList.any { currencyStatus ->
currencyStatus.id == pair.to.currency.id
}
}.map { pair -> SwapCryptoCurrency(groupingCurrency(pair), pair.providers) }
val unavailableCryptoCurrencies =
cryptoCurrencyList - availableCryptoCurrencies.map { it.currencyStatus.currency }.toSet()
return SwapCurrenciesGroup(
available = availableCryptoCurrencies,
unavailable = unavailableCryptoCurrencies.map { currency ->
SwapCryptoCurrency(
CryptoCurrencyStatus(
currency = currency,
value = CryptoCurrencyStatus.Loading, // todo select token unavailable
),
emptyList(),
)
},
afterSearch = false,
)
}
}