diff --git a/src/components/NetworkSwitcher/NetworkSwitcher.tsx b/src/components/NetworkSwitcher/NetworkSwitcher.tsx index 8cf2a70..1cd1c2f 100644 --- a/src/components/NetworkSwitcher/NetworkSwitcher.tsx +++ b/src/components/NetworkSwitcher/NetworkSwitcher.tsx @@ -2,10 +2,9 @@ import React from 'react'; import { Button, styled, SxProps } from '@mui/material'; import capitalize from 'lodash-es/capitalize'; -import { useSwitchNetwork } from 'wagmi'; import { SwitchArrowsIcon } from '@icons/SwitchArrowsIcon'; -import { getChainId, NetworkName, useSubsquidNetwork } from '@network/useSubsquidNetwork.ts'; +import { NetworkName, useSubsquidNetwork } from '@network/useSubsquidNetwork.ts'; const inverseNetworkName = (name: string) => name === NetworkName.Mainnet ? NetworkName.Testnet : NetworkName.Mainnet; @@ -27,28 +26,13 @@ export function NetworkSwitcher({ color?: string; hideText?: boolean; }) { - const { network, switchAndReset: changeAndReset } = useSubsquidNetwork(); - const { switchNetworkAsync } = useSwitchNetwork(); - - const handleAppSwitchAsync = async (network: NetworkName) => { - try { - await switchNetworkAsync?.(getChainId(network)); - } catch (e: any) { - if (e.message?.toLowerCase().includes('user rejected the request')) { - return; - } - - throw e; - } - - changeAndReset(network); - }; + const { network, switchAndReset } = useSubsquidNetwork(); return ( <> handleAppSwitchAsync(inverseNetworkName(network))} + onClick={async () => switchAndReset(inverseNetworkName(network))} sx={sx} > diff --git a/src/index.tsx b/src/index.tsx index bda4852..f88ca2e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -119,13 +119,13 @@ export function useAppReload({ navigate(to); } - // root = createRoot(container); + root = createRoot(container); root.render(); await hideLoader(); }; } -const root = createRoot(container); +let root = createRoot(container); root.render(); // hideLoader(0); diff --git a/src/layouts/NetworkLayout/NetworkLayout.tsx b/src/layouts/NetworkLayout/NetworkLayout.tsx index 0ce529b..3960559 100644 --- a/src/layouts/NetworkLayout/NetworkLayout.tsx +++ b/src/layouts/NetworkLayout/NetworkLayout.tsx @@ -1,6 +1,6 @@ import '@rainbow-me/rainbowkit/styles.css'; -import React, { PropsWithChildren, useEffect, useState } from 'react'; +import { PropsWithChildren, useState } from 'react'; import { AppBar as AppBarMaterial, @@ -14,14 +14,11 @@ import { import { alpha } from '@mui/system/colorManipulator'; import classnames from 'classnames'; import { Outlet } from 'react-router-dom'; -import { useDisconnect, useNetwork, useWalletClient } from 'wagmi'; import { Logo } from '@components/Logo'; import { NetworkSwitcher } from '@components/NetworkSwitcher'; import { TopBanner, useBannerHeight } from '@components/TopBanner'; import { MenuIcon } from '@icons/MenuIcon'; -import { useAccount } from '@network/useAccount'; -import { getChainId, getNetworkName, useSubsquidNetwork } from '@network/useSubsquidNetwork'; import { ColorVariant } from '../../theme'; @@ -256,25 +253,6 @@ export const NetworkLayout = ({ }: PropsWithChildren<{ stretchContent?: boolean; }>) => { - const { isConnected } = useAccount(); - const { isLoading } = useWalletClient(); - const { chain } = useNetwork(); - const { disconnect } = useDisconnect(); - const { network, switchAndReset } = useSubsquidNetwork(); - - useEffect(() => { - if (!isConnected || isLoading) return; - - if (chain?.id === getChainId(network)) return; - - if (!chain?.unsupported) { - switchAndReset(getNetworkName(chain?.id)); - return; - } - - disconnect(); - }, [chain, disconnect, isConnected, network, isLoading, switchAndReset]); - const theme = useTheme(); const narrowLg = useMediaQuery(theme.breakpoints.down('lg')); const narrowXs = useMediaQuery(theme.breakpoints.down('xs')); diff --git a/src/network/useSubsquidNetwork.ts b/src/network/useSubsquidNetwork.ts index a77bc3a..f8c2193 100644 --- a/src/network/useSubsquidNetwork.ts +++ b/src/network/useSubsquidNetwork.ts @@ -1,5 +1,8 @@ +import { useCallback, useEffect } from 'react'; + import { useQueryClient } from '@tanstack/react-query'; import useLocalStorageState from 'use-local-storage-state'; +import { useWalletClient, useAccount, useNetwork, useDisconnect, useSwitchNetwork } from 'wagmi'; import { arbitrum, arbitrumSepolia } from 'wagmi/chains'; import { localStorageStringSerializer } from '@hooks/useLocalStorageState.ts'; @@ -16,18 +19,56 @@ function validate(app: NetworkName): NetworkName { } export function useSubsquidNetwork() { - const [app, changeApp] = useLocalStorageState('network', { + const queryClient = useQueryClient(); + const walletClient = useWalletClient(); + const { switchNetworkAsync } = useSwitchNetwork({ throwForSwitchChainNotSupported: true }); + const account = useAccount(); + const { chain } = useNetwork(); + const { disconnect } = useDisconnect(); + const [app, setApp] = useLocalStorageState('network', { serializer: localStorageStringSerializer, defaultValue: defaultApp, + storageSync: false, }); - const queryClient = useQueryClient(); + const changeApp = useCallback( + (network: NetworkName) => { + setApp(network); + queryClient.clear(); + }, + [queryClient, setApp], + ); + + const switchAndReset = async (network: NetworkName) => { + if (account.isConnected) { + try { + await switchNetworkAsync?.(getChainId(network)); + } catch (e: unknown) { + if (e instanceof Error) { + if (e.message.toLowerCase().includes('user rejected the request')) return; + if (e.message.toLowerCase().includes('already pending for origin')) return; + } + + throw e; + } + } - const switchAndReset = (network: NetworkName) => { changeApp(network); - queryClient.clear(); + console.log('switched to ' + network); }; + useEffect(() => { + if (!account.isConnected || walletClient.isLoading) return; + if (chain?.id === getChainId(app)) return; + + if (chain && !chain.unsupported) { + changeApp(getNetworkName(chain.id)); + return; + } + + disconnect(); + }, [account, app, chain, disconnect, walletClient, changeApp]); + return { network: validate(app), switchAndReset }; } @@ -35,6 +76,6 @@ export function getChainId(network: NetworkName) { return network === NetworkName.Mainnet ? arbitrum.id : arbitrumSepolia.id; } -export function getNetworkName(chainId?: number) { +export function getNetworkName(chainId: number) { return chainId === arbitrum.id ? NetworkName.Mainnet : NetworkName.Testnet; }