Updated on 2026-08-14
This commit is contained in:
parent
fc0295bf33
commit
d9320f8c2a
25 changed files with 369 additions and 89 deletions
|
|
@ -1,10 +1,8 @@
|
|||
package com.tangem.domain.staking.model
|
||||
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
|
||||
sealed class StakingAvailability {
|
||||
|
||||
data class Available(val yield: Yield) : StakingAvailability()
|
||||
data class Available(val option: StakingOption) : StakingAvailability()
|
||||
|
||||
data object Unavailable : StakingAvailability()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
package com.tangem.domain.staking.model
|
||||
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
|
||||
data class StakingEntryInfo(
|
||||
val rewardInfo: Yield.RewardInfo,
|
||||
val rewardSchedule: Yield.Metadata.RewardSchedule,
|
||||
val tokenSymbol: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tangem.domain.staking.model
|
||||
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import com.tangem.domain.models.staking.NetworkType
|
||||
import com.tangem.domain.models.staking.YieldToken
|
||||
import com.tangem.domain.staking.model.ethpool.P2PEthPoolVault
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
|
||||
/**
|
||||
* Represents a staking option from any provider
|
||||
* Unified abstraction over StakeKit and P2P staking integrations
|
||||
*/
|
||||
sealed interface StakingOption {
|
||||
|
||||
/** Unique identifier for the staking option */
|
||||
val integrationId: String
|
||||
|
||||
/** Annual Percentage Yield */
|
||||
val apy: SerializedBigDecimal
|
||||
|
||||
/** Token being staked */
|
||||
val token: YieldToken // TODO p2p
|
||||
|
||||
/** Whether this staking option is available */
|
||||
val isAvailable: Boolean
|
||||
|
||||
/**
|
||||
* StakeKit staking option
|
||||
* Wraps StakeKit Yield with all validator and metadata information
|
||||
*/
|
||||
data class StakeKit(val yield: Yield) : StakingOption {
|
||||
override val integrationId: String = yield.id
|
||||
override val apy: SerializedBigDecimal = yield.apy
|
||||
override val token: YieldToken = yield.token
|
||||
override val isAvailable: Boolean = yield.isAvailable
|
||||
}
|
||||
|
||||
/**
|
||||
* P2P pooled staking option
|
||||
* Wraps P2P ETH Pool vault information
|
||||
*/
|
||||
data class P2P(val vault: P2PEthPoolVault) : StakingOption {
|
||||
override val integrationId: String =
|
||||
"p2p-ethereum-pooled:${vault.vaultAddress}"
|
||||
override val apy: SerializedBigDecimal = vault.apy
|
||||
override val token: YieldToken = createEthToken()
|
||||
override val isAvailable: Boolean = !vault.isPrivate
|
||||
|
||||
private fun createEthToken(): YieldToken { // TODO
|
||||
return YieldToken(
|
||||
name = "Ethereum",
|
||||
network = NetworkType.ETHEREUM,
|
||||
symbol = "ETH",
|
||||
decimals = 18,
|
||||
address = null, // Native token
|
||||
coinGeckoId = "ethereum",
|
||||
logoURI = null,
|
||||
isPoints = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
package com.tangem.domain.staking.model.ethpool
|
||||
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* P2P.org pooled staking vault information
|
||||
* Simplified version for vault list display
|
||||
* Analogue of stakekit yield
|
||||
*/
|
||||
@Serializable
|
||||
data class P2PEthPoolVault(
|
||||
val vaultAddress: String,
|
||||
val displayName: String,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package com.tangem.domain.staking
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.domain.staking.model.stakekit.StakingError
|
||||
import com.tangem.domain.staking.repositories.P2PEthPoolRepository
|
||||
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Use case for fetching all staking options from all providers
|
||||
* Fetches both StakeKit yields and P2P vaults
|
||||
*/
|
||||
class FetchStakingOptionsUseCase(
|
||||
private val stakingRepository: StakingRepository,
|
||||
private val p2pRepository: P2PEthPoolRepository,
|
||||
private val stakingErrorResolver: StakingErrorResolver,
|
||||
) {
|
||||
suspend operator fun invoke(): Either<StakingError, Unit> {
|
||||
return either {
|
||||
catch(
|
||||
block = {
|
||||
coroutineScope {
|
||||
launch { stakingRepository.fetchYields() }
|
||||
launch { p2pRepository.fetchVaults() }
|
||||
}
|
||||
},
|
||||
catch = { stakingErrorResolver.resolve(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ class FetchStakingTokensUseCase(
|
|||
suspend operator fun invoke(): Either<StakingError, Unit> {
|
||||
return either {
|
||||
catch(
|
||||
block = { stakingRepository.fetchEnabledYields() },
|
||||
block = { stakingRepository.fetchYields() },
|
||||
catch = { stakingErrorResolver.resolve(it) },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.staking
|
|||
import arrow.core.Either
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.staking.model.StakingEntryInfo
|
||||
import com.tangem.domain.staking.model.StakingOption
|
||||
import com.tangem.domain.staking.model.stakekit.StakingError
|
||||
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
|
|
@ -18,13 +19,23 @@ class GetStakingEntryInfoUseCase(
|
|||
suspend operator fun invoke(
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
symbol: String,
|
||||
stakingOption: StakingOption,
|
||||
): Either<StakingError, StakingEntryInfo> {
|
||||
return Either
|
||||
.catch {
|
||||
stakingRepository.getEntryInfo(
|
||||
cryptoCurrencyId = cryptoCurrencyId,
|
||||
symbol = symbol,
|
||||
)
|
||||
when (stakingOption) {
|
||||
is StakingOption.StakeKit -> {
|
||||
stakingRepository.getEntryInfo(
|
||||
cryptoCurrencyId = cryptoCurrencyId,
|
||||
symbol = symbol,
|
||||
)
|
||||
}
|
||||
is StakingOption.P2P -> {
|
||||
StakingEntryInfo(
|
||||
tokenSymbol = "ETH",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.mapLeft { stakingErrorResolver.resolve(it) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,15 @@ import arrow.core.Either
|
|||
import com.tangem.domain.staking.model.ethpool.*
|
||||
import com.tangem.domain.staking.model.stakekit.StakingError
|
||||
|
||||
/**
|
||||
* P2P staking repository interface
|
||||
*/
|
||||
interface P2PEthPoolRepository {
|
||||
|
||||
/**
|
||||
* Fetch and store available staking vaults
|
||||
*
|
||||
* @param network P2P network (MAINNET or TESTNET)
|
||||
*/
|
||||
suspend fun fetchVaults(network: P2PEthPoolNetwork = P2PEthPoolNetwork.MAINNET)
|
||||
|
||||
/**
|
||||
* Get list of available staking vaults
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@ import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate
|
|||
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
// TODO p2p make 3 repos: stakekit, p2p, common staking
|
||||
@Suppress("TooManyFunctions")
|
||||
interface StakingRepository {
|
||||
|
||||
suspend fun fetchEnabledYields()
|
||||
suspend fun fetchYields()
|
||||
|
||||
fun getEnabledYields(): Flow<List<Yield>>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue