Updated on 2026-08-14
This commit is contained in:
parent
3f60d15820
commit
03f4f51fc7
8 changed files with 42 additions and 354 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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()}⚓")
|
||||
}
|
||||
}
|
||||
|
|
@ -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?
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue