Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-25 17:57:22 +04:00
parent 7d017162cb
commit 642ae56dc7
7 changed files with 98 additions and 20 deletions

View file

@ -4,8 +4,10 @@ import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
@ -45,6 +47,8 @@ internal object ActivityModule {
fun provideDefaultRampManager(
appStateHolder: AppStateHolder,
swapServiceLoader: SwapServiceLoader,
currenciesRepository: CurrenciesRepository,
getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
dispatchers: CoroutineDispatcherProvider,
): RampStateManager {
return DefaultRampManager(
@ -52,6 +56,8 @@ internal object ActivityModule {
buyService = Provider { requireNotNull(appStateHolder.buyService) },
sellService = Provider { requireNotNull(appStateHolder.sellService) },
swapServiceLoader = swapServiceLoader,
currenciesRepository = currenciesRepository,
getNetworkCoinStatusUseCase = getNetworkCoinStatusUseCase,
dispatchers = dispatchers,
)
}

View file

@ -4,23 +4,37 @@ import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRA
import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.isNullOrZero
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
@Suppress("LongParameterList")
internal class DefaultRampManager(
private val exchangeService: ExchangeService?,
private val buyService: Provider<ExchangeService>,
private val sellService: Provider<ExchangeService>,
private val swapServiceLoader: SwapServiceLoader,
private val currenciesRepository: CurrenciesRepository,
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
private val dispatchers: CoroutineDispatcherProvider,
) : RampStateManager {
private val cryptoCurrencyConverter = CryptoCurrencyConverter()
override fun isSellSupportedByService(cryptoCurrency: CryptoCurrency): Boolean {
return exchangeService?.availableForSell(
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
) ?: false
}
override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
return exchangeService?.availableForBuy(
scanResponse = scanResponse,
@ -28,10 +42,14 @@ internal class DefaultRampManager(
) ?: false
}
override fun availableForSell(cryptoCurrency: CryptoCurrency): Boolean {
return exchangeService?.availableForSell(
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
) ?: false
override suspend fun availableForSell(userWalletId: UserWalletId, status: CryptoCurrencyStatus): Boolean {
val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
if (!sellSupportedByService) return false
val reason = getSendUnavailabilityReason(userWalletId, status)
return reason == ScenarioUnavailabilityReason.None
}
override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
@ -75,4 +93,34 @@ internal class DefaultRampManager(
asset?.exchangeAvailable ?: false
}
}
private suspend fun getSendUnavailabilityReason(
userWalletId: UserWalletId,
cryptoCurrencyStatus: CryptoCurrencyStatus,
): ScenarioUnavailabilityReason {
val coinStatus = getNetworkCoinStatusUseCase.invokeSync(
userWalletId = userWalletId,
networkId = cryptoCurrencyStatus.currency.network.id,
derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
isSingleWalletWithTokens = false,
).getOrNull()
return when {
cryptoCurrencyStatus.value.amount.isNullOrZero() -> {
ScenarioUnavailabilityReason.EmptyBalance(ScenarioUnavailabilityReason.WithdrawalScenario.SEND)
}
currenciesRepository.isSendBlockedByPendingTransactions(
cryptoCurrencyStatus = cryptoCurrencyStatus,
coinStatus = coinStatus,
) -> {
ScenarioUnavailabilityReason.PendingTransaction(
withdrawalScenario = ScenarioUnavailabilityReason.WithdrawalScenario.SEND,
networkName = coinStatus?.currency?.network?.name.orEmpty(),
)
}
else -> {
ScenarioUnavailabilityReason.None
}
}
}
}