From f8d666f5a4d5bc1d2d20d524812a2988dc504675 Mon Sep 17 00:00:00 2001 From: evavirseda Date: Wed, 19 Jun 2024 09:30:50 +0200 Subject: [PATCH] feat(wallet-dashboard): hook logic to staking overview (#459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(wallet-dashboard): hook stake logic and add StakeCard component * feat(wallet-dashboard): cleanup * feat(wallet-dasboard): add Stake interface * feat(wallet-dashboard): remove interface and add a type * feat(wallet-dashboard): add hook and updtae type * feat(wallet-dashboard): add props interface * feat(wallet-dashboard): cleanup code * feat(wallet-dashboard):remove headers * apply suggestion and use @iota * bring back List and better than before * feat(wallet-dashboard): remove List component * feat(wallet-dashboard): rename names, update types and rename file * feat(wallet-dashboard): rename constant * feat(wallet-dashboard): add stakedIotaId * feat(wallet-dashboard): remove unnecessary id * feat(wallet-dashboard): remove derbis * feat(wallet-dashboard): remove debris * feat(wallet-dashboard): add total hooks, format util and move hook to different folder * feat(wallet): update components to use new hooks * feat(wallet): cleanup * feat(core):cleanup * feat(explorer): cleanup * feat(wallet-dashboard): undo unnecessary change * feat(apps/core): move to stake folder * feat(wallet-dashboard): rename variables * feat(wallet-dashboard): rename type * feat(wallet-dashboard): fix build --------- Co-authored-by: Marc Espin Co-authored-by: cpl121 <100352899+cpl121@users.noreply.github.com> Co-authored-by: Begoña Álvarez de la Cruz --- .../{ => stake}/useGetDelegatedStake.tsx | 0 .../hooks/stake/useTotalDelegatedRewards.ts | 17 ++++ .../src/hooks/stake/useTotalDelegatedStake.ts | 12 +++ apps/core/src/index.ts | 5 +- .../src/utils/stake/formatDelegatedStake.ts | 27 ++++++ .../src/pages/address-result/TotalStaked.tsx | 28 +++--- .../app/dashboard/staking/page.tsx | 85 +++++++++++-------- .../components/Cards/StakeCard.tsx | 25 ++++++ .../components/Cards/index.ts | 1 + apps/wallet-dashboard/components/List.tsx | 37 -------- .../Popup/Popups/StakeDetailsPopup.tsx | 17 ++-- .../components/Popup/Popups/UnstakePopup.tsx | 21 ++--- apps/wallet-dashboard/components/index.ts | 1 - .../app/pages/home/tokens/TokenIconLink.tsx | 38 ++++----- .../src/ui/app/staking/home/StakedCard.tsx | 13 ++- .../app/staking/validators/ValidatorsCard.tsx | 53 +++++------- 16 files changed, 210 insertions(+), 170 deletions(-) rename apps/core/src/hooks/{ => stake}/useGetDelegatedStake.tsx (100%) create mode 100644 apps/core/src/hooks/stake/useTotalDelegatedRewards.ts create mode 100644 apps/core/src/hooks/stake/useTotalDelegatedStake.ts create mode 100644 apps/core/src/utils/stake/formatDelegatedStake.ts create mode 100644 apps/wallet-dashboard/components/Cards/StakeCard.tsx delete mode 100644 apps/wallet-dashboard/components/List.tsx diff --git a/apps/core/src/hooks/useGetDelegatedStake.tsx b/apps/core/src/hooks/stake/useGetDelegatedStake.tsx similarity index 100% rename from apps/core/src/hooks/useGetDelegatedStake.tsx rename to apps/core/src/hooks/stake/useGetDelegatedStake.tsx diff --git a/apps/core/src/hooks/stake/useTotalDelegatedRewards.ts b/apps/core/src/hooks/stake/useTotalDelegatedRewards.ts new file mode 100644 index 00000000000..f7523c1c191 --- /dev/null +++ b/apps/core/src/hooks/stake/useTotalDelegatedRewards.ts @@ -0,0 +1,17 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useMemo } from 'react'; +import { type ExtendedDelegatedStake } from '../../utils/stake/formatDelegatedStake'; + +export function useTotalDelegatedRewards(delegatedStake: ExtendedDelegatedStake[]) { + return useMemo(() => { + if (!delegatedStake) return 0n; + return delegatedStake.reduce((acc, curr) => { + if (curr.status === 'Active' && curr.estimatedReward) { + return acc + BigInt(curr.estimatedReward); + } + return acc; + }, 0n); + }, [delegatedStake]); +} diff --git a/apps/core/src/hooks/stake/useTotalDelegatedStake.ts b/apps/core/src/hooks/stake/useTotalDelegatedStake.ts new file mode 100644 index 00000000000..25182bc3688 --- /dev/null +++ b/apps/core/src/hooks/stake/useTotalDelegatedStake.ts @@ -0,0 +1,12 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useMemo } from 'react'; +import { type ExtendedDelegatedStake } from '../../utils/stake/formatDelegatedStake'; + +export function useTotalDelegatedStake(delegatedStake: ExtendedDelegatedStake[]) { + return useMemo(() => { + if (!delegatedStake) return 0n; + return delegatedStake.reduce((acc, curr) => acc + BigInt(curr.principal), 0n); + }, [delegatedStake]); +} diff --git a/apps/core/src/index.ts b/apps/core/src/index.ts index fa8d5df3d49..c2521436690 100644 --- a/apps/core/src/index.ts +++ b/apps/core/src/index.ts @@ -36,8 +36,11 @@ export * from './utils/kiosk'; export * from './hooks/useElementDimensions'; export * from './hooks/useIotaCoinData'; export * from './hooks/useLocalStorage'; -export * from './hooks/useGetDelegatedStake'; +export * from './hooks/stake/useGetDelegatedStake'; export * from './hooks/useTokenPrice'; export * from './hooks/useKioskClient'; export * from './components/KioskClientProvider'; +export * from './utils/stake/formatDelegatedStake'; +export * from './hooks/stake/useTotalDelegatedRewards'; +export * from './hooks/stake/useTotalDelegatedStake'; export * from './hooks/useQueryTransactionsByAddress'; diff --git a/apps/core/src/utils/stake/formatDelegatedStake.ts b/apps/core/src/utils/stake/formatDelegatedStake.ts new file mode 100644 index 00000000000..fbdeee85013 --- /dev/null +++ b/apps/core/src/utils/stake/formatDelegatedStake.ts @@ -0,0 +1,27 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { DelegatedStake, StakeObject } from '@iota/iota.js/client'; + +export type ExtendedDelegatedStake = StakeObject & { + validatorAddress: string; + estimatedReward?: string; +}; + +export function formatDelegatedStake( + delegatedStakeData: DelegatedStake[], +): ExtendedDelegatedStake[] { + return delegatedStakeData.flatMap((delegatedStake) => { + return delegatedStake.stakes.map((stake) => { + return { + validatorAddress: delegatedStake.validatorAddress, + estimatedReward: stake.status === 'Active' ? stake.estimatedReward : '', + stakeActiveEpoch: stake.stakeActiveEpoch, + stakeRequestEpoch: stake.stakeRequestEpoch, + status: stake.status, + stakedIotaId: stake.stakedIotaId, + principal: stake.principal, + }; + }); + }); +} diff --git a/apps/explorer/src/pages/address-result/TotalStaked.tsx b/apps/explorer/src/pages/address-result/TotalStaked.tsx index 21704fc9799..b5f4f78e53c 100644 --- a/apps/explorer/src/pages/address-result/TotalStaked.tsx +++ b/apps/explorer/src/pages/address-result/TotalStaked.tsx @@ -2,8 +2,12 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { useFormatCoin, useGetDelegatedStake } from '@iota/core'; -import { useMemo } from 'react'; +import { + formatDelegatedStake, + useFormatCoin, + useGetDelegatedStake, + useTotalDelegatedStake, +} from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota.js/utils'; import { Text, Heading } from '@iota/ui'; import { Iota } from '@iota/icons'; @@ -13,18 +17,14 @@ export function TotalStaked({ address }: { address: string }): JSX.Element | nul address, }); - // Total active stake for all delegations - const totalActivePendingStake = useMemo(() => { - if (!delegatedStake) return 0n; - return delegatedStake.reduce( - (acc, curr) => - curr.stakes.reduce((total, { principal }) => total + BigInt(principal), acc), - 0n, - ); - }, [delegatedStake]); + const delegatedStakes = delegatedStake ? formatDelegatedStake(delegatedStake) : []; + const totalDelegatedStake = useTotalDelegatedStake(delegatedStakes); + const [formattedDelegatedStake, symbol, queryResultStake] = useFormatCoin( + totalDelegatedStake, + IOTA_TYPE_ARG, + ); - const [formatted, symbol] = useFormatCoin(totalActivePendingStake, IOTA_TYPE_ARG); - return totalActivePendingStake ? ( + return totalDelegatedStake ? (
@@ -32,7 +32,7 @@ export function TotalStaked({ address }: { address: string }): JSX.Element | nul Staking - {formatted} {symbol} + {queryResultStake.isPending ? '-' : `${formattedDelegatedStake} ${symbol}`}
diff --git a/apps/wallet-dashboard/app/dashboard/staking/page.tsx b/apps/wallet-dashboard/app/dashboard/staking/page.tsx index 4442bd8da9a..e2959c454ec 100644 --- a/apps/wallet-dashboard/app/dashboard/staking/page.tsx +++ b/apps/wallet-dashboard/app/dashboard/staking/page.tsx @@ -1,31 +1,41 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 + 'use client'; -import { AmountBox, Box, List, NewStakePopup, StakeDetailsPopup, Button } from '@/components'; +import { AmountBox, Box, StakeCard, NewStakePopup, StakeDetailsPopup, Button } from '@/components'; import { usePopups } from '@/hooks'; +import { + ExtendedDelegatedStake, + formatDelegatedStake, + useFormatCoin, + useGetDelegatedStake, + useTotalDelegatedRewards, + useTotalDelegatedStake, +} from '@iota/core'; +import { useCurrentAccount } from '@iota/dapp-kit'; +import { IOTA_TYPE_ARG } from '@iota/iota.js/utils'; function StakingDashboardPage(): JSX.Element { + const account = useCurrentAccount(); const { openPopup, closePopup } = usePopups(); + const { data: delegatedStakeData } = useGetDelegatedStake({ + address: account?.address || '', + }); - const HARCODED_STAKE_DATA = { - title: 'Your Stake', - value: '100 IOTA', - }; - const HARCODED_REWARDS_DATA = { - title: 'Earned', - value: '0.297 IOTA', - }; - const HARCODED_STAKING_LIST_TITLE = 'List of stakes'; - const HARCODED_STAKING_LIST = [ - { id: '0', validator: 'Validator 1', stake: '50 IOTA', rewards: '0.15 IOTA' }, - { id: '1', validator: 'Validator 2', stake: '30 IOTA', rewards: '0.09 IOTA' }, - { id: '2', validator: 'Validator 3', stake: '20 IOTA', rewards: '0.06 IOTA' }, - ]; - - // Use `Stake` when https://github.com/iotaledger/iota/pull/459 gets merged - // @ts-expect-error TODO improve typing here - const viewStakeDetails = (stake) => { + const delegatedStakes = delegatedStakeData ? formatDelegatedStake(delegatedStakeData) : []; + const totalDelegatedStake = useTotalDelegatedStake(delegatedStakes); + const totalDelegatedRewards = useTotalDelegatedRewards(delegatedStakes); + const [formattedDelegatedStake, stakeSymbol, stakeResult] = useFormatCoin( + totalDelegatedStake, + IOTA_TYPE_ARG, + ); + const [formattedDelegatedRewards, rewardsSymbol, rewardsResult] = useFormatCoin( + totalDelegatedRewards, + IOTA_TYPE_ARG, + ); + + const viewStakeDetails = (stake: ExtendedDelegatedStake) => { openPopup(); }; @@ -35,22 +45,29 @@ function StakingDashboardPage(): JSX.Element { return (
+ + + +
+

List of stakes

+ {delegatedStakes?.map((stake) => ( + + ))} +
+
-
- {' '} - - - - - -
); } diff --git a/apps/wallet-dashboard/components/Cards/StakeCard.tsx b/apps/wallet-dashboard/components/Cards/StakeCard.tsx new file mode 100644 index 00000000000..04b70f687d6 --- /dev/null +++ b/apps/wallet-dashboard/components/Cards/StakeCard.tsx @@ -0,0 +1,25 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { Box, Button } from '@/components/index'; +import { ExtendedDelegatedStake } from '@iota/core'; + +interface StakeCardProps { + stake: ExtendedDelegatedStake; + onDetailsClick: (stake: ExtendedDelegatedStake) => void; +} + +function StakeCard({ stake, onDetailsClick }: StakeCardProps): JSX.Element { + return ( + +
Validator: {stake.validatorAddress}
+
Stake: {stake.principal}
+ {stake.status === 'Active' &&

Estimated reward: {stake.estimatedReward}

} +
Status: {stake.status}
+ +
+ ); +} + +export default StakeCard; diff --git a/apps/wallet-dashboard/components/Cards/index.ts b/apps/wallet-dashboard/components/Cards/index.ts index 665e7e0e190..59d8c5dd155 100644 --- a/apps/wallet-dashboard/components/Cards/index.ts +++ b/apps/wallet-dashboard/components/Cards/index.ts @@ -1,4 +1,5 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +export { default as StakeCard } from './StakeCard'; export { default as AssetCard } from './AssetCard'; diff --git a/apps/wallet-dashboard/components/List.tsx b/apps/wallet-dashboard/components/List.tsx deleted file mode 100644 index cfd32ea32ad..00000000000 --- a/apps/wallet-dashboard/components/List.tsx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { Button } from '.'; - -interface ListProps { - data: { id: string; [key: string]: React.ReactNode }[]; - title?: string; - onItemClick?: (item: { id: string; [key: string]: React.ReactNode }) => void; - actionText?: string; -} - -function List({ data, title, onItemClick, actionText }: ListProps): JSX.Element { - return ( -
- {title &&

{title}

} -
    - {data.map((item) => ( -
  • - {Object.entries(item).map(([key, value]) => ( -
    -
    {key}:
    -
    {value}
    -
    - ))} - {onItemClick && ( - - )} -
  • - ))} -
-
- ); -} - -export default List; diff --git a/apps/wallet-dashboard/components/Popup/Popups/StakeDetailsPopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/StakeDetailsPopup.tsx index bdbece7d390..cb5388d652d 100644 --- a/apps/wallet-dashboard/components/Popup/Popups/StakeDetailsPopup.tsx +++ b/apps/wallet-dashboard/components/Popup/Popups/StakeDetailsPopup.tsx @@ -5,14 +5,10 @@ import React from 'react'; import { Button } from '@/components/index'; import { usePopups } from '@/hooks'; import UnstakePopup from './UnstakePopup'; +import { ExtendedDelegatedStake } from '@iota/core'; interface StakeDetailsPopupProps { - stake: { - id: string; - validator: string; - stake: string; - rewards: string; - }; + stake: ExtendedDelegatedStake; } function StakeDetailsPopup({ stake }: StakeDetailsPopupProps): JSX.Element { @@ -28,9 +24,12 @@ function StakeDetailsPopup({ stake }: StakeDetailsPopupProps): JSX.Element { return (
-

{stake.validator}

-

Stake: {stake.stake}

-

Rewards: {stake.rewards}

+

{stake.validatorAddress}

+

Stake: {stake.principal}

+

Stake Active Epoch: {stake.stakeActiveEpoch}

+

Stake Request Epoch: {stake.stakeRequestEpoch}

+ {stake.status === 'Active' &&

Estimated reward: {stake.estimatedReward}

} +

Status: {stake.status}

diff --git a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx index a1bfed4c2b6..6fb7f4f8f61 100644 --- a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx +++ b/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx @@ -3,27 +3,20 @@ import React from 'react'; import { Button } from '@/components'; +import { ExtendedDelegatedStake } from '@iota/core'; interface UnstakePopupProps { - stake: { - id: string; - validator: string; - stake: string; - rewards: string; - }; + stake: ExtendedDelegatedStake; onUnstake: (id: string) => void; } -function UnstakePopup({ - stake: { id, validator, stake, rewards }, - onUnstake, -}: UnstakePopupProps): JSX.Element { +function UnstakePopup({ stake, onUnstake }: UnstakePopupProps): JSX.Element { return (
-

{validator}

-

Stake: {stake}

-

Rewards: {rewards}

- +

{stake.validatorAddress}

+

Stake: {stake.principal}

+ {stake.status === 'Active' &&

Estimated reward: {stake.estimatedReward}

} +
); } diff --git a/apps/wallet-dashboard/components/index.ts b/apps/wallet-dashboard/components/index.ts index 5c82a2d8a89..cbbec6ddbd7 100644 --- a/apps/wallet-dashboard/components/index.ts +++ b/apps/wallet-dashboard/components/index.ts @@ -6,7 +6,6 @@ export { default as Notifications } from './Notifications/Notifications'; export { default as TransactionTile } from './TransactionTile'; export { default as Box } from './Box'; export { default as AmountBox } from './AmountBox'; -export { default as List } from './List'; export { default as Input } from './Input'; export { default as VirtualList } from './VirtualList'; export { default as TransactionIcon } from './TransactionIcon'; diff --git a/apps/wallet/src/ui/app/pages/home/tokens/TokenIconLink.tsx b/apps/wallet/src/ui/app/pages/home/tokens/TokenIconLink.tsx index 7a414f8b429..816559af6d6 100644 --- a/apps/wallet/src/ui/app/pages/home/tokens/TokenIconLink.tsx +++ b/apps/wallet/src/ui/app/pages/home/tokens/TokenIconLink.tsx @@ -9,10 +9,14 @@ import { DELEGATED_STAKES_QUERY_STALE_TIME, } from '_src/shared/constants'; import { Text } from '_src/ui/app/shared/text'; -import { useFormatCoin, useGetDelegatedStake } from '@iota/core'; +import { + formatDelegatedStake, + useFormatCoin, + useGetDelegatedStake, + useTotalDelegatedStake, +} from '@iota/core'; import { WalletActionStake24 } from '@iota/icons'; import { IOTA_TYPE_ARG } from '@iota/iota.js/utils'; -import { useMemo } from 'react'; export function TokenIconLink({ accountAddress, @@ -28,41 +32,37 @@ export function TokenIconLink({ }); // Total active stake for all delegations - const totalActivePendingStake = useMemo(() => { - if (!delegatedStake) return 0n; - return delegatedStake.reduce( - (acc, curr) => - curr.stakes.reduce((total, { principal }) => total + BigInt(principal), acc), - 0n, - ); - }, [delegatedStake]); - - const [formatted, symbol, queryResult] = useFormatCoin(totalActivePendingStake, IOTA_TYPE_ARG); + const delegatedStakes = delegatedStake ? formatDelegatedStake(delegatedStake) : []; + const totalDelegatedStake = useTotalDelegatedStake(delegatedStakes); + const [formattedDelegatedStake, symbol, queryResultStake] = useFormatCoin( + totalDelegatedStake, + IOTA_TYPE_ARG, + ); return ( { ampli.clickedStakeIota({ - isCurrentlyStaking: totalActivePendingStake > 0, + isCurrentlyStaking: totalDelegatedStake > 0, sourceFlow: 'Home page', }); }} - loading={isPending || queryResult.isPending} + loading={isPending || queryResultStake.isPending} before={} - data-testid={`stake-button-${formatted}-${symbol}`} + data-testid={`stake-button-${formattedDelegatedStake}-${symbol}`} >
- {totalActivePendingStake ? 'Currently Staked' : 'Stake and Earn IOTA'} + {totalDelegatedStake ? 'Currently Staked' : 'Stake and Earn IOTA'} - {!!totalActivePendingStake && ( + {!!totalDelegatedStake && ( - {formatted} {symbol} + {formattedDelegatedStake} {symbol} )}
diff --git a/apps/wallet/src/ui/app/staking/home/StakedCard.tsx b/apps/wallet/src/ui/app/staking/home/StakedCard.tsx index 039bfd1189b..1f729700966 100644 --- a/apps/wallet/src/ui/app/staking/home/StakedCard.tsx +++ b/apps/wallet/src/ui/app/staking/home/StakedCard.tsx @@ -6,8 +6,11 @@ import { NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_REDEEMABLE } from '_src/shared/cons import { CountDownTimer } from '_src/ui/app/shared/countdown-timer'; import { Text } from '_src/ui/app/shared/text'; import { IconTooltip } from '_src/ui/app/shared/tooltip'; -import { useFormatCoin, useGetTimeBeforeEpochNumber } from '@iota/core'; -import { type StakeObject } from '@iota/iota.js/client'; +import { + useFormatCoin, + useGetTimeBeforeEpochNumber, + type ExtendedDelegatedStake, +} from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota.js/utils'; import { cva, cx, type VariantProps } from 'class-variance-authority'; import type { ReactNode } from 'react'; @@ -39,10 +42,6 @@ const STATUS_VARIANT = { [StakeState.IN_ACTIVE]: 'inActive', } as const; -export type DelegationObjectWithValidator = Extract & { - validatorAddress: string; -}; - const cardStyle = cva( [ 'group flex no-underline flex-col p-3.75 pr-2 py-3 box-border w-full rounded-2xl border border-solid h-36', @@ -107,7 +106,7 @@ function StakeCardContent({ } interface StakeCardProps { - delegationObject: DelegationObjectWithValidator; + delegationObject: ExtendedDelegatedStake; currentEpoch: number; inactiveValidator?: boolean; } diff --git a/apps/wallet/src/ui/app/staking/validators/ValidatorsCard.tsx b/apps/wallet/src/ui/app/staking/validators/ValidatorsCard.tsx index ea4f6bab264..100679744a2 100644 --- a/apps/wallet/src/ui/app/staking/validators/ValidatorsCard.tsx +++ b/apps/wallet/src/ui/app/staking/validators/ValidatorsCard.tsx @@ -13,21 +13,24 @@ import { DELEGATED_STAKES_QUERY_REFETCH_INTERVAL, DELEGATED_STAKES_QUERY_STALE_TIME, } from '_src/shared/constants'; -import { useGetDelegatedStake } from '@iota/core'; +import { + formatDelegatedStake, + useGetDelegatedStake, + useTotalDelegatedRewards, + useTotalDelegatedStake, +} from '@iota/core'; import { useIotaClientQuery } from '@iota/dapp-kit'; import { Plus12 } from '@iota/icons'; -import type { StakeObject } from '@iota/iota.js/client'; import { useMemo } from 'react'; import { useActiveAddress } from '../../hooks/useActiveAddress'; -import { getAllStakeIota } from '../getAllStakeIota'; import { StakeAmount } from '../home/StakeAmount'; -import { StakeCard, type DelegationObjectWithValidator } from '../home/StakedCard'; +import { StakeCard } from '../home/StakedCard'; export function ValidatorsCard() { const accountAddress = useActiveAddress(); const { - data: delegatedStake, + data: delegatedStakeData, isPending, isError, error, @@ -39,15 +42,13 @@ export function ValidatorsCard() { const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); const activeValidators = system?.activeValidators; + const delegatedStake = delegatedStakeData ? formatDelegatedStake(delegatedStakeData) : []; // Total active stake for all Staked validators - const totalStake = useMemo(() => { - if (!delegatedStake) return 0n; - return getAllStakeIota(delegatedStake); - }, [delegatedStake]); + const totalDelegatedStake = useTotalDelegatedStake(delegatedStake); const delegations = useMemo(() => { - return delegatedStake?.flatMap((delegation) => { + return delegatedStakeData?.flatMap((delegation) => { return delegation.stakes.map((d) => ({ ...d, // flag any inactive validator for the stakeIota object @@ -65,23 +66,11 @@ export function ValidatorsCard() { ({ inactiveValidator }) => inactiveValidator, ); - // Get total rewards for all delegations - const totalEarnTokenReward = useMemo(() => { - if (!delegatedStake || !activeValidators) return 0n; - return ( - delegatedStake.reduce( - (acc, curr) => - curr.stakes.reduce( - (total, { estimatedReward }: StakeObject & { estimatedReward?: string }) => - total + BigInt(estimatedReward || 0), - acc, - ), - 0n, - ) || 0n - ); - }, [delegatedStake, activeValidators]); + // // Get total rewards for all delegations + const delegatedStakes = delegatedStakeData ? formatDelegatedStake(delegatedStakeData) : []; + const totalDelegatedRewards = useTotalDelegatedRewards(delegatedStakes); - const numberOfValidators = delegatedStake?.length || 0; + const numberOfValidators = delegatedStakeData?.length || 0; if (isPending) { return ( @@ -120,9 +109,7 @@ export function ValidatorsCard() { ?.filter(({ inactiveValidator }) => inactiveValidator) .map((delegation) => (
- + @@ -164,9 +151,7 @@ export function ValidatorsCard() { ?.filter(({ inactiveValidator }) => !inactiveValidator) .map((delegation) => (