Skip to content

Commit

Permalink
fix: try to fix infinite switch loop
Browse files Browse the repository at this point in the history
  • Loading branch information
belopash committed May 17, 2024
1 parent 88a4723 commit c872b92
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 49 deletions.
22 changes: 3 additions & 19 deletions src/components/NetworkSwitcher/NetworkSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 (
<>
<SwitchButton
fill={color}
onClick={async () => handleAppSwitchAsync(inverseNetworkName(network))}
onClick={async () => switchAndReset(inverseNetworkName(network))}
sx={sx}
>
<SwitchArrowsIcon fill={color} />
Expand Down
4 changes: 2 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@ export function useAppReload({
navigate(to);
}

// root = createRoot(container);
root = createRoot(container);
root.render(<App />);

await hideLoader();
};
}

const root = createRoot(container);
let root = createRoot(container);
root.render(<App />);
// hideLoader(0);
24 changes: 1 addition & 23 deletions src/layouts/NetworkLayout/NetworkLayout.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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';

Expand Down Expand Up @@ -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'));
Expand Down
51 changes: 46 additions & 5 deletions src/network/useSubsquidNetwork.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -16,25 +19,63 @@ function validate(app: NetworkName): NetworkName {
}

export function useSubsquidNetwork() {
const [app, changeApp] = useLocalStorageState<NetworkName>('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<NetworkName>('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 };
}

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;
}

0 comments on commit c872b92

Please sign in to comment.