Updated on 2026-08-14
This commit is contained in:
parent
072d04125d
commit
e00fd4599e
14 changed files with 492 additions and 253 deletions
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import com.tangem.domain.models.staking.StakingEntryType.Companion.fromBalanceType
|
||||
|
||||
fun BalanceItem.toStakingBalanceEntry(validatorName: String? = null): StakingBalanceEntry {
|
||||
return StakingBalanceEntry(
|
||||
id = groupId,
|
||||
type = fromBalanceType(type),
|
||||
amount = amount,
|
||||
validator = validatorAddress?.let {
|
||||
ValidatorInfo(address = it, name = validatorName)
|
||||
},
|
||||
date = date,
|
||||
actions = StakingEntryActions.StakeKit(
|
||||
pendingActions = pendingActions,
|
||||
pendingActionsConstraints = pendingActionsConstraints,
|
||||
),
|
||||
isPending = isPending,
|
||||
rawCurrencyId = rawCurrencyId,
|
||||
)
|
||||
}
|
||||
|
||||
fun List<BalanceItem>.toStakingBalanceEntries(
|
||||
validatorNameResolver: (String?) -> String? = { null },
|
||||
): List<StakingBalanceEntry> {
|
||||
return map { it.toStakingBalanceEntry(validatorNameResolver(it.validatorAddress)) }
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
fun P2PEthPoolStakingAccount.toStakingBalanceEntries(vaultName: String? = null): List<StakingBalanceEntry> {
|
||||
return buildList {
|
||||
if (stake.assets > BigDecimal.ZERO) {
|
||||
add(
|
||||
StakingBalanceEntry(
|
||||
id = vaultAddress,
|
||||
type = StakingEntryType.STAKED,
|
||||
amount = stake.assets,
|
||||
validator = ValidatorInfo(address = vaultAddress, name = vaultName),
|
||||
date = null,
|
||||
actions = StakingEntryActions.P2PEthPool(
|
||||
ticket = null,
|
||||
estimatedWithdrawalDate = null,
|
||||
isClaimable = false,
|
||||
),
|
||||
isPending = false,
|
||||
rawCurrencyId = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
exitQueue.requests.forEach { request ->
|
||||
add(
|
||||
StakingBalanceEntry(
|
||||
id = "${vaultAddress}_${request.ticket}",
|
||||
type = StakingEntryType.UNSTAKING,
|
||||
amount = request.totalAssets,
|
||||
validator = ValidatorInfo(address = vaultAddress, name = vaultName),
|
||||
date = request.withdrawalTimestamp,
|
||||
actions = StakingEntryActions.P2PEthPool(
|
||||
ticket = request.ticket,
|
||||
estimatedWithdrawalDate = request.withdrawalTimestamp,
|
||||
isClaimable = request.isClaimable,
|
||||
),
|
||||
isPending = false,
|
||||
rawCurrencyId = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if (availableToWithdraw > BigDecimal.ZERO) {
|
||||
add(
|
||||
StakingBalanceEntry(
|
||||
id = "${vaultAddress}_withdrawable",
|
||||
type = StakingEntryType.WITHDRAWABLE,
|
||||
amount = availableToWithdraw,
|
||||
validator = ValidatorInfo(address = vaultAddress, name = vaultName),
|
||||
date = null,
|
||||
actions = StakingEntryActions.P2PEthPool(
|
||||
ticket = null,
|
||||
estimatedWithdrawalDate = null,
|
||||
isClaimable = true,
|
||||
),
|
||||
isPending = false,
|
||||
rawCurrencyId = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -21,6 +22,9 @@ sealed interface StakingBalance {
|
|||
@Serializable
|
||||
sealed interface Data : StakingBalance {
|
||||
|
||||
/** Provider-agnostic list of balance entries for UI display */
|
||||
val entries: List<StakingBalanceEntry>
|
||||
|
||||
@Serializable
|
||||
data class StakeKit(
|
||||
override val stakingId: StakingID,
|
||||
|
|
@ -28,25 +32,23 @@ sealed interface StakingBalance {
|
|||
val balance: YieldBalanceItem,
|
||||
) : Data {
|
||||
|
||||
override val totalStaked: BigDecimal
|
||||
get() = balance.items
|
||||
.filter { it.type == BalanceType.STAKED }
|
||||
.sumOf { it.amount }
|
||||
override val totalStaked: SerializedBigDecimal = balance.items
|
||||
.filter { it.type == BalanceType.STAKED }
|
||||
.sumOf { it.amount }
|
||||
|
||||
override val totalRewards: BigDecimal
|
||||
get() = balance.items
|
||||
.filter { it.type == BalanceType.REWARDS }
|
||||
.sumOf { it.amount }
|
||||
override val totalRewards: SerializedBigDecimal = balance.items
|
||||
.filter { it.type == BalanceType.REWARDS }
|
||||
.sumOf { it.amount }
|
||||
|
||||
override val unstakingAmount: BigDecimal
|
||||
get() = balance.items
|
||||
.filter { it.type == BalanceType.UNSTAKING || it.type == BalanceType.UNLOCKING }
|
||||
.sumOf { it.amount }
|
||||
override val unstakingAmount: SerializedBigDecimal = balance.items
|
||||
.filter { it.type == BalanceType.UNSTAKING || it.type == BalanceType.UNLOCKING }
|
||||
.sumOf { it.amount }
|
||||
|
||||
override val withdrawableAmount: BigDecimal
|
||||
get() = balance.items
|
||||
.filter { it.type == BalanceType.UNSTAKED }
|
||||
.sumOf { it.amount }
|
||||
override val withdrawableAmount: SerializedBigDecimal = balance.items
|
||||
.filter { it.type == BalanceType.UNSTAKED }
|
||||
.sumOf { it.amount }
|
||||
|
||||
override val entries: List<StakingBalanceEntry> = balance.items.toStakingBalanceEntries()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
|
@ -56,17 +58,15 @@ sealed interface StakingBalance {
|
|||
val account: P2PEthPoolStakingAccount,
|
||||
) : Data {
|
||||
|
||||
override val totalStaked: BigDecimal
|
||||
get() = account.stake.assets
|
||||
override val totalStaked: SerializedBigDecimal = account.stake.assets
|
||||
|
||||
override val totalRewards: BigDecimal
|
||||
get() = account.stake.totalEarnedAssets
|
||||
override val totalRewards: SerializedBigDecimal = account.stake.totalEarnedAssets
|
||||
|
||||
override val unstakingAmount: BigDecimal
|
||||
get() = account.exitQueue.total
|
||||
override val unstakingAmount: SerializedBigDecimal = account.exitQueue.total
|
||||
|
||||
override val withdrawableAmount: BigDecimal
|
||||
get() = account.availableToWithdraw
|
||||
override val withdrawableAmount: SerializedBigDecimal = account.availableToWithdraw
|
||||
|
||||
override val entries: List<StakingBalanceEntry> = account.toStakingBalanceEntries()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class StakingBalanceEntry(
|
||||
val id: String,
|
||||
val type: StakingEntryType,
|
||||
val amount: SerializedBigDecimal,
|
||||
val validator: ValidatorInfo?,
|
||||
val date: Instant?,
|
||||
val actions: StakingEntryActions,
|
||||
val isPending: Boolean,
|
||||
val rawCurrencyId: String?,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ValidatorInfo(
|
||||
val address: String,
|
||||
val name: String?,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface StakingEntryActions {
|
||||
|
||||
@Serializable
|
||||
data class StakeKit(
|
||||
val pendingActions: List<PendingAction>,
|
||||
val pendingActionsConstraints: List<PendingActionConstraints>,
|
||||
) : StakingEntryActions {
|
||||
val hasPendingActions: Boolean get() = pendingActions.isNotEmpty()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class P2PEthPool(
|
||||
val ticket: String?,
|
||||
val estimatedWithdrawalDate: Instant?,
|
||||
val isClaimable: Boolean,
|
||||
) : StakingEntryActions
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.domain.models.staking
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
enum class StakingEntryType {
|
||||
AVAILABLE,
|
||||
STAKED,
|
||||
PREPARING,
|
||||
LOCKED,
|
||||
UNSTAKING,
|
||||
UNLOCKING,
|
||||
WITHDRAWABLE,
|
||||
REWARDS,
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromBalanceType(type: BalanceType): StakingEntryType = when (type) {
|
||||
BalanceType.AVAILABLE -> AVAILABLE
|
||||
BalanceType.STAKED -> STAKED
|
||||
BalanceType.PREPARING -> PREPARING
|
||||
BalanceType.LOCKED -> LOCKED
|
||||
BalanceType.UNSTAKING -> UNSTAKING
|
||||
BalanceType.UNLOCKING -> UNLOCKING
|
||||
BalanceType.UNSTAKED -> WITHDRAWABLE // stakekit's UNSTAKED = ready to withdraw
|
||||
BalanceType.REWARDS -> REWARDS
|
||||
BalanceType.UNKNOWN -> UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue