Updated on 2026-08-14
This commit is contained in:
parent
e87d946e40
commit
a3a18854c8
48 changed files with 544 additions and 328 deletions
|
|
@ -4,10 +4,12 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
|||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.onramp.model.OnrampCountry
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface ConfirmResidencyComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val country: OnrampCountry,
|
||||
val onDismiss: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ internal class DefaultConfirmResidencyComponent @AssistedInject constructor(
|
|||
is ConfirmResidencyBottomSheetConfig.SelectCountry -> selectCountryComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCountryComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = { isCountrySelected ->
|
||||
// Dismiss country select sheet
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ internal class DefaultOnrampMainComponent @AssistedInject constructor(
|
|||
is OnrampMainBottomSheetConfig.ConfirmResidency -> confirmResidencyComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = ConfirmResidencyComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
country = config.country,
|
||||
onDismiss = {
|
||||
|
|
@ -65,6 +66,7 @@ internal class DefaultOnrampMainComponent @AssistedInject constructor(
|
|||
is OnrampMainBottomSheetConfig.CurrenciesList -> selectCurrencyComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCurrencyComponent.Params(
|
||||
userWallet = model.userWallet,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
) : Model(), OnrampIntents {
|
||||
|
||||
private val params: OnrampMainComponent.Params = paramsContainer.require()
|
||||
|
||||
val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
private val stateFactory = OnrampStateFactory(
|
||||
currentStateProvider = Provider { _state.value },
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
|
|
@ -68,7 +71,6 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
onrampIntents = this,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
)
|
||||
private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
private val _state: MutableStateFlow<OnrampMainComponentUM> = MutableStateFlow(
|
||||
value = stateFactory.getInitialState(
|
||||
currency = params.cryptoCurrency.name,
|
||||
|
|
@ -107,7 +109,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
|
||||
private fun checkResidenceCountry() {
|
||||
modelScope.launch {
|
||||
checkOnrampAvailabilityUseCase()
|
||||
checkOnrampAvailabilityUseCase(userWallet)
|
||||
.onRight(::handleOnrampAvailability)
|
||||
.onLeft(::handleOnrampError)
|
||||
}
|
||||
|
|
@ -158,7 +160,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
if (!state?.amountBlockState?.amountFieldModel?.fiatValue.isNullOrEmpty()) {
|
||||
_state.update { amountStateFactory.getAmountSecondaryLoadingState() }
|
||||
}
|
||||
fetchPairsUseCase.invoke(params.cryptoCurrency).fold(
|
||||
fetchPairsUseCase.invoke(userWallet, params.cryptoCurrency).fold(
|
||||
ifLeft = ::handleOnrampError,
|
||||
ifRight = { _state.update { amountStateFactory.getAmountSecondaryResetState() } },
|
||||
)
|
||||
|
|
@ -184,6 +186,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
val content = state.value as? OnrampMainComponentUM.Content ?: return@runCatching
|
||||
if (content.amountBlockState.amountFieldModel.fiatAmount.value.isNullOrZero()) return@runCatching
|
||||
fetchQuotesUseCase.invoke(
|
||||
userWallet = userWallet,
|
||||
amount = content.amountBlockState.amountFieldModel.fiatAmount,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
).onLeft(::handleOnrampError)
|
||||
|
|
@ -216,7 +219,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onBuyClick(quote: OnrampProviderWithQuote.Data) {
|
||||
if (isDemoCardUseCase.invoke(selectedUserWallet.cardId)) {
|
||||
if (isDemoCardUseCase.invoke(userWallet.cardId)) {
|
||||
showDemoWarning()
|
||||
} else {
|
||||
val currentContentState = state.value as? OnrampMainComponentUM.Content ?: return
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.core.ui.extensions.wrappedList
|
|||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.onramp.GetOnrampRedirectUrlUseCase
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.redirect.OnrampRedirectComponent
|
||||
import com.tangem.features.onramp.redirect.entity.OnrampRedirectTopBarUM
|
||||
|
|
@ -29,6 +30,7 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val getOnrampRedirectUrlUseCase: GetOnrampRedirectUrlUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
router: Router,
|
||||
|
|
@ -36,6 +38,8 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
) : Model() {
|
||||
|
||||
private val params: OnrampRedirectComponent.Params = paramsContainer.require()
|
||||
private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
val state = OnrampRedirectUM(
|
||||
topBarConfig = OnrampRedirectTopBarUM(
|
||||
title = combinedReference(
|
||||
|
|
@ -62,7 +66,7 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
fun getRedirectUrl(isDarkTheme: Boolean) {
|
||||
modelScope.launch {
|
||||
getOnrampRedirectUrlUseCase.invoke(
|
||||
userWalletId = params.userWalletId,
|
||||
userWallet = selectedUserWallet,
|
||||
quote = params.onrampProviderWithQuote,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
isDarkTheme = isDarkTheme,
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ internal class DefaultOnrampComponent @AssistedInject constructor(
|
|||
OnrampChild.Settings -> settingsComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = OnrampSettingsComponent.Params(
|
||||
params.cryptoCurrency,
|
||||
navigation::pop,
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onBack = navigation::pop,
|
||||
),
|
||||
)
|
||||
OnrampChild.Main -> onrampMainComponentFactory.create(
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.selectcountry
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface SelectCountryComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onDismiss: (Boolean) -> Unit)
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onDismiss: (Boolean) -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, SelectCountryComponent>
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import com.tangem.domain.onramp.GetOnrampCountryUseCase
|
|||
import com.tangem.domain.onramp.OnrampSaveDefaultCountryUseCase
|
||||
import com.tangem.domain.onramp.analytics.OnrampAnalyticsEvent
|
||||
import com.tangem.domain.onramp.model.OnrampCountry
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selectcountry.SelectCountryComponent
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
|
||||
|
|
@ -44,11 +45,15 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
private val saveDefaultCountryUseCase: OnrampSaveDefaultCountryUseCase,
|
||||
private val getOnrampCountryUseCase: GetOnrampCountryUseCase,
|
||||
private val fetchOnrampCountriesUseCase: FetchOnrampCountriesUseCase,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<CountryListUM> get() = controller.state
|
||||
private val params: SelectCountryComponent.Params = paramsContainer.require()
|
||||
private val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
val state: StateFlow<CountryListUM> get() = controller.state
|
||||
|
||||
private val controller = CountryListUMController(
|
||||
searchBarUM = createSearchBarUM(),
|
||||
loadingItems = loadingItems,
|
||||
|
|
@ -103,7 +108,7 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
|
||||
private fun updateCountriesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCountriesUseCase().onLeft {
|
||||
fetchOnrampCountriesUseCase(userWallet).onLeft {
|
||||
controller.update(UpdateCountryItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.selectcurrency
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
||||
internal interface SelectCurrencyComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onDismiss: () -> Unit)
|
||||
data class Params(
|
||||
val userWallet: UserWallet,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, SelectCurrencyComponent>
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ internal class OnrampSelectCurrencyModel @Inject constructor(
|
|||
|
||||
private fun updateCurrenciesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCurrenciesUseCase().onLeft {
|
||||
fetchOnrampCurrenciesUseCase(userWallet = params.userWallet).onLeft {
|
||||
controller.update(UpdateCurrencyItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ internal class DefaultOnrampSettingsComponent @AssistedInject constructor(
|
|||
OnrampSettingsConfig.SelectCountry -> selectCountryComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCountryComponent.Params(
|
||||
params.cryptoCurrency,
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = { model.bottomSheetNavigation.dismiss() },
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.settings
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface OnrampSettingsComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onBack: () -> Unit)
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onBack: () -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, OnrampSettingsComponent>
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
getOnrampStatusUseCase(txId = transaction.txId)
|
||||
getOnrampStatusUseCase(userWallet = userWallet, txId = transaction.txId)
|
||||
.fold(
|
||||
ifLeft = { error ->
|
||||
analyticsEventHandler.sendOnrampErrorEvent(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.domain.tokens.GetTokenListUseCase
|
|||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
||||
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast
|
||||
|
|
@ -52,11 +53,13 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getAvailablePairsUseCase: GetAvailablePairsUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<TokenListUM> = tokenListUMController.state
|
||||
|
||||
private var params: AvailableSwapPairsComponent.Params = paramsContainer.require()
|
||||
private val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
private val tokenListFlow = getTokenListUseCaseFlow()
|
||||
|
||||
|
|
@ -212,6 +215,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
availablePairsByNetworkFlow.update(networkInfo = networkInfo, state = lceLoading())
|
||||
|
||||
getAvailablePairsUseCase(
|
||||
userWallet = userWallet,
|
||||
initialCurrency = networkInfo,
|
||||
currencies = statuses.map(CryptoCurrencyStatus::currency),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@ import com.tangem.datasource.api.express.models.response.SwapPair
|
|||
import com.tangem.datasource.api.express.models.response.SwapPairsWithProviders
|
||||
import com.tangem.datasource.api.express.models.response.TxDetails
|
||||
import com.tangem.datasource.crypto.DataSignatureVerifier
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.converters.*
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
|
|
@ -48,6 +51,7 @@ internal class DefaultSwapRepository(
|
|||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val errorsDataConverter: ErrorsDataConverter,
|
||||
private val dataSignatureVerifier: DataSignatureVerifier,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
moshi: Moshi,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
) : SwapRepository {
|
||||
|
|
@ -60,6 +64,7 @@ internal class DefaultSwapRepository(
|
|||
private val txDetailsMoshiAdapter = moshi.adapter(TxDetails::class.java)
|
||||
|
||||
override suspend fun getPairs(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currencyList: List<CryptoCurrency>,
|
||||
): PairsWithProviders {
|
||||
|
|
@ -73,6 +78,7 @@ internal class DefaultSwapRepository(
|
|||
|
||||
val pairsDeferred = async {
|
||||
getPairsInternal(
|
||||
userWallet = userWallet,
|
||||
from = arrayListOf(initial),
|
||||
to = currenciesList,
|
||||
)
|
||||
|
|
@ -80,6 +86,7 @@ internal class DefaultSwapRepository(
|
|||
|
||||
val reversedPairsDeferred = async {
|
||||
getPairsInternal(
|
||||
userWallet = userWallet,
|
||||
from = currenciesList,
|
||||
to = arrayListOf(initial),
|
||||
)
|
||||
|
|
@ -90,7 +97,13 @@ internal class DefaultSwapRepository(
|
|||
|
||||
val allPairs = pairs + reversedPairs
|
||||
|
||||
val providers = tangemExpressApi.getProviders().getOrThrow()
|
||||
val providers = tangemExpressApi.getProviders(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).getOrThrow()
|
||||
|
||||
return@withContext swapPairInfoConverter.convert(
|
||||
SwapPairsWithProviders(
|
||||
|
|
@ -109,6 +122,7 @@ internal class DefaultSwapRepository(
|
|||
}
|
||||
|
||||
override suspend fun getPairsOnly(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currencyList: List<CryptoCurrency>,
|
||||
): PairsWithProviders {
|
||||
|
|
@ -122,6 +136,7 @@ internal class DefaultSwapRepository(
|
|||
|
||||
val pairsDeferred = async {
|
||||
getPairsInternal(
|
||||
userWallet = userWallet,
|
||||
from = arrayListOf(initial),
|
||||
to = currenciesList,
|
||||
)
|
||||
|
|
@ -129,6 +144,7 @@ internal class DefaultSwapRepository(
|
|||
|
||||
val reversedPairsDeferred = async {
|
||||
getPairsInternal(
|
||||
userWallet = userWallet,
|
||||
from = currenciesList,
|
||||
to = arrayListOf(initial),
|
||||
)
|
||||
|
|
@ -156,25 +172,42 @@ internal class DefaultSwapRepository(
|
|||
}
|
||||
|
||||
private suspend fun getPairsInternal(
|
||||
userWallet: UserWallet,
|
||||
from: List<NetworkLeastTokenInfo>,
|
||||
to: List<NetworkLeastTokenInfo>,
|
||||
): ApiResponse<List<SwapPair>> {
|
||||
return tangemExpressApi.getPairs(
|
||||
PairsRequestBody(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
body = PairsRequestBody(
|
||||
from = from,
|
||||
to = to,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getExchangeStatus(txId: String): Either<UnknownError, ExchangeStatusModel> {
|
||||
override suspend fun getExchangeStatus(
|
||||
userWallet: UserWallet,
|
||||
txId: String,
|
||||
): Either<UnknownError,
|
||||
ExchangeStatusModel,> {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
either {
|
||||
catch(
|
||||
block = {
|
||||
exchangeStatusConverter.convert(
|
||||
tangemExpressApi
|
||||
.getExchangeStatus(txId)
|
||||
.getExchangeStatus(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
txId = txId,
|
||||
)
|
||||
.getOrThrow(),
|
||||
)
|
||||
},
|
||||
|
|
@ -188,7 +221,7 @@ internal class DefaultSwapRepository(
|
|||
}
|
||||
|
||||
override suspend fun findBestQuote(
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
fromContractAddress: String,
|
||||
fromNetwork: String,
|
||||
toContractAddress: String,
|
||||
|
|
@ -211,6 +244,11 @@ internal class DefaultSwapRepository(
|
|||
toDecimals = toDecimals,
|
||||
providerId = providerId,
|
||||
rateType = rateType.name.lowercase(),
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).getOrThrow()
|
||||
QuoteModel(
|
||||
toTokenAmount = createFromAmountWithOffset(response.toAmount, response.toDecimals),
|
||||
|
|
@ -223,6 +261,7 @@ internal class DefaultSwapRepository(
|
|||
}
|
||||
|
||||
override suspend fun getExchangeData(
|
||||
userWallet: UserWallet,
|
||||
fromContractAddress: String,
|
||||
fromNetwork: String,
|
||||
toContractAddress: String,
|
||||
|
|
@ -255,6 +294,11 @@ internal class DefaultSwapRepository(
|
|||
requestId = requestId,
|
||||
refundAddress = refundAddress,
|
||||
refundExtraId = refundExtraId,
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).getOrThrow()
|
||||
if (dataSignatureVerifier.verifySignature(response.signature, response.txDetailsJson)) {
|
||||
val txDetails = parseTxDetails(response.txDetailsJson)
|
||||
|
|
@ -281,6 +325,7 @@ internal class DefaultSwapRepository(
|
|||
}
|
||||
|
||||
override suspend fun exchangeSent(
|
||||
userWallet: UserWallet,
|
||||
txId: String,
|
||||
fromNetwork: String,
|
||||
fromAddress: String,
|
||||
|
|
@ -290,7 +335,12 @@ internal class DefaultSwapRepository(
|
|||
): Either<ExpressDataError, Unit> = withContext(coroutineDispatcher.io) {
|
||||
try {
|
||||
tangemExpressApi.exchangeSent(
|
||||
ExchangeSentRequestBody(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
body = ExchangeSentRequestBody(
|
||||
txId = txId,
|
||||
fromNetwork = fromNetwork,
|
||||
fromAddress = fromAddress,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.datasource.local.preferences.PreferencesKeys
|
|||
import com.tangem.datasource.local.preferences.utils.getObjectList
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectListSync
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectMapSync
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.converters.SavedSwapTransactionListConverter
|
||||
import com.tangem.feature.swap.domain.SwapTransactionRepository
|
||||
|
|
@ -80,9 +80,8 @@ internal class DefaultSwapTransactionRepository(
|
|||
}
|
||||
|
||||
override suspend fun getTransactions(
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
scanResponse: ScanResponse,
|
||||
): Flow<List<SavedSwapTransactionListModel>?> {
|
||||
return withContext(dispatchers.io) {
|
||||
val txStatuses = appPreferencesStore.getObjectMapSync<ExchangeStatusModel>(
|
||||
|
|
@ -93,7 +92,7 @@ internal class DefaultSwapTransactionRepository(
|
|||
).map { savedTransactions ->
|
||||
val currencyTxs = savedTransactions
|
||||
?.filter {
|
||||
it.userWalletId == userWalletId.stringValue &&
|
||||
it.userWalletId == userWallet.walletId.stringValue &&
|
||||
(
|
||||
it.toCryptoCurrencyId == cryptoCurrencyId.value ||
|
||||
it.fromCryptoCurrencyId == cryptoCurrencyId.value
|
||||
|
|
@ -103,7 +102,7 @@ internal class DefaultSwapTransactionRepository(
|
|||
currencyTxs?.mapNotNull {
|
||||
converter.convertBack(
|
||||
value = it,
|
||||
scanResponse = scanResponse,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
txStatuses = txStatuses,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ internal class SwapDataModule {
|
|||
errorsDataConverter: ErrorsDataConverter,
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
): SwapRepository {
|
||||
return DefaultSwapRepository(
|
||||
tangemExpressApi = tangemExpressApi,
|
||||
|
|
@ -46,6 +47,7 @@ internal class SwapDataModule {
|
|||
dataSignatureVerifier = dataSignature,
|
||||
moshi = moshi,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.swap.domain.api
|
|||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.domain.models.ExpressDataError
|
||||
import com.tangem.feature.swap.domain.models.domain.*
|
||||
|
|
@ -9,16 +10,24 @@ import java.math.BigDecimal
|
|||
|
||||
interface SwapRepository {
|
||||
|
||||
suspend fun getPairs(initialCurrency: LeastTokenInfo, currencyList: List<CryptoCurrency>): PairsWithProviders
|
||||
suspend fun getPairs(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currencyList: List<CryptoCurrency>,
|
||||
): PairsWithProviders
|
||||
|
||||
/** Express getPairs request variant without providers request */
|
||||
suspend fun getPairsOnly(initialCurrency: LeastTokenInfo, currencyList: List<CryptoCurrency>): PairsWithProviders
|
||||
suspend fun getPairsOnly(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currencyList: List<CryptoCurrency>,
|
||||
): PairsWithProviders
|
||||
|
||||
suspend fun getExchangeStatus(txId: String): Either<UnknownError, ExchangeStatusModel>
|
||||
suspend fun getExchangeStatus(userWallet: UserWallet, txId: String): Either<UnknownError, ExchangeStatusModel>
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun findBestQuote(
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
fromContractAddress: String,
|
||||
fromNetwork: String,
|
||||
toContractAddress: String,
|
||||
|
|
@ -43,6 +52,7 @@ interface SwapRepository {
|
|||
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun getExchangeData(
|
||||
userWallet: UserWallet,
|
||||
fromContractAddress: String,
|
||||
fromNetwork: String,
|
||||
toContractAddress: String,
|
||||
|
|
@ -61,6 +71,7 @@ interface SwapRepository {
|
|||
// TODO: Add target error handling, remove either ([REDACTED_JIRA])
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun exchangeSent(
|
||||
userWallet: UserWallet,
|
||||
txId: String,
|
||||
fromNetwork: String,
|
||||
fromAddress: String,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast
|
||||
|
|
@ -10,9 +11,14 @@ class GetAvailablePairsUseCase(
|
|||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currencies: List<CryptoCurrency>,
|
||||
): List<SwapPairLeast> {
|
||||
return swapRepository.getPairsOnly(initialCurrency, currencies).pairs
|
||||
return swapRepository.getPairsOnly(
|
||||
userWallet = userWallet,
|
||||
initialCurrency = initialCurrency,
|
||||
currencyList = currencies,
|
||||
).pairs
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +114,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
}
|
||||
|
||||
val pairsLeast = getPairs(
|
||||
userWallet = userWallet,
|
||||
initialCurrency = LeastTokenInfo(
|
||||
contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress ?: "0",
|
||||
network = currency.network.backendId,
|
||||
|
|
@ -197,10 +198,15 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private suspend fun getPairs(
|
||||
userWallet: UserWallet,
|
||||
initialCurrency: LeastTokenInfo,
|
||||
currenciesList: List<CryptoCurrency>,
|
||||
): PairsWithProviders {
|
||||
return repository.getPairs(initialCurrency, currenciesList)
|
||||
return repository.getPairs(
|
||||
userWallet = userWallet,
|
||||
initialCurrency = initialCurrency,
|
||||
currencyList = currenciesList,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun givePermissionToSwap(
|
||||
|
|
@ -308,7 +314,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
isBalanceWithoutFeeEnough: Boolean,
|
||||
): Pair<SwapProvider, SwapState> {
|
||||
val maybeQuotes = repository.findBestQuote(
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
fromContractAddress = fromToken.currency.getContractAddress(),
|
||||
fromNetwork = fromToken.currency.network.backendId,
|
||||
toContractAddress = toToken.currency.getContractAddress(),
|
||||
|
|
@ -619,6 +625,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
return result.fold(
|
||||
ifRight = { txHash ->
|
||||
repository.exchangeSent(
|
||||
userWallet = userWallet,
|
||||
txId = swapData.transaction.txId,
|
||||
fromNetwork = currencyToSendStatus.currency.network.backendId,
|
||||
fromAddress = currencyToSendStatus.value.networkAddress?.defaultAddress?.value.orEmpty(),
|
||||
|
|
@ -674,6 +681,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
swapProvider: SwapProvider,
|
||||
): SwapTransactionState {
|
||||
val exchangeData = repository.getExchangeData(
|
||||
userWallet = userWallet,
|
||||
fromContractAddress = currencyToSend.currency.getContractAddress(),
|
||||
fromNetwork = currencyToSend.currency.network.backendId,
|
||||
toContractAddress = currencyToGet.currency.getContractAddress(),
|
||||
|
|
@ -726,6 +734,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
ifLeft = { SwapTransactionState.Error.TransactionError(it) },
|
||||
ifRight = { txHash ->
|
||||
repository.exchangeSent(
|
||||
userWallet = userWallet,
|
||||
txId = exchangeDataCex.txId,
|
||||
fromNetwork = currencyToSend.currency.network.backendId,
|
||||
fromAddress = currencyToSend.value.networkAddress?.defaultAddress?.value.orEmpty(),
|
||||
|
|
@ -1132,7 +1141,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
}
|
||||
|
||||
val quotes = repository.findBestQuote(
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
fromContractAddress = fromToken.getContractAddress(),
|
||||
fromNetwork = fromToken.network.backendId,
|
||||
toContractAddress = toToken.getContractAddress(),
|
||||
|
|
@ -1388,6 +1397,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
selectedFee: FeeType,
|
||||
): SwapState {
|
||||
return repository.getExchangeData(
|
||||
userWallet = userWallet,
|
||||
fromContractAddress = fromToken.currency.getContractAddress(),
|
||||
fromNetwork = fromToken.currency.network.backendId,
|
||||
toContractAddress = toToken.currency.getContractAddress(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.domain.models.domain.ExchangeStatusModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModel
|
||||
|
|
@ -18,9 +18,8 @@ interface SwapTransactionRepository {
|
|||
)
|
||||
|
||||
suspend fun getTransactions(
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
scanResponse: ScanResponse,
|
||||
): Flow<List<SavedSwapTransactionListModel>?>
|
||||
|
||||
suspend fun removeTransaction(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import arrow.core.getOrElse
|
|||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.ui.bottomsheet.receive.AddressModel
|
||||
import com.tangem.common.ui.bottomsheet.receive.mapToAddressModels
|
||||
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
|
|
@ -17,8 +19,6 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.common.ui.bottomsheet.receive.AddressModel
|
||||
import com.tangem.common.ui.bottomsheet.receive.mapToAddressModels
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
|
|
@ -166,7 +166,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
appCurrencyProvider = Provider { selectedAppCurrencyFlow.value },
|
||||
currentStateProvider = Provider { uiState.value },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
import com.tangem.domain.tokens.model.Quote
|
||||
import com.tangem.domain.tokens.model.analytics.TokenExchangeAnalyticsEvent
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.swap.domain.SwapTransactionRepository
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.*
|
||||
|
|
@ -29,7 +28,6 @@ import kotlinx.collections.immutable.PersistentList
|
|||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -39,14 +37,13 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
private val quotesRepository: QuotesRepository,
|
||||
private val quotesRepositoryV2: QuotesRepositoryV2,
|
||||
private val tokensFeatureToggles: TokensFeatureToggles,
|
||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val swapTransactionStatusStore: SwapTransactionStatusStore,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
@Assisted private val userWalletId: UserWalletId,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
@Assisted private val cryptoCurrency: CryptoCurrency,
|
||||
) {
|
||||
|
||||
|
|
@ -60,14 +57,9 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
}
|
||||
|
||||
suspend operator fun invoke(): Flow<PersistentList<ExchangeUM>> {
|
||||
val selectedWallet = getSelectedWalletSyncUseCase().fold(
|
||||
ifLeft = { return emptyFlow() },
|
||||
ifRight = { it },
|
||||
)
|
||||
return swapTransactionRepository.getTransactions(
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
scanResponse = selectedWallet.scanResponse,
|
||||
).conflate()
|
||||
.map { savedTransactions ->
|
||||
val quotes = savedTransactions
|
||||
|
|
@ -91,7 +83,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
val shouldDispose = selectedTx.activeStatus?.isAutoDisposable == true || isForceDispose
|
||||
if (shouldDispose) {
|
||||
swapTransactionRepository.removeTransaction(
|
||||
userWalletId = userWalletId,
|
||||
userWalletId = userWallet.walletId,
|
||||
fromCryptoCurrency = selectedTx.fromCryptoCurrency,
|
||||
toCryptoCurrency = selectedTx.toCryptoCurrency,
|
||||
txId = selectedTx.info.txId,
|
||||
|
|
@ -117,7 +109,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private suspend fun getExchangeStatus(txId: String, provider: SwapProvider): ExchangeStatusModel? {
|
||||
return swapRepository.getExchangeStatus(txId)
|
||||
return swapRepository.getExchangeStatus(userWallet = userWallet, txId = txId)
|
||||
.fold(
|
||||
ifLeft = { null },
|
||||
ifRight = { statusModel ->
|
||||
|
|
@ -157,7 +149,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
val refundContractAddress = status.refundContractAddress
|
||||
if (refundNetwork != null && refundContractAddress != null) {
|
||||
return addCryptoCurrenciesUseCase(
|
||||
userWalletId = userWalletId,
|
||||
userWalletId = userWallet.walletId,
|
||||
contractAddress = refundContractAddress,
|
||||
networkId = refundNetwork,
|
||||
).getOrNull()
|
||||
|
|
@ -219,7 +211,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
clickIntents: TokenDetailsClickIntents,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
currentStateProvider: Provider<TokenDetailsState>,
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): ExchangeStatusFactory
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
|||
import com.tangem.domain.tokens.model.analytics.TokenExchangeAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.swap.domain.models.domain.ExchangeStatus
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.ExchangeStatusNotification
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeUM
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -36,7 +36,7 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val cryptoCurrency: CryptoCurrency,
|
||||
@Assisted appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted userWalletId: UserWalletId,
|
||||
@Assisted userWallet: UserWallet,
|
||||
@Assisted cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
|
|
@ -49,7 +49,7 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
clickIntents = clickIntents,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
appCurrencyProvider = appCurrencyProvider,
|
||||
clickIntents = clickIntents,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
clickIntents: TokenDetailsClickIntents,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
currentStateProvider: Provider<TokenDetailsState>,
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
): ExpressStatusFactory
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import com.tangem.domain.onramp.model.OnrampStatus.Status.*
|
|||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsOnrampTransactionStateConverter
|
||||
import com.tangem.utils.Provider
|
||||
|
|
@ -39,7 +39,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
@Assisted private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val cryptoCurrency: CryptoCurrency,
|
||||
@Assisted private val userWalletId: UserWalletId,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
) {
|
||||
|
||||
private val onrampTransactionStateConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -54,7 +54,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
|
||||
operator fun invoke(): Flow<List<ExpressTransactionStateUM.OnrampUM>> {
|
||||
return getOnrampTransactionsUseCase(
|
||||
userWalletId = userWalletId,
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
).map { maybeTransaction ->
|
||||
maybeTransaction.fold(
|
||||
|
|
@ -82,7 +82,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
return if (onrampTx.activeStatus.isTerminal) {
|
||||
onrampTx
|
||||
} else {
|
||||
getOnrampStatusUseCase(onrampTx.info.txId).fold(
|
||||
getOnrampStatusUseCase(userWallet = userWallet, onrampTx.info.txId).fold(
|
||||
ifLeft = {
|
||||
Timber.e("Couldn't update onramp status. $it")
|
||||
onrampTx
|
||||
|
|
@ -150,7 +150,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
clickIntents: TokenDetailsClickIntents,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
): OnrampStatusFactory
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import com.tangem.domain.nft.FetchNFTCollectionsUseCase
|
|||
import com.tangem.domain.settings.*
|
||||
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
|
|
@ -107,9 +108,7 @@ internal class WalletModel @Inject constructor(
|
|||
subscribeToUserWalletsUpdates()
|
||||
subscribeOnBalanceHiding()
|
||||
subscribeOnSelectedWalletFlow()
|
||||
subscribeToScreenBackgroundState()
|
||||
subscribeOnPushNotificationsPermission()
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
subscribeOnNFTUpdates()
|
||||
|
||||
clickIntents.initialize(innerWalletRouter, modelScope)
|
||||
|
|
@ -223,6 +222,8 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
|
||||
walletDeepLinksHandler.registerForWallet(scope = modelScope, userWallet = selectedWallet)
|
||||
subscribeOnExpressTransactionsUpdates(selectedWallet)
|
||||
subscribeToScreenBackgroundState(selectedWallet)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
|
|
@ -231,7 +232,7 @@ internal class WalletModel @Inject constructor(
|
|||
|
||||
// We need to update the current wallet quotes if the application was in the background for more than 10 seconds
|
||||
// and then returned to the foreground
|
||||
private fun subscribeToScreenBackgroundState() {
|
||||
private fun subscribeToScreenBackgroundState(userWallet: UserWallet) {
|
||||
screenLifecycleProvider.isBackgroundState
|
||||
.onEach { isBackground ->
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
|
|
@ -241,30 +242,31 @@ internal class WalletModel @Inject constructor(
|
|||
isBackground -> needToRefreshTimer()
|
||||
needToRefreshWallet && !isBackground -> {
|
||||
triggerRefreshWalletQuotes()
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
subscribeOnExpressTransactionsUpdates(userWallet)
|
||||
}
|
||||
!isBackground -> subscribeOnExpressTransactionsUpdates()
|
||||
!isBackground -> subscribeOnExpressTransactionsUpdates(userWallet)
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
.saveIn(expressStatusJobHolder)
|
||||
}
|
||||
|
||||
private fun subscribeOnExpressTransactionsUpdates() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching { onrampStatusFactory.updateOnrmapTransactionStatuses() }
|
||||
},
|
||||
onSuccess = { /* no-op */ },
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}.saveIn(expressStatusJobHolder)
|
||||
private fun subscribeOnExpressTransactionsUpdates(userWallet: UserWallet) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
onrampStatusFactory.updateOnrmapTransactionStatuses(userWallet)
|
||||
}
|
||||
},
|
||||
onSuccess = { /* no-op */ },
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.onramp.OnrampUpdateTransactionStatusUseCase
|
|||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
import com.tangem.domain.onramp.model.OnrampStatus.Status.*
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -40,22 +41,22 @@ internal class OnrampStatusFactory @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun updateOnrmapTransactionStatuses() = withContext(dispatchers.io) {
|
||||
suspend fun updateOnrmapTransactionStatuses(userWallet: UserWallet) = withContext(dispatchers.io) {
|
||||
val singleWalletState = stateHolder.getSelectedWallet() as? WalletState.SingleCurrency.Content
|
||||
?: return@withContext
|
||||
|
||||
singleWalletState.expressTxs.map { tx ->
|
||||
async {
|
||||
if (tx is ExpressTransactionStateUM.OnrampUM) {
|
||||
updateOnrampTxStatus(tx)
|
||||
updateOnrampTxStatus(userWallet, tx)
|
||||
}
|
||||
}
|
||||
}.awaitAll()
|
||||
}
|
||||
|
||||
private suspend fun updateOnrampTxStatus(onrampTx: ExpressTransactionStateUM.OnrampUM) {
|
||||
private suspend fun updateOnrampTxStatus(userWallet: UserWallet, onrampTx: ExpressTransactionStateUM.OnrampUM) {
|
||||
if (!onrampTx.activeStatus.isTerminal) {
|
||||
getOnrampStatusUseCase(onrampTx.info.txId).fold(
|
||||
getOnrampStatusUseCase(userWallet = userWallet, onrampTx.info.txId).fold(
|
||||
ifLeft = {
|
||||
Timber.e("Couldn't update onramp status. $it")
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue