diff --git a/src/App.tsx b/src/App.tsx
index b3295ce..9c2f7b8 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -9,6 +9,7 @@ import { WagmiProvider } from 'wagmi';
import { queryClient } from '@api/client';
import { Alert } from '@components/Alert';
+import { SquidHeightProvider } from '@hooks/useSquidNetworkHeightHooks';
import { wagmiConfig } from '@network/config';
import { AppRoutes } from './AppRoutes';
@@ -33,10 +34,12 @@ function App() {
}}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
>
-
-
-
-
+
+
+
+
+
+
diff --git a/src/api/contracts/claim.ts b/src/api/contracts/claim.ts
index b5db77e..2cff9a9 100644
--- a/src/api/contracts/claim.ts
+++ b/src/api/contracts/claim.ts
@@ -7,7 +7,7 @@ import { useWriteContract, useClient } from 'wagmi';
import { REWARD_TREASURY_CONTRACT_ABI } from '@api/contracts/reaward-treasury.abi';
import { VESTING_CONTRACT_ABI } from '@api/contracts/vesting.abi';
import { AccountType, SourceWallet } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount.ts';
import { useContracts } from '@network/useContracts.ts';
@@ -67,7 +67,7 @@ function useClaimFromVestingContract() {
export function useClaim() {
const client = useClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
diff --git a/src/api/contracts/gateway-registration/useRegisterGateway.ts b/src/api/contracts/gateway-registration/useRegisterGateway.ts
index e1e5462..24a89ab 100644
--- a/src/api/contracts/gateway-registration/useRegisterGateway.ts
+++ b/src/api/contracts/gateway-registration/useRegisterGateway.ts
@@ -6,7 +6,7 @@ import { encodeFunctionData } from 'viem';
import { usePublicClient, useWriteContract } from 'wagmi';
import { AccountType } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -82,7 +82,7 @@ export function useRegisterGateway() {
const [error, setError] = useState(null);
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const registerGatewayFromWallet = useRegisterGatewayFromWallet();
const registerGatewayFromVestingContract = useRegisterGatewayFromVestingContract();
diff --git a/src/api/contracts/gateway-registration/useStakeGateway.ts b/src/api/contracts/gateway-registration/useStakeGateway.ts
index c719f3e..e80d8c5 100644
--- a/src/api/contracts/gateway-registration/useStakeGateway.ts
+++ b/src/api/contracts/gateway-registration/useStakeGateway.ts
@@ -5,7 +5,7 @@ import { encodeFunctionData } from 'viem';
import { usePublicClient, useWriteContract } from 'wagmi';
import { AccountType, SourceWallet } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -105,7 +105,7 @@ function useStakeFromVestingContract() {
export function useStakeGateway() {
const client = usePublicClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
diff --git a/src/api/contracts/gateway-registration/useUnregisterGateway.ts b/src/api/contracts/gateway-registration/useUnregisterGateway.ts
index 30e4391..4549036 100644
--- a/src/api/contracts/gateway-registration/useUnregisterGateway.ts
+++ b/src/api/contracts/gateway-registration/useUnregisterGateway.ts
@@ -7,7 +7,7 @@ import { useWriteContract, usePublicClient } from 'wagmi';
import { AccountType } from '@api/subsquid-network-squid';
import { BlockchainGateway } from '@api/subsquid-network-squid/gateways-graphql';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -78,7 +78,7 @@ export function useUnregisterGateway() {
const [error, setError] = useState(null);
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const unregisterGatewayFromWallet = useUnregisterGatewayFromWallet();
const unregisterGatewayFromVestingContract = useUnregisterGatewayFromVestingContract();
diff --git a/src/api/contracts/gateway-registration/useUnstakeGateway.ts b/src/api/contracts/gateway-registration/useUnstakeGateway.ts
index a6adb16..d08aba5 100644
--- a/src/api/contracts/gateway-registration/useUnstakeGateway.ts
+++ b/src/api/contracts/gateway-registration/useUnstakeGateway.ts
@@ -4,7 +4,7 @@ import { encodeFunctionData } from 'viem';
import { useWriteContract, usePublicClient } from 'wagmi';
import { AccountType, GatewayStakeFragmentFragment } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -65,7 +65,7 @@ function useUnstakeFromVestingContract() {
export function useUnstakeGateway() {
const client = usePublicClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
diff --git a/src/api/contracts/staking.ts b/src/api/contracts/staking.ts
index e5f7aab..de69206 100644
--- a/src/api/contracts/staking.ts
+++ b/src/api/contracts/staking.ts
@@ -16,7 +16,7 @@ import {
import { useApproveSqd } from '@api/contracts/sqd';
import { VESTING_CONTRACT_ABI } from '@api/contracts/vesting.abi';
import { AccountType, Worker, SourceWallet } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -104,7 +104,7 @@ function useDepositFromVestingContract() {
export function useWorkerDelegate() {
const client = useClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
@@ -195,7 +195,7 @@ function useUndelegateFromVestingContract() {
export function useWorkerUndelegate() {
const client = usePublicClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
@@ -238,7 +238,7 @@ export function useWorkerUndelegate() {
export function useCapedStake({ workerId }: { workerId?: string }) {
const contracts = useContracts();
- const { currentHeight, isLoading: isHeightLoading } = useSquidNetworkHeightHooks();
+ const { currentHeight, isLoading: isHeightLoading } = useSquidNetworkHeight();
const { data, isLoading } = useReadContract({
address: contracts.SOFT_CAP,
diff --git a/src/api/contracts/vesting.ts b/src/api/contracts/vesting.ts
index 415a611..cefb60f 100644
--- a/src/api/contracts/vesting.ts
+++ b/src/api/contracts/vesting.ts
@@ -5,7 +5,7 @@ import { erc20Abi, MulticallResponse } from 'viem';
import { waitForTransactionReceipt } from 'viem/actions';
import { useReadContracts, useWriteContract, useClient } from 'wagmi';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useContracts } from '@network/useContracts';
import { errorMessage, WriteContractRes } from './utils';
@@ -13,7 +13,7 @@ import { VESTING_CONTRACT_ABI } from './vesting.abi';
export function useVestingContracts({ addresses }: { addresses: `0x${string}`[] }) {
const contracts = useContracts();
- const { currentHeight, isLoading: isSquidHeightLoading } = useSquidNetworkHeightHooks();
+ const { currentHeight, isLoading: isSquidHeightLoading } = useSquidNetworkHeight();
const { data, isLoading } = useReadContracts({
contracts: addresses.flatMap(address => {
@@ -119,7 +119,7 @@ function unwrapResult(result?: MulticallResponse): T | undefined {
export function useVestingContractRelease() {
const client = useClient();
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
const { SQD } = useContracts();
diff --git a/src/api/contracts/worker-registration/useRegisterWorker.ts b/src/api/contracts/worker-registration/useRegisterWorker.ts
index 06d44b1..457bae0 100644
--- a/src/api/contracts/worker-registration/useRegisterWorker.ts
+++ b/src/api/contracts/worker-registration/useRegisterWorker.ts
@@ -9,7 +9,7 @@ import { useWriteContract, usePublicClient, useClient } from 'wagmi';
import { useApproveSqd } from '@api/contracts/sqd';
import { VESTING_CONTRACT_ABI } from '@api/contracts/vesting.abi';
import { AccountType, SourceWallet } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -120,7 +120,7 @@ export function useRegisterWorker() {
const [error, setError] = useState(null);
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const registerWorkerContract = useRegisterFromWallet();
const registerVestingContract = useRegisterWorkerFromVestingContract();
diff --git a/src/api/contracts/worker-registration/useUnregisterWorker.ts b/src/api/contracts/worker-registration/useUnregisterWorker.ts
index adda864..bea5a0a 100644
--- a/src/api/contracts/worker-registration/useUnregisterWorker.ts
+++ b/src/api/contracts/worker-registration/useUnregisterWorker.ts
@@ -8,7 +8,7 @@ import { useWriteContract, useClient } from 'wagmi';
import { VESTING_CONTRACT_ABI } from '@api/contracts/vesting.abi';
import { AccountType } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -76,7 +76,7 @@ export function useUnregisterWorker() {
const client = useClient();
const { address } = useAccount();
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [error, setError] = useState(null);
const unregisterWorkerFromWallet = useUnregisterWorkerFromWallet();
diff --git a/src/api/contracts/worker-registration/useUpdateWorker.ts b/src/api/contracts/worker-registration/useUpdateWorker.ts
index 8e63707..5f3581f 100644
--- a/src/api/contracts/worker-registration/useUpdateWorker.ts
+++ b/src/api/contracts/worker-registration/useUpdateWorker.ts
@@ -7,7 +7,7 @@ import { waitForTransactionReceipt } from 'viem/actions';
import { useWriteContract, useClient } from 'wagmi';
import { AccountType } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -79,7 +79,7 @@ export function useUpdateWorker() {
const [error, setError] = useState(null);
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const updateWorkerFromWallet = useUpdateWorkerFromWallet();
const updateWorkerFromVestingContract = useUpdateWorkerFromVestingContract();
diff --git a/src/api/contracts/worker-registration/useWithdrawWorker.ts b/src/api/contracts/worker-registration/useWithdrawWorker.ts
index fed6b80..c72ac25 100644
--- a/src/api/contracts/worker-registration/useWithdrawWorker.ts
+++ b/src/api/contracts/worker-registration/useWithdrawWorker.ts
@@ -9,7 +9,7 @@ import { useWriteContract, useClient } from 'wagmi';
import { VESTING_CONTRACT_ABI } from '@api/contracts/vesting.abi';
import { UnregisterWorkerRequest } from '@api/contracts/worker-registration/useUnregisterWorker';
import { AccountType } from '@api/subsquid-network-squid';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks.ts';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
import { useAccount } from '@network/useAccount';
import { useContracts } from '@network/useContracts.ts';
@@ -69,7 +69,7 @@ export function useWithdrawWorker() {
const client = useClient();
const { address } = useAccount();
const [isLoading, setLoading] = useState(false);
- const { setWaitHeight } = useSquidNetworkHeightHooks();
+ const { setWaitHeight } = useSquidNetworkHeight();
const [error, setError] = useState(null);
const withdrawWorkerFromWallet = useWithdrawWorkerFromWallet();
diff --git a/src/hooks/useSquidNetworkHeightHooks.ts b/src/hooks/useSquidNetworkHeightHooks.tsx
similarity index 53%
rename from src/hooks/useSquidNetworkHeightHooks.ts
rename to src/hooks/useSquidNetworkHeightHooks.tsx
index 1a26ec8..978056c 100644
--- a/src/hooks/useSquidNetworkHeightHooks.ts
+++ b/src/hooks/useSquidNetworkHeightHooks.tsx
@@ -1,15 +1,49 @@
-import { useEffect, useMemo } from 'react';
+import {
+ createContext,
+ PropsWithChildren,
+ useCallback,
+ useContext,
+ useEffect,
+ useMemo,
+} from 'react';
import { logger } from '@logger';
import { useQueryClient } from '@tanstack/react-query';
import { max, partition } from 'lodash-es';
+import { useBlockNumber } from 'wagmi';
import { useSquidDataSource, useSquidNetworkHeightQuery } from '@api/subsquid-network-squid';
import { localStorageStringSerializer, useLocalStorageState } from '@hooks/useLocalStorageState';
type HeightHook = { height: number; invalidateQueries: unknown[] };
-export function useSquidNetworkHeightHooks() {
+const SquidHeightContext = createContext<{
+ currentHeight: number;
+ waitHeight: number;
+ heightHooks: HeightHook[];
+ isLoading: boolean;
+ setWaitHeight: (height: bigint | string, invalidateQueries?: unknown[]) => void;
+}>({
+ currentHeight: 0,
+ waitHeight: 0,
+ isLoading: false,
+ heightHooks: [],
+ setWaitHeight: () => {},
+});
+
+export function useSquidNetworkHeight() {
+ const { isLoading, currentHeight, waitHeight, setWaitHeight } = useContext(SquidHeightContext);
+
+ return {
+ isLoading,
+ isWaiting: currentHeight < waitHeight,
+ currentHeight,
+ waitHeight,
+ setWaitHeight,
+ };
+}
+
+export function SquidHeightProvider({ children }: PropsWithChildren) {
const queryClient = useQueryClient();
const dataSource = useSquidDataSource();
const [heightHooksRaw, setHeightHooksRaw] = useLocalStorageState('squid_height_hooks', {
@@ -30,28 +64,14 @@ export function useSquidNetworkHeightHooks() {
const heightHooks: HeightHook[] = useMemo(() => {
try {
return JSON.parse(heightHooksRaw);
- } catch (e: any) {
- logger.error(`Cant parse json form squid_height_hooks: ${e.message}`);
+ } catch (e: unknown) {
+ logger.error(
+ `Cant parse json form squid_height_hooks: ${e instanceof Error ? e.message : e}`,
+ );
return [];
}
}, [heightHooksRaw]);
- const maxWaitedHook = useMemo(() => {
- return max(heightHooks.map(h => h.height)) || 0;
- }, [heightHooks]);
-
- const setWaitHeight = useMemo(() => {
- return (height: bigint | string, invalidateQueries: unknown[] = []) => {
- heightHooks.push({
- height: Number(height),
- invalidateQueries: invalidateQueries,
- });
- heightHooks.splice(0, heightHooks.length - 10);
-
- setHeightHooksRaw(JSON.stringify(heightHooks));
- };
- }, [heightHooks, setHeightHooksRaw]);
-
useEffect(() => {
const [notReady, ready] = partition(heightHooks, hook => hook.height > currentHeight);
if (!ready.length) return;
@@ -69,11 +89,43 @@ export function useSquidNetworkHeightHooks() {
});
}, [currentHeight, heightHooks, queryClient, setHeightHooksRaw]);
- return {
- isLoading,
- isWaiting: heightHooks.length > 0,
- waitHeight: maxWaitedHook,
- currentHeight: currentHeight ? String(currentHeight) : '0',
- setWaitHeight,
- };
+ const setWaitHeight = useCallback(
+ (height: bigint | string, invalidateQueries: unknown[] = []) => {
+ heightHooks.push({
+ height: Number(height),
+ invalidateQueries: invalidateQueries,
+ });
+ heightHooks.splice(0, heightHooks.length - 10);
+
+ setHeightHooksRaw(JSON.stringify(heightHooks));
+ },
+ [heightHooks, setHeightHooksRaw],
+ );
+
+ const maxWaitHeight = useMemo(() => {
+ return max(heightHooks.map(h => h.height)) || 0;
+ }, [heightHooks]);
+
+ const { data: chainHeight } = useBlockNumber();
+ useEffect(() => {
+ if (isLoading) return;
+
+ if (chainHeight && BigInt(currentHeight) < chainHeight && maxWaitHeight < chainHeight) {
+ setWaitHeight(chainHeight);
+ }
+ }, [chainHeight, currentHeight, heightHooks, isLoading, maxWaitHeight, setWaitHeight]);
+
+ return (
+
+ {children}
+
+ );
}
diff --git a/src/layouts/NetworkLayout/NetworkLayout.tsx b/src/layouts/NetworkLayout/NetworkLayout.tsx
index 38a1960..f6ece59 100644
--- a/src/layouts/NetworkLayout/NetworkLayout.tsx
+++ b/src/layouts/NetworkLayout/NetworkLayout.tsx
@@ -14,12 +14,11 @@ import {
import { alpha } from '@mui/system/colorManipulator';
import classnames from 'classnames';
import { Outlet } from 'react-router-dom';
-import { useDisconnect, useWalletClient, useBlockNumber } from 'wagmi';
+import { useDisconnect, useWalletClient } from 'wagmi';
import { Logo } from '@components/Logo';
// import { NetworkSwitcher } from '@components/NetworkSwitcher';
import { TopBanner, useBannerHeight } from '@components/TopBanner';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks';
import { MenuIcon } from '@icons/MenuIcon';
import { useAccount } from '@network/useAccount';
import { getChainId, getSubsquidNetwork } from '@network/useSubsquidNetwork';
@@ -269,14 +268,6 @@ export const NetworkLayout = ({
const { disconnect } = useDisconnect();
const network = getSubsquidNetwork();
- const { data: chainHeight } = useBlockNumber();
- const {
- currentHeight: squidHeight,
- waitHeight: waitSquidHeight,
- setWaitHeight,
- isLoading,
- } = useSquidNetworkHeightHooks();
-
useEffect(() => {
if (!isConnected || walletClient.isLoading) return;
if (chain?.id === getChainId(network)) return;
@@ -284,13 +275,6 @@ export const NetworkLayout = ({
disconnect();
}, [isConnected, chain, disconnect, walletClient, network]);
- useEffect(() => {
- if (isLoading) return;
- if (chainHeight && BigInt(squidHeight) < chainHeight && waitSquidHeight < chainHeight) {
- setWaitHeight(chainHeight);
- }
- }, [chainHeight, isLoading, setWaitHeight, squidHeight, waitSquidHeight]);
-
const centeredSx = {
alignSelf: stretchContent ? 'stretch' : 'flex-start',
};
diff --git a/src/layouts/NetworkLayout/SyncSquidSnackbar.tsx b/src/layouts/NetworkLayout/SyncSquidSnackbar.tsx
index b9d1ec5..bba1a08 100644
--- a/src/layouts/NetworkLayout/SyncSquidSnackbar.tsx
+++ b/src/layouts/NetworkLayout/SyncSquidSnackbar.tsx
@@ -2,10 +2,10 @@ import React from 'react';
import { Box, CircularProgress, Paper, Stack } from '@mui/material';
-import { useSquidNetworkHeightHooks } from '@hooks/useSquidNetworkHeightHooks';
+import { useSquidNetworkHeight } from '@hooks/useSquidNetworkHeightHooks';
export const SyncSquidSnackbar = () => {
- const { isWaiting, waitHeight, currentHeight } = useSquidNetworkHeightHooks();
+ const { isWaiting, waitHeight, currentHeight } = useSquidNetworkHeight();
if (!isWaiting) return null;