Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-28 09:54:30 +04:00
parent 3f60d15820
commit 03f4f51fc7
8 changed files with 42 additions and 354 deletions

View file

@ -13,6 +13,7 @@ import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
import com.tangem.domain.staking.StakingIdFactory
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.staking.multi.MultiYieldBalanceSupplier
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.single.SingleYieldBalanceFetcher
import com.tangem.domain.staking.single.SingleYieldBalanceSupplier
@ -404,7 +405,6 @@ internal object TokensDomainModule {
tokensFeatureToggles: TokensFeatureToggles,
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
stakingRepository: StakingRepository,
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
@ -412,6 +412,7 @@ internal object TokensDomainModule {
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
multiYieldBalanceSupplier: MultiYieldBalanceSupplier,
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
stakingIdFactory: StakingIdFactory,
@ -419,7 +420,6 @@ internal object TokensDomainModule {
return CachedCurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
stakingRepository = stakingRepository,
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
@ -427,6 +427,7 @@ internal object TokensDomainModule {
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
singleQuoteStatusSupplier = singleQuoteStatusSupplier,
singleYieldBalanceSupplier = singleYieldBalanceSupplier,
multiYieldBalanceSupplier = multiYieldBalanceSupplier,
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
tokensFeatureToggles = tokensFeatureToggles,
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
@ -440,7 +441,6 @@ internal object TokensDomainModule {
tokensFeatureToggles: TokensFeatureToggles,
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
stakingRepository: StakingRepository,
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
@ -448,6 +448,7 @@ internal object TokensDomainModule {
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
multiYieldBalanceSupplier: MultiYieldBalanceSupplier,
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
stakingIdFactory: StakingIdFactory,
@ -455,7 +456,6 @@ internal object TokensDomainModule {
return CachedCurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
stakingRepository = stakingRepository,
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
@ -463,6 +463,7 @@ internal object TokensDomainModule {
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
singleQuoteStatusSupplier = singleQuoteStatusSupplier,
singleYieldBalanceSupplier = singleYieldBalanceSupplier,
multiYieldBalanceSupplier = multiYieldBalanceSupplier,
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
tokensFeatureToggles = tokensFeatureToggles,

View file

@ -20,7 +20,6 @@ import com.tangem.data.staking.converters.transaction.StakingTransactionConverte
import com.tangem.data.staking.converters.transaction.StakingTransactionStatusConverter
import com.tangem.data.staking.converters.transaction.StakingTransactionTypeConverter
import com.tangem.data.staking.store.YieldsBalancesStore
import com.tangem.data.staking.utils.StakingIdFactory
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.stakekit.StakeKitApi
@ -60,7 +59,6 @@ import com.tangem.utils.extensions.orZero
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.math.BigDecimal
@Suppress("LargeClass", "LongParameterList", "TooManyFunctions")
internal class DefaultStakingRepository(
@ -71,7 +69,6 @@ internal class DefaultStakingRepository(
private val walletManagersFacade: WalletManagersFacade,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val stakingFeatureToggles: StakingFeatureToggles,
private val stakingIdFactory: StakingIdFactory,
moshi: Moshi,
) : StakingRepository {
@ -375,32 +372,6 @@ internal class DefaultStakingRepository(
}
}
override suspend fun getSingleYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrency: CryptoCurrency,
): YieldBalance {
val stakingId = stakingIdFactory.create(
userWalletId = userWalletId,
currencyId = cryptoCurrency.id,
network = cryptoCurrency.network,
) ?: error("Could not create stakingId")
return stakingBalanceStoreV2.getSyncOrNull(userWalletId = userWalletId, stakingId = stakingId)
?: YieldBalance.Error(integrationId = stakingId.integrationId, address = stakingId.address)
}
override suspend fun getMultiYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): List<YieldBalance>? {
val stakingIds = cryptoCurrencies.mapNotNull {
stakingIdFactory.create(userWalletId = userWalletId, currencyId = it.id, network = it.network)
}
return stakingBalanceStoreV2.getAllSyncOrNull(userWalletId)
?.filter { it.getStakingId() in stakingIds }
}
override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean {
return withContext(dispatchers.default) {
val balances = stakingBalanceStoreV2.getAllSyncOrNull(userWalletId) ?: return@withContext false
@ -415,14 +386,6 @@ internal class DefaultStakingRepository(
}
}
override fun getActionRequirementAmount(integrationId: String, stakingActionType: StakingActionType): BigDecimal? {
return when {
stakingIdFactory.isPolygonIntegrationId(integrationId) &&
stakingActionType == StakingActionType.CLAIM_REWARDS -> BigDecimal.ONE
else -> null
}
}
private suspend fun createActionRequestBody(
userWalletId: UserWalletId,
network: Network,

View file

@ -10,7 +10,6 @@ import com.tangem.data.staking.DefaultStakingTransactionHashRepository
import com.tangem.data.staking.converters.error.StakeKitErrorConverter
import com.tangem.data.staking.store.YieldsBalancesStore
import com.tangem.data.staking.toggles.DefaultStakingFeatureToggles
import com.tangem.data.staking.utils.StakingIdFactory
import com.tangem.datasource.api.stakekit.StakeKitApi
import com.tangem.datasource.api.stakekit.models.response.model.error.StakeKitErrorResponse
import com.tangem.datasource.di.NetworkMoshi
@ -45,7 +44,6 @@ internal object StakingDataModule {
walletManagersFacade: WalletManagersFacade,
getUserWalletUseCase: GetUserWalletUseCase,
stakingFeatureToggles: StakingFeatureToggles,
stakingIdFactory: StakingIdFactory,
@NetworkMoshi moshi: Moshi,
): StakingRepository {
return DefaultStakingRepository(
@ -57,7 +55,6 @@ internal object StakingDataModule {
getUserWalletUseCase = getUserWalletUseCase,
stakingFeatureToggles = stakingFeatureToggles,
moshi = moshi,
stakingIdFactory = stakingIdFactory,
)
}

View file

@ -1,77 +0,0 @@
package com.tangem.data.staking.utils
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.toCoinId
import com.tangem.blockchainsdk.utils.toMigratedCoinId
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.model.StakingID
import com.tangem.domain.walletmanager.WalletManagersFacade
import javax.inject.Inject
/**
* Factory of [StakingID]
*
* @property walletManagersFacade wallet manager facade
*
[REDACTED_AUTHOR]
*/
internal class StakingIdFactory @Inject constructor(
private val walletManagersFacade: WalletManagersFacade,
) {
suspend fun create(userWalletId: UserWalletId, currencyId: CryptoCurrency.ID, network: Network): StakingID? {
val address = walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network)
val integrationId = createIntegrationId(currencyId)
if (address == null || integrationId == null) return null
return StakingID(integrationId = integrationId, address = address)
}
fun createIntegrationId(currencyId: CryptoCurrency.ID): String? {
val integrationKey = with(currencyId) { rawNetworkId.plus(rawCurrencyId) }
return integrationIdMap[integrationKey]
}
fun isPolygonIntegrationId(integrationId: String): Boolean = integrationId == ETHEREUM_POLYGON_INTEGRATION_ID
@Suppress("UnusedPrivateMember", "unused")
companion object {
private const val TON_INTEGRATION_ID = "ton-ton-chorus-one-pools-staking"
private const val SOLANA_INTEGRATION_ID = "solana-sol-native-multivalidator-staking"
private const val COSMOS_INTEGRATION_ID = "cosmos-atom-native-staking"
private const val ETHEREUM_POLYGON_INTEGRATION_ID = "ethereum-matic-native-staking"
private const val BINANCE_INTEGRATION_ID = "bsc-bnb-native-staking"
private const val POLKADOT_INTEGRATION_ID = "polkadot-dot-validator-staking"
private const val AVALANCHE_INTEGRATION_ID = "avalanche-avax-native-staking"
private const val TRON_INTEGRATION_ID = "tron-trx-native-staking"
private const val CRONOS_INTEGRATION_ID = "cronos-cro-native-staking"
private const val KAVA_INTEGRATION_ID = "kava-kava-native-staking"
private const val NEAR_INTEGRATION_ID = "near-near-native-staking"
private const val TEZOS_INTEGRATION_ID = "tezos-xtz-native-staking"
private const val CARDANO_INTEGRATION_ID = "cardano-ada-native-staking"
// uncomment items as implementation is ready
private val integrationIdMap = mapOf(
Blockchain.TON.toDefaultKey() to TON_INTEGRATION_ID,
Blockchain.Solana.toDefaultKey() to SOLANA_INTEGRATION_ID,
Blockchain.Cosmos.toDefaultKey() to COSMOS_INTEGRATION_ID,
Blockchain.Tron.toDefaultKey() to TRON_INTEGRATION_ID,
Blockchain.Ethereum.id + Blockchain.Polygon.toMigratedCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
// Blockchain.Ethereum.id + Blockchain.Polygon.toCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
Blockchain.BSC.toDefaultKey() to BINANCE_INTEGRATION_ID,
// Blockchain.Polkadot.toDefaultKey() to POLKADOT_INTEGRATION_ID,
// Blockchain.Avalanche.toDefaultKey() to AVALANCHE_INTEGRATION_ID,
// Blockchain.Cronos.toDefaultKey() to CRONOS_INTEGRATION_ID,
// Blockchain.Kava.toDefaultKey() to KAVA_INTEGRATION_ID,
// Blockchain.Near.toDefaultKey() to NEAR_INTEGRATION_ID,
// Blockchain.Tezos.toDefaultKey() to TEZOS_INTEGRATION_ID,
Blockchain.Cardano.toDefaultKey() to CARDANO_INTEGRATION_ID,
)
private fun Blockchain.toDefaultKey(): String = id + toCoinId()
}
}

View file

@ -1,188 +0,0 @@
package com.tangem.data.staking.utils
import com.google.common.truth.Truth
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.toCoinId
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
import com.tangem.common.test.utils.ProvideTestModels
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.model.StakingID
import com.tangem.domain.walletmanager.WalletManagersFacade
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.params.ParameterizedTest
/**
[REDACTED_AUTHOR]
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class StakingIdFactoryTest {
private val walletManagersFacade: WalletManagersFacade = mockk()
private val factory = StakingIdFactory(walletManagersFacade = walletManagersFacade)
@BeforeEach
fun resetMocks() {
clearMocks(walletManagersFacade)
}
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class CreateIntegrationId {
@ParameterizedTest
@ProvideTestModels
fun createIntegrationId(model: CreateIntegrationIdModel) {
// Act
val actual = factory.createIntegrationId(currencyId = model.currencyId)
// Assert
Truth.assertThat(actual).isEqualTo(model.expected)
}
private fun provideTestModels() = listOf(
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.TON),
expected = "ton-ton-chorus-one-pools-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.Solana),
expected = "solana-sol-native-multivalidator-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.Cosmos),
expected = "cosmos-atom-native-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.Tron),
expected = "tron-trx-native-staking",
),
CreateIntegrationIdModel(
currencyId = CryptoCurrency.ID.fromValue(value = "coin⟨ETH⟩polygon-ecosystem-token⚓"),
expected = "ethereum-matic-native-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.BSC),
expected = "bsc-bnb-native-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.Cardano),
expected = "cardano-ada-native-staking",
),
CreateIntegrationIdModel(
currencyId = createCurrencyId(blockchain = Blockchain.Bitcoin),
expected = null,
),
)
}
data class CreateIntegrationIdModel(val currencyId: CryptoCurrency.ID, val expected: String?)
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class Create {
private val defaultAddress = "address"
@Test
fun `create returns null if address is null`() = runTest {
// Arrange
val userWalletId = UserWalletId(stringValue = "011")
val currency = MockCryptoCurrencyFactory().createCoin(Blockchain.TON)
coEvery {
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = currency.network)
} returns null
// Act
val actual = factory.create(
userWalletId = userWalletId,
currencyId = currency.id,
network = currency.network,
)
// Assert
val expected = null
Truth.assertThat(actual).isEqualTo(expected)
coVerify(exactly = 1) {
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = currency.network)
}
}
@ParameterizedTest
@ProvideTestModels
fun create(model: CreateModel) = runTest {
// Arrange
val userWalletId = UserWalletId(stringValue = "011")
val network = MockCryptoCurrencyFactory().createCoin(Blockchain.TON).network
coEvery {
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network)
} returns defaultAddress
// Act
val actual = factory.create(userWalletId = userWalletId, currencyId = model.currencyId, network = network)
// Assert
Truth.assertThat(actual).isEqualTo(model.expected)
coVerify(exactly = 1) {
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network)
}
}
private fun provideTestModels() = listOf(
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.TON),
expected = createStakingId(integrationId = "ton-ton-chorus-one-pools-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.Solana),
expected = createStakingId(integrationId = "solana-sol-native-multivalidator-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.Cosmos),
expected = createStakingId(integrationId = "cosmos-atom-native-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.Tron),
expected = createStakingId(integrationId = "tron-trx-native-staking"),
),
CreateModel(
currencyId = CryptoCurrency.ID.fromValue(value = "coin⟨ETH⟩polygon-ecosystem-token⚓"),
expected = createStakingId(integrationId = "ethereum-matic-native-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.BSC),
expected = createStakingId(integrationId = "bsc-bnb-native-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.Cardano),
expected = createStakingId(integrationId = "cardano-ada-native-staking"),
),
CreateModel(
currencyId = createCurrencyId(blockchain = Blockchain.Bitcoin),
expected = null,
),
)
private fun createStakingId(integrationId: String): StakingID {
return StakingID(integrationId = integrationId, address = defaultAddress)
}
}
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: StakingID?)
private fun createCurrencyId(blockchain: Blockchain): CryptoCurrency.ID {
return CryptoCurrency.ID.fromValue(value = "coin⟨${blockchain.id}${blockchain.toCoinId()}")
}
}

View file

@ -10,15 +10,12 @@ import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingEntryInfo
import com.tangem.domain.staking.model.stakekit.NetworkType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.action.StakingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionStatus
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.domain.staking.model.stakekit.transaction.ActionParams
import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
import kotlinx.coroutines.flow.Flow
import java.math.BigDecimal
@Suppress("TooManyFunctions")
interface StakingRepository {
@ -45,13 +42,6 @@ interface StakingRepository {
stakingActionStatus: StakingActionStatus,
): List<StakingAction>
suspend fun getSingleYieldBalanceSync(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): YieldBalance
suspend fun getMultiYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): List<YieldBalance>?
suspend fun createAction(userWalletId: UserWalletId, network: Network, params: ActionParams): StakingAction
suspend fun estimateGas(userWalletId: UserWalletId, network: Network, params: ActionParams): StakingGasEstimate
@ -64,9 +54,4 @@ interface StakingRepository {
): Pair<StakingTransaction, TransactionData.Compiled>
suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean
/**
* Return action requirement amount
*/
fun getActionRequirementAmount(integrationId: String, stakingActionType: StakingActionType): BigDecimal?
}

View file

@ -1,10 +1,7 @@
package com.tangem.domain.tokens.operations
import arrow.core.*
import arrow.core.raise.Raise
import arrow.core.raise.catch
import arrow.core.raise.either
import arrow.core.raise.recover
import arrow.core.raise.*
import com.tangem.blockchainsdk.utils.toBlockchain
import com.tangem.domain.core.utils.EitherFlow
import com.tangem.domain.models.currency.CryptoCurrency
@ -23,7 +20,8 @@ import com.tangem.domain.staking.StakingIdFactory
import com.tangem.domain.staking.model.StakingID
import com.tangem.domain.staking.model.isStakingSupported
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.multi.MultiYieldBalanceProducer
import com.tangem.domain.staking.multi.MultiYieldBalanceSupplier
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
import com.tangem.domain.staking.single.SingleYieldBalanceSupplier
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
@ -39,7 +37,6 @@ import kotlinx.coroutines.flow.*
* Base operations for working with currency status
*
* @property currenciesRepository repository for currencies
* @property stakingRepository repository for staking
*
[REDACTED_AUTHOR]
*/
@ -47,11 +44,11 @@ import kotlinx.coroutines.flow.*
abstract class BaseCurrencyStatusOperations(
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
private val stakingRepository: StakingRepository,
private val multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
private val singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
private val singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
private val multiYieldBalanceSupplier: MultiYieldBalanceSupplier,
private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
private val stakingIdFactory: StakingIdFactory,
private val tokensFeatureToggles: TokensFeatureToggles,
@ -411,34 +408,44 @@ abstract class BaseCurrencyStatusOperations(
private suspend fun getYieldBalancesSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): Either<Error.EmptyYieldBalances, List<YieldBalance>> {
return catch(
block = {
val balances = stakingRepository.getMultiYieldBalanceSync(
userWalletId = userWalletId,
cryptoCurrencies = cryptoCurrencies,
)
): Either<Error.EmptyYieldBalances, List<YieldBalance>> = either {
val stakingIds = cryptoCurrencies.mapNotNull { cryptoCurrency ->
stakingIdFactory.create(userWalletId = userWalletId, cryptoCurrency = cryptoCurrency)
.getOrNull()
}
if (balances.isNullOrEmpty()) {
Error.EmptyYieldBalances.left()
} else {
balances.right()
}
},
catch = { Error.EmptyYieldBalances.left() },
ensure(stakingIds.isNotEmpty()) { Error.EmptyYieldBalances }
val balances = multiYieldBalanceSupplier.getSyncOrNull(
params = MultiYieldBalanceProducer.Params(userWalletId = userWalletId),
)
.orEmpty()
.filter { it.getStakingId() in stakingIds }
ensure(balances.isNotEmpty()) { Error.EmptyYieldBalances }
balances
}
private suspend fun getYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrency: CryptoCurrency,
): Either<Error.EmptyYieldBalances, YieldBalance> {
return catch(
block = { stakingRepository.getSingleYieldBalanceSync(userWalletId, cryptoCurrency).right() },
catch = {
Error.EmptyYieldBalances.left()
},
): Either<Error, YieldBalance> = either {
val stakingId = stakingIdFactory.create(userWalletId, cryptoCurrency)
.mapLeft {
val exception = IllegalStateException("$it")
Error.DataError(exception)
}
.bind()
val yieldBalance = singleYieldBalanceSupplier.getSyncOrNull(
params = SingleYieldBalanceProducer.Params(
userWalletId = userWalletId,
stakingId = stakingId,
),
)
ensureNotNull(yieldBalance) { Error.EmptyYieldBalances }
}
private suspend fun Raise<Error>.getPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {

View file

@ -28,7 +28,7 @@ import com.tangem.domain.staking.StakingIdFactory
import com.tangem.domain.staking.model.StakingIntegrationID
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.multi.MultiYieldBalanceSupplier
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
import com.tangem.domain.staking.single.SingleYieldBalanceSupplier
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.*
class CachedCurrenciesStatusesOperations(
private val currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
stakingRepository: StakingRepository,
private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
@ -55,6 +54,7 @@ class CachedCurrenciesStatusesOperations(
private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
private val singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
private val singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
multiYieldBalanceSupplier: MultiYieldBalanceSupplier,
private val multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
private val stakingIdFactory: StakingIdFactory,
@ -63,11 +63,11 @@ class CachedCurrenciesStatusesOperations(
BaseCurrencyStatusOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
stakingRepository = stakingRepository,
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
singleQuoteStatusSupplier = singleQuoteStatusSupplier,
singleYieldBalanceSupplier = singleYieldBalanceSupplier,
multiYieldBalanceSupplier = multiYieldBalanceSupplier,
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
stakingIdFactory = stakingIdFactory,
tokensFeatureToggles = tokensFeatureToggles,