Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-16 19:31:35 +03:00
parent 9cfd045c7b
commit 02d7e5df0b
15 changed files with 80 additions and 173 deletions

View file

@ -13,26 +13,6 @@ class CardExchangeRules(
val cardProvider: () -> CardDTO?,
) : ExchangeRules {
override fun isBuyAllowed(): Boolean {
val card = cardProvider() ?: return false
return when {
card.isDemoCard() -> true
card.isStart2Coin -> false
else -> true
}
}
override fun isSellAllowed(): Boolean {
val card = cardProvider() ?: return false
return when {
card.isDemoCard() -> false
card.isStart2Coin -> false
else -> true
}
}
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean {
val card = scanResponse.card
@ -46,10 +26,6 @@ class CardExchangeRules(
override fun availableForSell(currency: Currency): Boolean {
val card = cardProvider() ?: return false
return when {
card.isDemoCard() -> false
card.isStart2Coin -> false
else -> true
}
return !card.isStart2Coin
}
}

View file

@ -52,9 +52,6 @@ class CurrencyExchangeManager(
_initializationStatus.value = lceContent()
}
override fun isBuyAllowed(): Boolean = primaryRules.isBuyAllowed() && buyService.isBuyAllowed()
override fun isSellAllowed(): Boolean = primaryRules.isSellAllowed() && sellService.isSellAllowed()
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean {
return primaryRules.availableForBuy(scanResponse, currency) &&
buyService.availableForBuy(scanResponse, currency)

View file

@ -1,5 +1,10 @@
package com.tangem.tap.network.exchangeServices
import arrow.core.Either
import arrow.core.raise.catch
import arrow.core.raise.either
import arrow.core.raise.ensure
import arrow.core.right
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
@ -37,16 +42,6 @@ internal class DefaultRampManager(
private val cryptoCurrencyConverter = CryptoCurrencyConverter(excludedBlockchains)
override fun isSellSupportedByService(cryptoCurrency: CryptoCurrency): Boolean {
return runCatching {
exchangeService?.availableForSell(
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
)
}
.getOrNull()
?: false
}
override suspend fun availableForBuy(
scanResponse: ScanResponse,
userWalletId: UserWalletId,
@ -66,18 +61,40 @@ internal class DefaultRampManager(
?: false
}
override suspend fun availableForSell(userWalletId: UserWalletId, status: CryptoCurrencyStatus): Boolean {
return runCatching {
val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
override suspend fun availableForSell(
userWalletId: UserWalletId,
status: CryptoCurrencyStatus,
): Either<ScenarioUnavailabilityReason, Unit> {
return either {
val sellSupportedByService = catch(
block = {
val serviceCurrency = cryptoCurrencyConverter.convertBack(status.currency)
if (!sellSupportedByService) return false
exchangeService?.availableForSell(currency = serviceCurrency) ?: false
},
catch = { raise(ScenarioUnavailabilityReason.NotSupportedBySellService(status.currency.name)) },
)
ensure(condition = sellSupportedByService) {
ScenarioUnavailabilityReason.NotSupportedBySellService(status.currency.name)
}
val reason = getSendUnavailabilityReason(userWalletId, status)
reason == ScenarioUnavailabilityReason.None
ensure(condition = reason is ScenarioUnavailabilityReason.None) {
when (reason) {
is ScenarioUnavailabilityReason.EmptyBalance -> {
reason.copy(withdrawalScenario = ScenarioUnavailabilityReason.WithdrawalScenario.SELL)
}
is ScenarioUnavailabilityReason.PendingTransaction -> {
reason.copy(withdrawalScenario = ScenarioUnavailabilityReason.WithdrawalScenario.SELL)
}
else -> reason
}
}
Unit.right()
}
.getOrNull()
?: false
}
override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {

View file

@ -11,8 +11,6 @@ import kotlinx.coroutines.flow.StateFlow
typealias ExchangeServiceInitializationStatus = Lce<Throwable, Any>
interface Exchanger {
fun isBuyAllowed(): Boolean
fun isSellAllowed(): Boolean
fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean
fun availableForSell(currency: Currency): Boolean
}
@ -30,8 +28,6 @@ interface ExchangeService : Exchanger, ExchangeUrlBuilder {
MutableStateFlow(value = lceLoading())
override suspend fun update() {}
override fun isBuyAllowed(): Boolean = false
override fun isSellAllowed(): Boolean = false
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean = false
override fun availableForSell(currency: Currency): Boolean = false
override fun getUrl(
@ -54,8 +50,6 @@ interface ExchangeRules : Exchanger {
companion object {
fun dummy(): ExchangeRules = object : ExchangeRules {
override fun isBuyAllowed(): Boolean = false
override fun isSellAllowed(): Boolean = false
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean = false
override fun availableForSell(currency: Currency): Boolean = false
}

View file

@ -54,13 +54,7 @@ internal class MercuryoService(private val environment: MercuryoEnvironment) : E
}
}
override fun isBuyAllowed(): Boolean = true
override fun isSellAllowed(): Boolean = false
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean {
if (!isBuyAllowed()) return false
val mercuryoNetwork = currency.blockchain.mercuryoNetwork
val contractAddress = (currency as? Currency.Token)?.token?.contractAddress ?: ""
val availableCurrency = availableMercuryoCurrencies.firstOrNull {

View file

@ -102,12 +102,6 @@ class MoonPayService(
}
}
override fun isBuyAllowed(): Boolean = false
override fun isSellAllowed(): Boolean {
return status?.responseUserStatus?.isSellAllowed ?: false
}
override fun availableForBuy(scanResponse: ScanResponse, currency: Currency): Boolean = false
override fun availableForSell(currency: Currency): Boolean {
@ -187,6 +181,10 @@ class MoonPayService(
return Base64.encodeToString(sha256encoded, Base64.NO_WRAP)
}
private fun isSellAllowed(): Boolean {
return status?.responseUserStatus?.isSellAllowed ?: false
}
companion object {
const val URL_SELL = "sell.moonpay.com"
}