From eda4c772774532abb7b34155d242e0222f4033db Mon Sep 17 00:00:00 2001 From: Burnt Nerve Date: Mon, 21 Oct 2024 16:04:48 -0500 Subject: [PATCH] Added initial batch claiming work --- .../staking/components/modals/rewards.tsx | 63 ++++++++++++++----- .../staking/components/validators-table.tsx | 2 + src/features/staking/lib/core/tx.ts | 39 +++++++----- 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/features/staking/components/modals/rewards.tsx b/src/features/staking/components/modals/rewards.tsx index b9e7213..5b7a2cc 100644 --- a/src/features/staking/components/modals/rewards.tsx +++ b/src/features/staking/components/modals/rewards.tsx @@ -1,4 +1,6 @@ +import type { MsgWithdrawDelegatorRewardEncodeObject } from "@cosmjs/stargate"; import BigNumber from "bignumber.js"; +import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; import { memo, useEffect, useRef, useState } from "react"; import { toast } from "react-toastify"; @@ -12,7 +14,7 @@ import { fetchUserDataAction } from "../../context/actions"; import { useStaking } from "../../context/hooks"; import { setModalOpened } from "../../context/reducer"; import { normaliseCoin } from "../../lib/core/coins"; -import { claimRewards } from "../../lib/core/tx"; +import { claimRewardsBatch } from "../../lib/core/tx"; type Step = "completed" | "loading"; @@ -33,23 +35,56 @@ const claimRewardsLoop = async ( const delegatorAddress = stakingRef.account.bech32Address; - delegations - .reduce(async (promise, delegation) => { - await promise; + // Collect the rewards claims in an array of messages + const rewardClaimMessages = delegations.reduce((messages, delegation) => { + const normalised = normaliseCoin(delegation.rewards); - const normalised = normaliseCoin(delegation.rewards); + if (new BigNumber(normalised.amount).lt(MIN_CLAIMABLE_XION)) { + return messages; + } + + const addresses = { + delegator: delegatorAddress, + validator: delegation.validatorAddress, + }; + + const msg = MsgWithdrawDelegatorReward.fromPartial({ + delegatorAddress: addresses.delegator, + validatorAddress: addresses.validator, + }); + + messages.push({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: msg, + } satisfies MsgWithdrawDelegatorRewardEncodeObject); + + return messages; + }, [] as MsgWithdrawDelegatorRewardEncodeObject[]); + + if (rewardClaimMessages.length === 0) { + toast("No claimable rewards found.", { type: "info" }); + + return; + } + + // delegations + // .reduce(async (promise, delegation) => { + // await promise; + + // const normalised = normaliseCoin(delegation.rewards); - if (new BigNumber(normalised.amount).lt(MIN_CLAIMABLE_XION)) { - return; - } + // if (new BigNumber(normalised.amount).lt(MIN_CLAIMABLE_XION)) { + // return; + // } - const addresses = { - delegator: delegatorAddress, - validator: delegation.validatorAddress, - }; + // const addresses = { + // delegator: delegatorAddress, + // validator: delegation.validatorAddress, + // }; - await claimRewards(addresses, client); - }, Promise.resolve()) + // await claimRewards(addresses, client); + // }, Promise.resolve()) + claimRewardsBatch(rewardClaimMessages, client, delegatorAddress) .then(() => fetchUserDataAction(delegatorAddress, staking)) .then(() => { setStep("completed"); diff --git a/src/features/staking/components/validators-table.tsx b/src/features/staking/components/validators-table.tsx index c475551..f14637c 100644 --- a/src/features/staking/components/validators-table.tsx +++ b/src/features/staking/components/validators-table.tsx @@ -218,6 +218,8 @@ const ValidatorsTable = () => { !staking.state.validators.unbonding || !staking.state.validators.bonded; + console.log({staking}); + const validators = currentTab === "active" ? activeValidators : inactiveValidators; diff --git a/src/features/staking/lib/core/tx.ts b/src/features/staking/lib/core/tx.ts index 50de7bf..64fd860 100644 --- a/src/features/staking/lib/core/tx.ts +++ b/src/features/staking/lib/core/tx.ts @@ -1,28 +1,21 @@ -import type { - Coin, - DeliverTxResponse, - MsgBeginRedelegateEncodeObject, - MsgDelegateEncodeObject, - MsgUndelegateEncodeObject, - MsgWithdrawDelegatorRewardEncodeObject, -} from "@cosmjs/stargate"; +import type { Coin, DeliverTxResponse, MsgBeginRedelegateEncodeObject, MsgDelegateEncodeObject, MsgUndelegateEncodeObject, MsgWithdrawDelegatorRewardEncodeObject } from "@cosmjs/stargate"; import BigNumber from "bignumber.js"; import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; -import { - MsgBeginRedelegate, - MsgCancelUnbondingDelegation, - MsgDelegate, - MsgUndelegate, -} from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { MsgBeginRedelegate, MsgCancelUnbondingDelegation, MsgDelegate, MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; + + import { FAUCET_CONTRACT_ADDRESS } from "@/config"; import { MIN_CLAIMABLE_XION } from "@/constants"; + + import type { Unbonding } from "../../context/state"; import { type AbstraxionSigningClient } from "./client"; import { getUXionCoinFromXion, normaliseCoin } from "./coins"; import { getCosmosFee } from "./fee"; + const getTxCoin = (coin: Coin) => ({ amount: coin.amount, denom: ["UXION", "XION"].includes(coin.denom.toUpperCase()) @@ -198,6 +191,22 @@ export const claimRewards = async ( .catch(handleTxError); }; +export const claimRewardsBatch = async ( + rewardClaimMessages: MsgWithdrawDelegatorRewardEncodeObject[], + client: NonNullable, + delegatorAddress: string, +) => { + const fee = await getCosmosFee({ + address: delegatorAddress, + msgs: rewardClaimMessages, + }); + + return await client + .signAndBroadcast(delegatorAddress, rewardClaimMessages, fee) + .then(getTxVerifier("withdraw_rewards")) + .catch(handleTxError); +}; + export const getCanClaimRewards = (rewards?: Coin) => { if (!rewards) { return false; @@ -309,4 +318,4 @@ export const faucetFunds = async ( return await client .execute(address, FAUCET_CONTRACT_ADDRESS, msg, "auto") .catch(handleTxError); -}; +}; \ No newline at end of file