From 8bdb35bccd371117595dbbf44f1615853c45f186 Mon Sep 17 00:00:00 2001 From: Bill He Date: Wed, 29 May 2024 10:07:44 -0700 Subject: [PATCH] Parse delegations for account staking balances --- .../exchange.dydx.abacus/output/Account.kt | 52 +++++++++++++++++++ .../wallet/account/AccountProcessor.kt | 38 ++++++++++++-- .../state/model/TradingStateMachine.kt | 1 + 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/output/Account.kt b/src/commonMain/kotlin/exchange.dydx.abacus/output/Account.kt index f010bb6de..d4cc279f7 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/output/Account.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/output/Account.kt @@ -1567,6 +1567,38 @@ data class AccountBalance( } } +@JsExport +@Serializable +data class StakingDelegation( + var validator: String, + var amount: String, +) { + companion object { + internal fun create( + existing: StakingDelegation?, + parser: ParserProtocol, + data: Map, + decimals: Int, + ): StakingDelegation? { + Logger.d { "creating Staking Delegation\n" } + + val validator = parser.asString(data["validator"]) + val amount = parser.asDecimal(data["amount"]) + if (validator != null && amount != null) { + val decimalAmount = amount * Numeric.decimal.TEN.pow(-1 * decimals) + val decimalAmountString = parser.asString(decimalAmount)!! + return if (existing?.validator != validator || existing.amount != decimalAmountString) { + StakingDelegation(validator, decimalAmountString) + } else { + existing + } + } + Logger.d { "Staking Delegation not valid" } + return null + } + } +} + @JsExport @Serializable data class HistoricalTradingReward( @@ -2020,6 +2052,7 @@ data class TradingRewards( data class Account( var balances: IMap?, var stakingBalances: IMap?, + var stakingDelegations: IList?, var subaccounts: IMap?, var groupedSubaccounts: IMap?, var tradingRewards: TradingRewards?, @@ -2078,6 +2111,24 @@ data class Account( } } + val stakingDelegations: IMutableList = + iMutableListOf() + val stakingDelegationsData = parser.asList(data["stakingDelegations"]) + stakingDelegationsData?.forEachIndexed { index, value -> + val stakingDelegationData = parser.asMap(value) ?: iMapOf() + val tokenInfo = findTokenInfo(tokensInfo, stakingDelegationData["denom"] as String) + if (tokenInfo != null) { + StakingDelegation.create( + existing?.stakingDelegations?.getOrNull(index), + parser, + stakingDelegationData, + tokenInfo.decimals, + )?.let { stakingDelegation -> + stakingDelegations.add(stakingDelegation) + } + } + } + val tradingRewardsData = parser.asMap(data["tradingRewards"]) val tradingRewards = if (tradingRewardsData != null) { TradingRewards.create(existing?.tradingRewards, parser, tradingRewardsData) @@ -2132,6 +2183,7 @@ data class Account( return Account( balances, stakingBalances, + stakingDelegations, subaccounts, groupedSubaccounts, tradingRewards, diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/processor/wallet/account/AccountProcessor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/processor/wallet/account/AccountProcessor.kt index 8bd017a8e..81c7af5c6 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/processor/wallet/account/AccountProcessor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/processor/wallet/account/AccountProcessor.kt @@ -809,8 +809,9 @@ private class V4AccountDelegationsProcessor(parser: ParserProtocol) : BaseProces return if (payload != null) { val modified = mutableMapOf() for (itemPayload in payload) { - val delegation = parser.asNativeMap(itemPayload) - val balance = parser.asNativeMap(delegation?.get("balance")) + val item = parser.asNativeMap(itemPayload) + val balance = parser.asNativeMap(item?.get("balance")) + if (balance != null) { val denom = parser.asString(balance["denom"]) if (denom != null) { @@ -842,6 +843,33 @@ private class V4AccountDelegationsProcessor(parser: ParserProtocol) : BaseProces null } } + + fun receivedDelegations( + existing: Map?, + payload: List?, + ): List? { + return if (payload != null) { + val modified = mutableListOf() + for (itemPayload in payload) { + val item = parser.asNativeMap(itemPayload) + val validator = parser.asString(parser.value(item, "delegation.validatorAddress")) + val amount = parser.asDecimal(parser.value(item, "balance.amount")) + val denom = parser.asString(parser.value(item, "balance.denom")) + if (validator != null && amount != null) { + modified.add( + mapOf( + "validator" to validator, + "amount" to amount, + "denom" to denom, + ), + ) + } + } + return modified + } else { + null + } + } } private class V4AccountTradingRewardsProcessor(parser: ParserProtocol) : BaseProcessor(parser) { @@ -914,8 +942,10 @@ internal class V4AccountProcessor(parser: ParserProtocol) : BaseProcessor(parser ): Map? { val modified = existing?.mutable() ?: mutableMapOf() val delegations = parser.asNativeMap(parser.value(existing, "stakingBalances")) - val modifiedDelegations = delegationsProcessor.received(delegations, payload) - modified.safeSet("stakingBalances", modifiedDelegations) + val modifiedStakingBalance = delegationsProcessor.received(delegations, payload) + modified.safeSet("stakingBalances", modifiedStakingBalance) + val modifiedDelegations = delegationsProcessor.receivedDelegations(delegations, payload) + modified.safeSet("stakingDelegations", modifiedDelegations) return modified } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt index e0cd84253..c97b0b406 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt @@ -1175,6 +1175,7 @@ open class TradingStateMachine( Account( account.balances, account.stakingBalances, + account.stakingDelegations, subaccounts, groupedSubaccounts, account.tradingRewards,