Updated on 2026-08-14
This commit is contained in:
parent
8670d180d1
commit
03019b0c4c
12 changed files with 50 additions and 68 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.token.DefaultStakingYieldsStore
|
||||
import com.tangem.datasource.local.token.StakingYieldsStore
|
||||
import dagger.Module
|
||||
|
|
@ -16,6 +15,6 @@ internal object StakingTokensStoreModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingTokensStore(): StakingYieldsStore {
|
||||
return DefaultStakingYieldsStore(dataStore = RuntimeDataStore())
|
||||
return DefaultStakingYieldsStore()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.domain.staking.model.StakingTokenWithYield
|
||||
|
||||
internal class DefaultStakingTokensStore(
|
||||
private val dataStore: StringKeyDataStore<List<StakingTokenWithYield>>,
|
||||
) : StakingTokensStore {
|
||||
|
||||
override suspend fun getSyncOrNull(): List<StakingTokenWithYield>? {
|
||||
return dataStore.getSyncOrNull(STAKING_TOKENS_KEY)
|
||||
}
|
||||
|
||||
override suspend fun store(items: List<StakingTokenWithYield>) {
|
||||
dataStore.store(STAKING_TOKENS_KEY, items)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val STAKING_TOKENS_KEY = "STAKING_TOKENS_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,16 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
|
||||
internal class DefaultStakingYieldsStore(
|
||||
private val dataStore: StringKeyDataStore<List<YieldDTO>>,
|
||||
) : StakingYieldsStore {
|
||||
internal class DefaultStakingYieldsStore : StakingYieldsStore {
|
||||
|
||||
override suspend fun getSyncOrNull(): List<YieldDTO>? {
|
||||
return dataStore.getSyncOrNull(STAKING_YIELDS_KEY)
|
||||
private var yields = mutableListOf<YieldDTO>()
|
||||
|
||||
override fun get(): List<YieldDTO> {
|
||||
return yields
|
||||
}
|
||||
|
||||
override suspend fun store(items: List<YieldDTO>) {
|
||||
dataStore.store(STAKING_YIELDS_KEY, items)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val STAKING_YIELDS_KEY = "STAKING_YIELDS_KEY"
|
||||
override fun store(items: List<YieldDTO>) {
|
||||
yields = items.toMutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
|||
|
||||
interface StakingYieldsStore {
|
||||
|
||||
suspend fun getSyncOrNull(): List<YieldDTO>?
|
||||
fun get(): List<YieldDTO>
|
||||
|
||||
suspend fun store(items: List<YieldDTO>)
|
||||
fun store(items: List<YieldDTO>)
|
||||
}
|
||||
|
|
@ -133,11 +133,10 @@ internal class DefaultStakingRepository(
|
|||
|
||||
override suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield {
|
||||
return withContext(dispatchers.io) {
|
||||
val yields = getEnabledYields() ?: error("No yields found")
|
||||
val rawCurrencyId = cryptoCurrencyId.rawCurrencyId ?: error("Staking custom tokens is not available")
|
||||
|
||||
val prefetchedYield = findPrefetchedYield(
|
||||
yields = yields,
|
||||
yields = getEnabledYields(),
|
||||
currencyId = rawCurrencyId,
|
||||
symbol = symbol,
|
||||
)
|
||||
|
|
@ -158,7 +157,7 @@ internal class DefaultStakingRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getStakingAvailability(
|
||||
override fun getStakingAvailability(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): StakingAvailability {
|
||||
|
|
@ -166,26 +165,22 @@ internal class DefaultStakingRepository(
|
|||
|
||||
val rawCurrencyId = cryptoCurrency.id.rawCurrencyId ?: return StakingAvailability.Unavailable
|
||||
|
||||
return withContext(dispatchers.io) {
|
||||
val isSupportedInMobileApp = getSupportedIntegrationId(cryptoCurrency.id).isNullOrEmpty().not()
|
||||
val isSupportedInMobileApp = getSupportedIntegrationId(cryptoCurrency.id).isNullOrEmpty().not()
|
||||
|
||||
val yields = getEnabledYields() ?: return@withContext if (isSupportedInMobileApp) {
|
||||
val prefetchedYield = findPrefetchedYield(
|
||||
yields = getEnabledYields(),
|
||||
currencyId = rawCurrencyId,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
)
|
||||
|
||||
return when {
|
||||
prefetchedYield != null && isSupportedInMobileApp -> {
|
||||
StakingAvailability.Available(prefetchedYield.id)
|
||||
}
|
||||
prefetchedYield == null && isSupportedInMobileApp -> {
|
||||
StakingAvailability.TemporaryUnavailable
|
||||
} else {
|
||||
StakingAvailability.Unavailable
|
||||
}
|
||||
|
||||
val prefetchedYield = findPrefetchedYield(yields, rawCurrencyId, cryptoCurrency.symbol)
|
||||
|
||||
when {
|
||||
prefetchedYield != null && isSupportedInMobileApp -> {
|
||||
StakingAvailability.Available(prefetchedYield.id)
|
||||
}
|
||||
prefetchedYield == null && isSupportedInMobileApp -> {
|
||||
StakingAvailability.TemporaryUnavailable
|
||||
}
|
||||
else -> StakingAvailability.Unavailable
|
||||
}
|
||||
else -> StakingAvailability.Unavailable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -398,7 +393,7 @@ internal class DefaultStakingRepository(
|
|||
key = getYieldBalancesKey(userWalletId),
|
||||
skipCache = refresh,
|
||||
block = {
|
||||
val yields = getEnabledYields() ?: error("No yields found")
|
||||
val yields = getEnabledYields()
|
||||
val availableCurrencies = cryptoCurrencies
|
||||
.mapNotNull { currency ->
|
||||
val addresses = walletManagersFacade.getAddresses(userWalletId, currency.network)
|
||||
|
|
@ -583,9 +578,10 @@ internal class DefaultStakingRepository(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getEnabledYields(): List<Yield>? {
|
||||
val yields = stakingYieldsStore.getSyncOrNull() ?: return null
|
||||
return yields.map { yieldConverter.convert(it) }
|
||||
private fun getEnabledYields(): List<Yield> {
|
||||
return stakingYieldsStore
|
||||
.get()
|
||||
.map { yieldConverter.convert(it) }
|
||||
}
|
||||
|
||||
private fun getBalanceRequestData(address: String, integrationId: String): YieldBalanceRequestBody {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class GetStakingAvailabilityUseCase(
|
|||
private val stakingErrorResolver: StakingErrorResolver,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): Either<StakingError, StakingAvailability> {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ interface StakingRepository {
|
|||
|
||||
suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield
|
||||
|
||||
suspend fun getStakingAvailability(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): StakingAvailability
|
||||
fun getStakingAvailability(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): StakingAvailability
|
||||
|
||||
suspend fun fetchSingleYieldBalance(
|
||||
userWalletId: UserWalletId,
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class MockStakingRepository : StakingRepository {
|
|||
isAvailable = false,
|
||||
)
|
||||
|
||||
override suspend fun getStakingAvailability(
|
||||
override fun getStakingAvailability(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): StakingAvailability = StakingAvailability.Unavailable
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ internal class TokenDetailsFragment : ComposeFragment() {
|
|||
val cryptoCurrency: CryptoCurrency = arguments
|
||||
?.getBundle(AppRoute.CurrencyDetails.CRYPTO_CURRENCY_KEY)
|
||||
?.unbundle(CryptoCurrency.serializer())
|
||||
?: error("Token Details screen can't open without `CryptoCurrency`")
|
||||
?: error("Token Details screen can't be opened without `CryptoCurrency`")
|
||||
|
||||
val param = cryptoCurrency.toParam() ?: return
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.pullToRefresh.PullToRefreshConfig
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.card.NetworkHasDerivationUseCase
|
||||
import com.tangem.domain.staking.GetStakingAvailabilityUseCase
|
||||
import com.tangem.domain.staking.GetStakingIntegrationIdUseCase
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
|
@ -30,6 +32,7 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
||||
private val getStakingIntegrationIdUseCase: GetStakingIntegrationIdUseCase,
|
||||
private val getStakingAvailabilityUseCase: GetStakingAvailabilityUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val userWalletId: UserWalletId,
|
||||
) : Converter<CryptoCurrency, TokenDetailsState> {
|
||||
|
|
@ -39,6 +42,8 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
override fun convert(value: CryptoCurrency): TokenDetailsState {
|
||||
val iconState = iconStateConverter.convert(value)
|
||||
val isSupportedInMobileApp = getStakingIntegrationIdUseCase(value.id).isNullOrBlank().not()
|
||||
val stakingAvailability = getStakingAvailabilityUseCase(userWalletId, value)
|
||||
.getOrElse { StakingAvailability.Unavailable }
|
||||
|
||||
return TokenDetailsState(
|
||||
topAppBarConfig = TokenDetailsTopAppBarConfig(
|
||||
|
|
@ -63,7 +68,11 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
selectedBalanceType = BalanceType.ALL,
|
||||
),
|
||||
marketPriceBlockState = MarketPriceBlockState.Loading(value.symbol),
|
||||
stakingBlocksState = StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp },
|
||||
stakingBlocksState = if (stakingAvailability == StakingAvailability.TemporaryUnavailable) {
|
||||
StakingBlockUM.TemporaryUnavailable
|
||||
} else {
|
||||
StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp }
|
||||
},
|
||||
notifications = persistentListOf(),
|
||||
pendingTxs = persistentListOf(),
|
||||
swapTxs = persistentListOf(),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.card.NetworkHasDerivationUseCase
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.staking.GetStakingAvailabilityUseCase
|
||||
import com.tangem.domain.staking.GetStakingIntegrationIdUseCase
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.staking.model.StakingEntryInfo
|
||||
|
|
@ -60,6 +61,7 @@ internal class TokenDetailsStateFactory(
|
|||
private val userWalletId: UserWalletId,
|
||||
stakingFeatureToggles: StakingFeatureToggles,
|
||||
getStakingIntegrationIdUseCase: GetStakingIntegrationIdUseCase,
|
||||
getStakingAvailabilityUseCase: GetStakingAvailabilityUseCase,
|
||||
symbol: String,
|
||||
decimals: Int,
|
||||
) {
|
||||
|
|
@ -69,6 +71,7 @@ internal class TokenDetailsStateFactory(
|
|||
clickIntents = clickIntents,
|
||||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||
getStakingIntegrationIdUseCase = getStakingIntegrationIdUseCase,
|
||||
getStakingAvailabilityUseCase = getStakingAvailabilityUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
userWalletId = userWalletId,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -135,12 +135,12 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
|
||||
private val userWalletId: UserWalletId = savedStateHandle.get<Bundle>(AppRoute.CurrencyDetails.USER_WALLET_ID_KEY)
|
||||
?.unbundle(UserWalletId.serializer())
|
||||
?: error("This screen can't open without `UserWalletId`")
|
||||
?: error("This screen can't be opened without `UserWalletId`")
|
||||
|
||||
private val cryptoCurrency: CryptoCurrency =
|
||||
savedStateHandle.get<Bundle>(AppRoute.CurrencyDetails.CRYPTO_CURRENCY_KEY)
|
||||
?.unbundle(CryptoCurrency.serializer())
|
||||
?: error("This screen can't open without `CryptoCurrency`")
|
||||
?: error("This screen can't be opened without `CryptoCurrency`")
|
||||
|
||||
private val userWallet: UserWallet
|
||||
|
||||
|
|
@ -172,6 +172,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
userWalletId = userWalletId,
|
||||
stakingFeatureToggles = stakingFeatureToggles,
|
||||
getStakingIntegrationIdUseCase = getStakingIntegrationIdUseCase,
|
||||
getStakingAvailabilityUseCase = getStakingAvailabilityUseCase,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
decimals = cryptoCurrency.decimals,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue