diff --git a/pages/test2.tsx b/pages/test2.tsx index c9256c9843..e607b757f8 100644 --- a/pages/test2.tsx +++ b/pages/test2.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { useQueries } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useAccount } from 'wagmi'; import { PublicKey, @@ -14,23 +14,23 @@ import FailedDonation, { } from '@/components/modals/FailedDonation'; import { getTotalGIVpower } from '@/helpers/givpower'; import { formatWeiHelper } from '@/helpers/number'; -import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; const YourApp = () => { const [failedModalType, setFailedModalType] = useState(); - const { address } = useAccount(); - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), + const queryClient = useQueryClient(); + const { address, chain } = useAccount(); + const subgraphValues = useFetchSubgraphDataForAllChains(); + + const { data } = useQuery({ + queryKey: ['interactedBlockNumber', chain?.id], + queryFn: () => 0, + staleTime: Infinity, }); + console.log('data', data); + // Solana wallet hooks const { publicKey, @@ -126,6 +126,22 @@ const YourApp = () => { Test Button +
+ {data} + + {chain?.id && ( + + )} +
{failedModalType && ( { const { formatMessage } = useIntl(); @@ -53,17 +52,12 @@ export const TabGIVbacksTop = () => { const [showGivBackExplain, setShowGivBackExplain] = useState(false); const [givBackStream, setGivBackStream] = useState(0n); const { givTokenDistroHelper } = useGIVTokenDistroHelper(showHarvestModal); - const { chain, address } = useAccount(); + const { chainId } = useAccount(); const dataChainId = - chain?.id === config.OPTIMISM_NETWORK_NUMBER + chainId === config.OPTIMISM_NETWORK_NUMBER ? config.OPTIMISM_NETWORK_NUMBER : config.GNOSIS_NETWORK_NUMBER; - const values = useQuery({ - queryKey: ['subgraph', dataChainId, address], - queryFn: async () => await fetchSubgraphData(dataChainId, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const values = useSubgraphInfo(dataChainId); const givTokenDistroBalance = useMemo(() => { const sdh = new SubgraphDataHelper(values.data); return sdh.getGIVTokenDistroBalance(); @@ -107,7 +101,7 @@ export const TabGIVbacksTop = () => { actionCb={() => { setShowHarvestModal(true); }} - network={chain?.id} + network={chainId} targetNetworks={[ { networkId: config.GNOSIS_NETWORK_NUMBER, diff --git a/src/components/GIVeconomyPages/GIVpower.tsx b/src/components/GIVeconomyPages/GIVpower.tsx index 9d1720f2cc..26556f949b 100644 --- a/src/components/GIVeconomyPages/GIVpower.tsx +++ b/src/components/GIVeconomyPages/GIVpower.tsx @@ -16,7 +16,6 @@ import Link from 'next/link'; import { useIntl } from 'react-intl'; import { useWeb3Modal } from '@web3modal/wagmi/react'; import { useAccount } from 'wagmi'; -import { useQueries } from '@tanstack/react-query'; import { GIVpowerTopContainer, Title, @@ -61,21 +60,13 @@ import { formatWeiHelper } from '@/helpers/number'; import { getTotalGIVpower } from '@/helpers/givpower'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; export function TabPowerTop() { const { formatMessage } = useIntl(); const { open: openConnectModal } = useWeb3Modal(); const { address } = useAccount(); - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); const givPower = getTotalGIVpower(subgraphValues, address); const givPowerFormatted = formatWeiHelper(givPower.total); const hasZeroGivPower = givPowerFormatted === '0'; diff --git a/src/components/GIVeconomyPages/GIVstream.tsx b/src/components/GIVeconomyPages/GIVstream.tsx index 7b20734b56..1d80656cbf 100644 --- a/src/components/GIVeconomyPages/GIVstream.tsx +++ b/src/components/GIVeconomyPages/GIVstream.tsx @@ -19,7 +19,6 @@ import { } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { Bar, FlowRateRow, @@ -52,7 +51,7 @@ import { GridWrapper, } from './GIVstream.sc'; import { IconWithTooltip } from '../IconWithToolTip'; -import { getHistory, fetchSubgraphData } from '@/services/subgraph.service'; +import { getHistory } from '@/services/subgraph.service'; import { formatWeiHelper } from '@/helpers/number'; import config from '@/configuration'; import { durationToString, shortenAddress } from '@/lib/helpers'; @@ -64,6 +63,7 @@ import { IconGIV } from '../Icons/GIV'; import { givEconomySupportedNetworks } from '@/lib/constants/constants'; import Pagination from '../Pagination'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; export const TabGIVstreamTop = () => { const { formatMessage } = useIntl(); @@ -71,15 +71,8 @@ export const TabGIVstreamTop = () => { const [rewardLiquidPart, setRewardLiquidPart] = useState(0n); const [rewardStream, setRewardStream] = useState(0n); const { givTokenDistroHelper } = useGIVTokenDistroHelper(showModal); - const { chain, address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); - - const chainId = chain?.id; + const { chainId } = useAccount(); + const currentValues = useSubgraphInfo(); const sdh = new SubgraphDataHelper(currentValues.data); const { allocatedTokens, claimed, givback } = sdh.getGIVTokenDistroBalance(); @@ -169,7 +162,7 @@ export const TabGIVstreamTop = () => { }; export const TabGIVstreamBottom = () => { - const { chain, address } = useAccount(); + const { chainId } = useAccount(); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); const { formatMessage } = useIntl(); @@ -177,14 +170,8 @@ export const TabGIVstreamBottom = () => { const [remain, setRemain] = useState(''); useState(0n); const [streamAmount, setStreamAmount] = useState(0n); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(); - const chainId = chain?.id; const sdh = new SubgraphDataHelper(currentValues.data); const givTokenDistroBalance = sdh.getGIVTokenDistroBalance(); const increaseSecRef = useRef(null); @@ -388,12 +375,7 @@ export const GIVstreamHistory: FC = () => { const [loading, setLoading] = useState(true); const [page, setPage] = useState(0); - const currentValue = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValue = useSubgraphInfo(); const chainId = chain?.id; const sdh = new SubgraphDataHelper(currentValue.data); diff --git a/src/components/RewardCard.tsx b/src/components/RewardCard.tsx index 45f7a228af..938ac801e6 100644 --- a/src/components/RewardCard.tsx +++ b/src/components/RewardCard.tsx @@ -25,6 +25,7 @@ import { INetworkIdWithChain } from './views/donate/common/common.types'; import { ChainType } from '@/types/config'; import { EVMWrongNetworkSwitchModal } from './modals/WrongNetworkInnerModal'; import { useFetchGIVPrice } from '@/hooks/useGivPrice'; +import { useSubgraphSyncInfo } from '@/hooks/useSubgraphSyncInfo'; interface IRewardCardProps { cardName: string; @@ -63,6 +64,7 @@ export const RewardCard: FC = ({ useState(false); const { data: givPrice } = useFetchGIVPrice(); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); + const subgraphSyncedInfo = useSubgraphSyncInfo(network); useEffect(() => { const price = @@ -132,7 +134,10 @@ export const RewardCard: FC = ({ label={actionLabel} onClick={actionCb} buttonType='primary' - disabled={liquidAmount === 0n} + disabled={ + liquidAmount === 0n || + !subgraphSyncedInfo.isSynced + } /> ) : ( diff --git a/src/components/cards/StakingCards/BaseStakingCard/StakingPoolInfoAndActions.tsx b/src/components/cards/StakingCards/BaseStakingCard/StakingPoolInfoAndActions.tsx index f110242078..c2668d0be8 100644 --- a/src/components/cards/StakingCards/BaseStakingCard/StakingPoolInfoAndActions.tsx +++ b/src/components/cards/StakingCards/BaseStakingCard/StakingPoolInfoAndActions.tsx @@ -54,6 +54,7 @@ import LockModal from '@/components/modals/StakeLock/Lock'; import { WhatIsStreamModal } from '@/components/modals/WhatIsStream'; import { LockupDetailsModal } from '@/components/modals/LockupDetailsModal'; import ExternalLink from '@/components/ExternalLink'; +import { useSubgraphSyncInfo } from '@/hooks/useSubgraphSyncInfo'; interface IStakingPoolInfoAndActionsProps { poolStakingConfig: PoolStakingConfig | RegenPoolStakingConfig; @@ -84,15 +85,16 @@ export const StakingPoolInfoAndActions: FC = ({ const [showWhatIsGIVstreamModal, setShowWhatIsGIVstreamModal] = useState(false); + const { formatMessage } = useIntl(); + const { setChainInfo } = useFarms(); + const router = useRouter(); + const subgraphSyncedInfo = useSubgraphSyncInfo(poolStakingConfig.network); const hold = showAPRModal || showStakeModal || showUnStakeModal || showHarvestModal || showLockModal; - const { formatMessage } = useIntl(); - const { setChainInfo } = useFarms(); - const router = useRouter(); const { apr, notStakedAmount: userNotStakedAmount, @@ -354,7 +356,12 @@ export const StakingPoolInfoAndActions: FC = ({ )} setShowHarvestModal(true)} label={formatMessage({ id: 'label.harvest_rewards', @@ -363,7 +370,10 @@ export const StakingPoolInfoAndActions: FC = ({ /> {isGIVpower && ( setShowLockModal(true)} label={ started @@ -386,7 +396,8 @@ export const StakingPoolInfoAndActions: FC = ({ disabled={ isDiscontinued || exploited || - userNotStakedAmount === 0n + userNotStakedAmount === 0n || + !subgraphSyncedInfo.isSynced } onClick={() => setShowStakeModal(true)} /> @@ -404,7 +415,10 @@ export const StakingPoolInfoAndActions: FC = ({ id: 'label.unstake', })} size='small' - disabled={availableStakedToken === 0n} + disabled={ + availableStakedToken === 0n || + !subgraphSyncedInfo.isSynced + } onClick={() => setShowUnStakeModal(true)} /> diff --git a/src/components/cards/StakingCards/GIVpowerCard/GIVpowerCardIntro.tsx b/src/components/cards/StakingCards/GIVpowerCard/GIVpowerCardIntro.tsx index 967bf7c45e..8672405076 100644 --- a/src/components/cards/StakingCards/GIVpowerCard/GIVpowerCardIntro.tsx +++ b/src/components/cards/StakingCards/GIVpowerCard/GIVpowerCardIntro.tsx @@ -14,8 +14,6 @@ import { useState } from 'react'; import { useIntl } from 'react-intl'; import styled from 'styled-components'; import Link from 'next/link'; -import { useQuery } from '@tanstack/react-query'; -import { useAccount } from 'wagmi'; import links from '@/lib/constants/links'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; import Routes from '@/lib/constants/Routes'; @@ -24,7 +22,7 @@ import TotalGIVpowerBox from '@/components/modals/StakeLock/TotalGIVpowerBox'; import { StakeCardState } from '../BaseStakingCard/BaseStakingCard'; import { useStakingPool } from '@/hooks/useStakingPool'; import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; import type { Dispatch, FC, SetStateAction } from 'react'; interface IGIVpowerCardIntro { @@ -42,13 +40,7 @@ const GIVpowerCardIntro: FC = ({ config.EVM_NETWORKS_CONFIG[poolNetwork].GIVPOWER || config.GNOSIS_CONFIG.GIVPOWER, ); - const { chain, address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(); const sdh = new SubgraphDataHelper(currentValues.data); const userGIVLocked = sdh.getUserGIVLockedBalance(); diff --git a/src/components/controller/subgraph.ctrl.tsx b/src/components/controller/subgraph.ctrl.tsx index d4d8300455..991f98597d 100644 --- a/src/components/controller/subgraph.ctrl.tsx +++ b/src/components/controller/subgraph.ctrl.tsx @@ -1,31 +1,18 @@ import React, { useEffect, useRef } from 'react'; import { useAccount } from 'wagmi'; -import { useQueries, useQueryClient } from '@tanstack/react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { Address } from 'viem'; -import config from '@/configuration'; -import { - fetchLatestIndexedBlock, - fetchSubgraphData, -} from '@/services/subgraph.service'; +import { fetchLatestIndexedBlock } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; +import { useInteractedBlockNumber } from '@/hooks/useInteractedBlockNumber'; const SubgraphController: React.FC = () => { const { address } = useAccount(); const queryClient = useQueryClient(); const pollingTimeoutsRef = useRef<{ [key: number]: NodeJS.Timeout }>({}); const refetchedChainsRef = useRef>(new Set()); - - useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address] as [ - string, - number, - Address, - ], - queryFn: async () => await fetchSubgraphData(chain.id, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - enabled: !!address, - })), - }); + useFetchSubgraphDataForAllChains(); + useInteractedBlockNumber(); useEffect(() => { const handleEvent = ( @@ -49,6 +36,10 @@ const SubgraphController: React.FC = () => { // Reset refetchedChainsRef for the current chain ID refetchedChainsRef.current.delete(eventChainId); + queryClient.setQueryData( + ['interactedBlockNumber', eventChainId], + blockNumber, + ); // Ensure any existing timeout is cleared if (pollingTimeoutsRef.current[eventChainId]) { diff --git a/src/components/givfarm/RegenStreamCard.tsx b/src/components/givfarm/RegenStreamCard.tsx index 8af1fe404e..c74c7ee5e2 100644 --- a/src/components/givfarm/RegenStreamCard.tsx +++ b/src/components/givfarm/RegenStreamCard.tsx @@ -20,7 +20,6 @@ import BigNumber from 'bignumber.js'; import styled from 'styled-components'; import { useIntl } from 'react-intl'; import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { durationToString } from '@/lib/helpers'; import { Bar, GsPTooltip } from '@/components/GIVeconomyPages/GIVstream.sc'; import { IconWithTooltip } from '@/components/IconWithToolTip'; @@ -35,9 +34,9 @@ import { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; import { Relative } from '../styled-components/Position'; import { ArchiveAndNetworkCover } from '../ArchiveAndNetworkCover/ArchiveAndNetworkCover'; import { getSubgraphChainId } from '@/helpers/network'; -import { fetchSubgraphData } from '@/services/subgraph.service'; import { useFetchMainnetThirdPartyTokensPrice } from '@/hooks/useFetchMainnetThirdPartyTokensPrice'; import { useFetchGnosisThirdPartyTokensPrice } from '@/hooks/useFetchGnosisThirdPartyTokensPrice'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; interface RegenStreamProps { streamConfig: RegenStreamConfig; @@ -63,13 +62,9 @@ export const RegenStreamCard: FC = ({ streamConfig }) => { const [lockedAmount, setLockedAmount] = useState(0n); const [claimedAmount, setClaimedAmount] = useState(0n); - const { address, chain } = useAccount(); + const { chain } = useAccount(); const subgraphChainId = getSubgraphChainId(streamConfig.network); - const currentValues = useQuery({ - queryKey: ['subgraph', subgraphChainId, address], - queryFn: async () => await fetchSubgraphData(subgraphChainId, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(subgraphChainId); const chainId = chain?.id; const { diff --git a/src/components/menu/RewardButtonWithMenu.tsx b/src/components/menu/RewardButtonWithMenu.tsx index 2acc23fadc..4b2e634a7f 100644 --- a/src/components/menu/RewardButtonWithMenu.tsx +++ b/src/components/menu/RewardButtonWithMenu.tsx @@ -1,7 +1,5 @@ import React, { FC, useEffect, useState } from 'react'; -import { useAccount } from 'wagmi'; import { FlexSpacer } from '@giveth/ui-design-system'; -import { useQuery } from '@tanstack/react-query'; import { MenuAndButtonContainer, BalanceButton, @@ -22,8 +20,7 @@ import { MenuContainer } from './Menu.sc'; import { ItemsProvider } from '@/context/Items.context'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; import { formatWeiHelper } from '@/helpers/number'; -import { fetchSubgraphData } from '@/services/subgraph.service'; -import config from '@/configuration'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; interface IRewardButtonWithMenuProps extends IHeaderButtonProps {} @@ -100,13 +97,7 @@ export const RewardButtonWithMenu: FC = ({ }; const HeaderRewardButton = () => { - const { chain, address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(); const sdh = new SubgraphDataHelper(currentValues.data); const givBalance = sdh.getGIVTokenBalance(); return ( diff --git a/src/components/menu/RewardItems.tsx b/src/components/menu/RewardItems.tsx index 4a379dfb1d..088f0a1bf9 100644 --- a/src/components/menu/RewardItems.tsx +++ b/src/components/menu/RewardItems.tsx @@ -10,7 +10,6 @@ import { useIntl } from 'react-intl'; import Image from 'next/image'; import Link from 'next/link'; import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import config from '@/configuration'; import useGIVTokenDistroHelper from '@/hooks/useGIVTokenDistroHelper'; import { formatWeiHelper } from '@/helpers/number'; @@ -37,7 +36,7 @@ import { setShowSwitchNetworkModal } from '@/features/modal/modal.slice'; import { getChainName } from '@/lib/network'; import { getNetworkConfig } from '@/helpers/givpower'; import { useIsSafeEnvironment } from '@/hooks/useSafeAutoConnect'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; export interface IRewardItemsProps { showWhatIsGIVstreamModal: boolean; @@ -55,17 +54,10 @@ export const RewardItems: FC = ({ const [givStreamLiquidPart, setGIVstreamLiquidPart] = useState(0n); const [flowRateNow, setFlowRateNow] = useState(0n); - const { address, chain } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !!chain, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const { chainId } = useAccount(); + const currentValues = useSubgraphInfo(); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); const dispatch = useAppDispatch(); - - const chainId = chain?.id; const sdh = new SubgraphDataHelper(currentValues.data); const tokenDistroBalance = sdh.getGIVTokenDistroBalance(); diff --git a/src/components/modals/Boost/BoostModal.tsx b/src/components/modals/Boost/BoostModal.tsx index 074f2235a8..26e1e6a24f 100644 --- a/src/components/modals/Boost/BoostModal.tsx +++ b/src/components/modals/Boost/BoostModal.tsx @@ -1,7 +1,6 @@ import { IconRocketInSpace32 } from '@giveth/ui-design-system'; import { FC, useState } from 'react'; import { useIntl } from 'react-intl'; -import { useQueries } from '@tanstack/react-query'; import { useAccount } from 'wagmi'; import { IModal } from '@/types/common'; import { Modal } from '../Modal'; @@ -12,8 +11,7 @@ import { BoostModalContainer } from './BoostModal.sc'; import BoostedInnerModal from './BoostedInnerModal'; import BoostInnerModal from './BoostInnerModal'; import { getTotalGIVpower } from '@/helpers/givpower'; -import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; interface IBoostModalProps extends IModal { projectId: string; @@ -31,15 +29,7 @@ const BoostModal: FC = ({ setShowModal, projectId }) => { const [percentage, setPercentage] = useState(0); const [state, setState] = useState(EBoostModalState.BOOSTING); const { address } = useAccount(); - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); const givPower = getTotalGIVpower(subgraphValues, address); if (givPower.total.isZero()) { diff --git a/src/components/modals/GIVdropHarvestModal.tsx b/src/components/modals/GIVdropHarvestModal.tsx index f0ed5d0db5..617f0693e6 100644 --- a/src/components/modals/GIVdropHarvestModal.tsx +++ b/src/components/modals/GIVdropHarvestModal.tsx @@ -12,7 +12,6 @@ import BigNumber from 'bignumber.js'; import { captureException } from '@sentry/nextjs'; import { useAccount } from 'wagmi'; import { WriteContractReturnType } from 'viem'; -import { useQuery } from '@tanstack/react-query'; import { Modal } from './Modal'; import { ConfirmedInnerModal, @@ -41,8 +40,8 @@ import { IModal } from '@/types/common'; import { useIsSafeEnvironment } from '@/hooks/useSafeAutoConnect'; import { useModalAnimation } from '@/hooks/useModalAnimation'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; -import { fetchSubgraphData } from '@/services/subgraph.service'; import { useFetchGIVPrice } from '@/hooks/useGivPrice'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; enum ClaimState { UNKNOWN, @@ -80,14 +79,9 @@ export const GIVdropHarvestModal: FC = ({ const { isAnimating, closeModal } = useModalAnimation(setShowModal); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); - const { address, chain } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const { address, chainId } = useAccount(); + const currentValues = useSubgraphInfo(); - const chainId = chain?.id; const sdh = new SubgraphDataHelper(currentValues.data); const givTokenDistroBalance = sdh.getGIVTokenDistroBalance(); const { data: givPrice } = useFetchGIVPrice(); diff --git a/src/components/modals/HarvestAll.tsx b/src/components/modals/HarvestAll.tsx index 4853230e28..4ea9f4f0dd 100644 --- a/src/components/modals/HarvestAll.tsx +++ b/src/components/modals/HarvestAll.tsx @@ -252,11 +252,19 @@ export const HarvestAllModal: FC = ({ if (txResponse) { setState(HarvestStates.SUBMITTED); setTxHash(txResponse); - const { status } = await waitForTransaction( + const { status, blockNumber } = await waitForTransaction( txResponse, isSafeEnv, ); - + const event = new CustomEvent('chainEvent', { + detail: { + type: 'success', + chainId: chainId, + blockNumber: blockNumber, + address: address, + }, + }); + window.dispatchEvent(event); setState( status ? HarvestStates.CONFIRMED : HarvestStates.ERROR, ); diff --git a/src/components/modals/StakeLock/LockSlider.tsx b/src/components/modals/StakeLock/LockSlider.tsx index 89fc599b24..d6efc9a4e8 100644 --- a/src/components/modals/StakeLock/LockSlider.tsx +++ b/src/components/modals/StakeLock/LockSlider.tsx @@ -12,12 +12,10 @@ import { import styled from 'styled-components'; import { Dispatch, FC, SetStateAction, useState } from 'react'; import { useIntl } from 'react-intl'; -import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { smallFormatDate } from '@/lib/helpers'; import { getUnlockDate } from '@/helpers/givpower'; import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; import type { IGIVpower } from '@/types/subgraph'; const maxRound = 26; @@ -29,13 +27,7 @@ interface ILockSlider { const LockSlider: FC = ({ round, setRound }) => { const { formatMessage, locale } = useIntl(); const [isChanged, setIsChanged] = useState(false); - const { address } = useAccount(); - const gnosisValues = useQuery({ - queryKey: ['subgraph', config.GNOSIS_NETWORK_NUMBER, address], - queryFn: async () => - await fetchSubgraphData(config.GNOSIS_NETWORK_NUMBER, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const gnosisValues = useSubgraphInfo(config.GNOSIS_NETWORK_NUMBER); const givpowerInfo = gnosisValues.data?.givpowerInfo as IGIVpower; const unlockDate = new Date(getUnlockDate(givpowerInfo, round)); return ( diff --git a/src/components/modals/StakeLock/LockingBrief.tsx b/src/components/modals/StakeLock/LockingBrief.tsx index 9d2161d5bd..cd62724ecf 100644 --- a/src/components/modals/StakeLock/LockingBrief.tsx +++ b/src/components/modals/StakeLock/LockingBrief.tsx @@ -1,12 +1,10 @@ import { brandColors, H5, Flex } from '@giveth/ui-design-system'; import styled from 'styled-components'; -import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { formatWeiHelper } from '@/helpers/number'; import { smallFormatDate } from '@/lib/helpers'; import { getUnlockDate } from '@/helpers/givpower'; import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; import type { FC } from 'react'; import type { IGIVpower } from '@/types/subgraph'; @@ -20,13 +18,7 @@ const LockingBrief: FC = ({ amount, onLocking = false, }) => { - const { address } = useAccount(); - const gnosisValues = useQuery({ - queryKey: ['subgraph', config.GNOSIS_NETWORK_NUMBER, address], - queryFn: async () => - await fetchSubgraphData(config.GNOSIS_NETWORK_NUMBER, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const gnosisValues = useSubgraphInfo(config.GNOSIS_NETWORK_NUMBER); const givpowerInfo = gnosisValues.data?.givpowerInfo as IGIVpower; const unlockDate = new Date(getUnlockDate(givpowerInfo, round)); return ( diff --git a/src/components/modals/StakeLock/TotalGIVpowerBox.tsx b/src/components/modals/StakeLock/TotalGIVpowerBox.tsx index 57eade613b..86893863d0 100644 --- a/src/components/modals/StakeLock/TotalGIVpowerBox.tsx +++ b/src/components/modals/StakeLock/TotalGIVpowerBox.tsx @@ -9,27 +9,17 @@ import styled from 'styled-components'; import { useEffect, useState } from 'react'; import BigNumber from 'bignumber.js'; import { useAccount } from 'wagmi'; -import { useQueries } from '@tanstack/react-query'; import { formatWeiHelper } from '@/helpers/number'; import { WrappedSpinner } from '@/components/Spinner'; import { getTotalGIVpower } from '@/helpers/givpower'; import { getGIVpowerOnChain } from '@/lib/stakingPool'; -import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; const TotalGIVpowerBox = () => { const [totalGIVpower, setTotalGIVpower] = useState(); const { address, chain } = useAccount(); const chainId = chain?.id; - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); useEffect(() => { async function fetchTotalGIVpower() { diff --git a/src/components/views/claim/cards/Govern.tsx b/src/components/views/claim/cards/Govern.tsx index 7fb9ebabc4..78d3f715c0 100644 --- a/src/components/views/claim/cards/Govern.tsx +++ b/src/components/views/claim/cards/Govern.tsx @@ -7,7 +7,6 @@ import { captureException } from '@sentry/nextjs'; import { useIntl } from 'react-intl'; import { formatEther } from 'viem'; import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { APRRow, ArrowButton, @@ -35,7 +34,7 @@ import useGIVTokenDistroHelper from '@/hooks/useGIVTokenDistroHelper'; import { IClaimViewCardProps } from '../Claim.view'; import { WeiPerEther } from '@/lib/constants/constants'; import { InputWithUnit } from '@/components/input/InputWithUnit'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; const GovernCardContainer = styled(Card)` padding-left: 254px; @@ -109,15 +108,9 @@ const GovernCard: FC = ({ index }) => { const [earnEstimate, setEarnEstimate] = useState(0n); const [apr, setApr] = useState(null); - const { address, chain } = useAccount(); - const chainId = chain?.id; + const { chainId } = useAccount(); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); - const gnosisValues = useQuery({ - queryKey: ['subgraph', config.GNOSIS_NETWORK_NUMBER, address], - queryFn: async () => - await fetchSubgraphData(config.GNOSIS_NETWORK_NUMBER, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const gnosisValues = useSubgraphInfo(config.GNOSIS_NETWORK_NUMBER); useEffect(() => { let _stacked = 0; diff --git a/src/components/views/claim/cards/Stake.tsx b/src/components/views/claim/cards/Stake.tsx index 22588e8738..def9267a08 100644 --- a/src/components/views/claim/cards/Stake.tsx +++ b/src/components/views/claim/cards/Stake.tsx @@ -4,8 +4,6 @@ import styled from 'styled-components'; import BigNumber from 'bignumber.js'; import { H2, H5, Lead, Flex } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; -import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { APRRow, ArrowButton, @@ -34,7 +32,7 @@ import { getNowUnixMS } from '@/helpers/time'; import { IClaimViewCardProps } from '../Claim.view'; import { WeiPerEther } from '@/lib/constants/constants'; import { InputWithUnit } from '@/components/input/InputWithUnit'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useSubgraphInfo } from '@/hooks/useSubgraphInfo'; const InvestCardContainer = styled(Card)` &::before { @@ -95,21 +93,9 @@ const InvestCard: FC = ({ index }) => { const [earnEstimate, setEarnEstimate] = useState(0n); const [APR, setAPR] = useState(Zero); - const { address } = useAccount(); const { givTokenDistroHelper } = useGIVTokenDistroHelper(); - const gnosisValues = useQuery({ - queryKey: ['subgraph', config.GNOSIS_NETWORK_NUMBER, address], - queryFn: async () => - await fetchSubgraphData(config.GNOSIS_NETWORK_NUMBER, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); - - const mainnetValues = useQuery({ - queryKey: ['subgraph', config.MAINNET_NETWORK_NUMBER, address], - queryFn: async () => - await fetchSubgraphData(config.MAINNET_NETWORK_NUMBER, address), - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const gnosisValues = useSubgraphInfo(config.GNOSIS_NETWORK_NUMBER); + const mainnetValues = useSubgraphInfo(config.MAINNET_NETWORK_NUMBER); useEffect(() => { if (totalAmount) { diff --git a/src/components/views/userProfile/ProfileOverviewTab.tsx b/src/components/views/userProfile/ProfileOverviewTab.tsx index b6c4e7fb1f..dbd42d7624 100644 --- a/src/components/views/userProfile/ProfileOverviewTab.tsx +++ b/src/components/views/userProfile/ProfileOverviewTab.tsx @@ -17,7 +17,6 @@ import { import { useIntl } from 'react-intl'; import { useAccount } from 'wagmi'; -import { useQueries } from '@tanstack/react-query'; import Routes from '@/lib/constants/Routes'; import { isUserRegistered } from '@/lib/helpers'; import { mediaQueries } from '@/lib/constants/constants'; @@ -36,9 +35,8 @@ import { useProfileContext } from '@/context/profile.context'; import { useIsSafeEnvironment } from '@/hooks/useSafeAutoConnect'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { QFDonorEligibilityCard } from '@/components/views/userProfile/QFDonorEligibilityCard'; -import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; import { getNowUnixMS } from '@/helpers/time'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; interface IBtnProps extends IButtonProps { outline?: boolean; @@ -115,15 +113,7 @@ const ProfileOverviewTab: FC = () => { const { activeQFRound } = useAppSelector(state => state.general); const boostedProjectsCount = userData?.boostedProjectsCount ?? 0; const { address } = useAccount(); - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); const givPower = getTotalGIVpower(subgraphValues, address); const { title, subtitle, buttons } = section; diff --git a/src/components/views/userProfile/boostedTab/EmptyPowerBoosting.tsx b/src/components/views/userProfile/boostedTab/EmptyPowerBoosting.tsx index 62c6266154..37f99a4e85 100644 --- a/src/components/views/userProfile/boostedTab/EmptyPowerBoosting.tsx +++ b/src/components/views/userProfile/boostedTab/EmptyPowerBoosting.tsx @@ -9,26 +9,16 @@ import { useIntl } from 'react-intl'; import Link from 'next/link'; import { FC } from 'react'; import { useAccount } from 'wagmi'; -import { useQueries } from '@tanstack/react-query'; import Routes from '@/lib/constants/Routes'; import { getTotalGIVpower } from '@/helpers/givpower'; -import config from '@/configuration'; -import { fetchSubgraphData } from '@/services/subgraph.service'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; interface IEmptyPowerBoosting { myAccount?: boolean; } export const EmptyPowerBoosting: FC = ({ myAccount }) => { const { address } = useAccount(); - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); const givPower = getTotalGIVpower(subgraphValues, address); const { formatMessage } = useIntl(); diff --git a/src/components/views/userProfile/boostedTab/ProfileBoostedTab.tsx b/src/components/views/userProfile/boostedTab/ProfileBoostedTab.tsx index 35b5d0cdea..ae78aa4e7c 100644 --- a/src/components/views/userProfile/boostedTab/ProfileBoostedTab.tsx +++ b/src/components/views/userProfile/boostedTab/ProfileBoostedTab.tsx @@ -4,7 +4,6 @@ import { captureException } from '@sentry/nextjs'; import { Col, Row } from '@giveth/ui-design-system'; import { useAccount } from 'wagmi'; -import { useQueries } from '@tanstack/react-query'; import { IUserProfileView } from '../UserProfile.view'; import BoostsTable from './BoostsTable'; import { IPowerBoosting } from '@/apollo/types/types'; @@ -29,8 +28,7 @@ import { formatWeiHelper } from '@/helpers/number'; import InlineToast, { EToastType } from '@/components/toasts/InlineToast'; import { useFetchPowerBoostingInfo } from './useFetchPowerBoostingInfo'; import { useProfileContext } from '@/context/profile.context'; -import { fetchSubgraphData } from '@/services/subgraph.service'; -import config from '@/configuration'; +import { useFetchSubgraphDataForAllChains } from '@/hooks/useFetchSubgraphDataForAllChains'; export const ProfileBoostedTab: FC = () => { const { user } = useProfileContext(); @@ -39,15 +37,7 @@ export const ProfileBoostedTab: FC = () => { const { address, chain } = useAccount(); const { userData } = useAppSelector(state => state.user); const boostedProjectsCount = userData?.boostedProjectsCount ?? 0; - const subgraphValues = useQueries({ - queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ - queryKey: ['subgraph', chain.id, address], - queryFn: async () => { - return await fetchSubgraphData(chain.id, address); - }, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - })), - }); + const subgraphValues = useFetchSubgraphDataForAllChains(); const givPower = getTotalGIVpower(subgraphValues, address); const isZeroGivPower = givPower.total.isZero(); const dispatch = useAppDispatch(); diff --git a/src/hooks/useFetchSubgraphDataForAllChains.ts b/src/hooks/useFetchSubgraphDataForAllChains.ts new file mode 100644 index 0000000000..f8acc552cd --- /dev/null +++ b/src/hooks/useFetchSubgraphDataForAllChains.ts @@ -0,0 +1,21 @@ +import { useQueries } from '@tanstack/react-query'; +import { Address } from 'viem'; +import { useAccount } from 'wagmi'; +import config from '@/configuration'; +import { fetchSubgraphData } from '@/services/subgraph.service'; + +export const useFetchSubgraphDataForAllChains = () => { + const { address } = useAccount(); + return useQueries({ + queries: config.CHAINS_WITH_SUBGRAPH.map(chain => ({ + queryKey: ['subgraph', chain.id, address] as [ + string, + number, + Address, + ], + queryFn: async () => await fetchSubgraphData(chain.id, address), + staleTime: config.SUBGRAPH_POLLING_INTERVAL, + enabled: !!address, + })), + }); +}; diff --git a/src/hooks/useGIVTokenDistroHelper.ts b/src/hooks/useGIVTokenDistroHelper.ts index 32f367eddd..a61acd7525 100644 --- a/src/hooks/useGIVTokenDistroHelper.ts +++ b/src/hooks/useGIVTokenDistroHelper.ts @@ -1,11 +1,8 @@ import { useState, useEffect } from 'react'; import { AddressZero } from '@ethersproject/constants'; -import { useQuery } from '@tanstack/react-query'; -import { useAccount } from 'wagmi'; import { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; -import { fetchSubgraphData } from '@/services/subgraph.service'; -import config from '@/configuration'; +import { useSubgraphInfo } from './useSubgraphInfo'; export const defaultTokenDistroHelper = new TokenDistroHelper({ contractAddress: AddressZero, @@ -23,13 +20,7 @@ const useGIVTokenDistroHelper = (hold = false) => { const [givTokenDistroHelper, setGIVTokenDistroHelper] = useState(defaultTokenDistroHelper); const [isLoaded, setIsLoaded] = useState(false); - const { chain, address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', chain?.id, address], - queryFn: async () => await fetchSubgraphData(chain?.id, address), - enabled: !hold, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(); useEffect(() => { const updateHelper = () => { diff --git a/src/hooks/useInteractedBlockNumber.ts b/src/hooks/useInteractedBlockNumber.ts new file mode 100644 index 0000000000..02f4f0c410 --- /dev/null +++ b/src/hooks/useInteractedBlockNumber.ts @@ -0,0 +1,11 @@ +import { useQuery } from '@tanstack/react-query'; +import { useAccount } from 'wagmi'; + +export const useInteractedBlockNumber = (_chainId?: number) => { + const { chainId: accountChainId } = useAccount(); + return useQuery({ + queryKey: ['interactedBlockNumber', _chainId || accountChainId], + queryFn: () => 0, + staleTime: Infinity, + }); +}; diff --git a/src/hooks/useStakingPool.ts b/src/hooks/useStakingPool.ts index 4f7737c74a..e93cf16556 100644 --- a/src/hooks/useStakingPool.ts +++ b/src/hooks/useStakingPool.ts @@ -1,7 +1,5 @@ import { useEffect, useState } from 'react'; -import { useQuery } from '@tanstack/react-query'; -import { useAccount } from 'wagmi'; import { getGivStakingAPR, getLPStakingAPR, @@ -10,8 +8,7 @@ import { import { SimplePoolStakingConfig, StakingType } from '@/types/config'; import { APR, UserStakeInfo } from '@/types/poolInfo'; import { Zero } from '@/helpers/number'; -import { fetchSubgraphData } from '@/services/subgraph.service'; -import config from '@/configuration'; +import { useSubgraphInfo } from './useSubgraphInfo'; export interface IStakeInfo { apr: APR; @@ -30,14 +27,7 @@ export const useStakingPool = ( notStakedAmount: 0n, stakedAmount: 0n, }); - const { address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', poolStakingConfig.network, address], - queryFn: async () => - await fetchSubgraphData(poolStakingConfig.network, address), - enabled: !hold, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(poolStakingConfig.network); useEffect(() => { const { network, type } = poolStakingConfig; diff --git a/src/hooks/useSubgraphInfo.ts b/src/hooks/useSubgraphInfo.ts new file mode 100644 index 0000000000..653b4ed2ab --- /dev/null +++ b/src/hooks/useSubgraphInfo.ts @@ -0,0 +1,15 @@ +import { useQuery } from '@tanstack/react-query'; +import { useAccount } from 'wagmi'; +import config from '@/configuration'; +import { fetchSubgraphData } from '@/services/subgraph.service'; + +export const useSubgraphInfo = (chainId?: number) => { + const { address, chainId: accountChainId } = useAccount(); + const _chainId = chainId || accountChainId; + return useQuery({ + queryKey: ['subgraph', _chainId, address], + queryFn: async () => await fetchSubgraphData(_chainId, address), + enabled: !!_chainId, + staleTime: config.SUBGRAPH_POLLING_INTERVAL, + }); +}; diff --git a/src/hooks/useSubgraphSyncInfo.ts b/src/hooks/useSubgraphSyncInfo.ts new file mode 100644 index 0000000000..b79864f016 --- /dev/null +++ b/src/hooks/useSubgraphSyncInfo.ts @@ -0,0 +1,31 @@ +import { useAccount } from 'wagmi'; +import { useMemo } from 'react'; +import { useInteractedBlockNumber } from './useInteractedBlockNumber'; +import { useSubgraphInfo } from './useSubgraphInfo'; + +export const useSubgraphSyncInfo = (chainId?: number) => { + const { chainId: accountChainId } = useAccount(); + const _chainId = chainId || accountChainId; + const interactedBlockInfo = useInteractedBlockNumber(_chainId); + const subgraphInfo = useSubgraphInfo(); + + const isSynced = useMemo(() => { + if (!subgraphInfo.data?.indexedBlockNumber) return false; + if (interactedBlockInfo.data === undefined) return false; + try { + const indexedBlockNumber = Number( + subgraphInfo.data?.indexedBlockNumber, + ); + const interactedBlockNumber = interactedBlockInfo.data; + return indexedBlockNumber >= interactedBlockNumber; + } catch (error) { + return false; + } + }, [interactedBlockInfo.data, subgraphInfo.data?.indexedBlockNumber]); + + return { + isSynced, + interactedBlockNumber: interactedBlockInfo.data, + indexedBlockNumber: subgraphInfo.data?.indexedBlockNumber, + }; +}; diff --git a/src/hooks/useTokenDistroHelper.ts b/src/hooks/useTokenDistroHelper.ts index 1ad69f15ab..3f786a2897 100644 --- a/src/hooks/useTokenDistroHelper.ts +++ b/src/hooks/useTokenDistroHelper.ts @@ -1,11 +1,8 @@ import { useState, useEffect, useMemo } from 'react'; -import { useAccount } from 'wagmi'; -import { useQuery } from '@tanstack/react-query'; import { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; import { RegenStreamConfig } from '@/types/config'; -import { fetchSubgraphData } from '@/services/subgraph.service'; -import config from '@/configuration'; +import { useSubgraphInfo } from './useSubgraphInfo'; export const useTokenDistroHelper = ( poolNetwork: number, @@ -14,13 +11,7 @@ export const useTokenDistroHelper = ( ) => { const [tokenDistroHelper, setTokenDistroHelper] = useState(); - const { address } = useAccount(); - const currentValues = useQuery({ - queryKey: ['subgraph', poolNetwork, address], - queryFn: async () => await fetchSubgraphData(poolNetwork, address), - enabled: !hold, - staleTime: config.SUBGRAPH_POLLING_INTERVAL, - }); + const currentValues = useSubgraphInfo(poolNetwork); const sdh = useMemo( () => new SubgraphDataHelper(currentValues.data), [currentValues.data], diff --git a/src/lib/subgraph/subgraphDataTransform.ts b/src/lib/subgraph/subgraphDataTransform.ts index 4a29566861..493ba5c415 100644 --- a/src/lib/subgraph/subgraphDataTransform.ts +++ b/src/lib/subgraph/subgraphDataTransform.ts @@ -198,6 +198,10 @@ export const transformUserGIVLocked = (info: any = {}): ITokenBalance => { }; }; +const transformIndexedBlockInfo = (info: any = {}): number => { + return info?.block?.number || 0; +}; + export const transformSubgraphData = (data: any = {}): ISubgraphState => { const result: ISubgraphState = {}; Object.entries(data).forEach(([key, value]) => { @@ -229,6 +233,9 @@ export const transformSubgraphData = (data: any = {}): ISubgraphState => { case key === 'userGIVLocked': result[key] = transformUserGIVLocked(value); break; + case key === '_meta': + result['indexedBlockNumber'] = transformIndexedBlockInfo(value); + break; default: } diff --git a/src/lib/subgraph/subgraphQueryBuilder.ts b/src/lib/subgraph/subgraphQueryBuilder.ts index 9e2ea70c4f..c5ea401093 100644 --- a/src/lib/subgraph/subgraphQueryBuilder.ts +++ b/src/lib/subgraph/subgraphQueryBuilder.ts @@ -13,6 +13,15 @@ export class SubgraphQueryBuilder { `; }; + static getIndexedBlockQuery = (): string => { + return `_meta { + block { + number + } + } + `; + }; + static getBalanceQuery = ( networkConfig: NetworkConfig, userAddress?: string, @@ -233,6 +242,7 @@ export class SubgraphQueryBuilder { const givpowerConfig = networkConfig?.GIVPOWER; return ` { + ${SubgraphQueryBuilder.getIndexedBlockQuery()} ${SubgraphQueryBuilder.getBalanceQuery(networkConfig, userAddress)} ${SubgraphQueryBuilder.generateTokenDistroQueries(networkConfig, userAddress)} ${SubgraphQueryBuilder.generateFarmingQueries(