From 1a00641bc9dfa512611a61f774592263a79bacb3 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 20 Mar 2024 15:24:14 -0400 Subject: [PATCH] - Remove disconnectedChain - Rely on setting Network Config from wagmi's useChainId - Wllow network switcher when not connected --- .../menus/AccountDisplay/MenuItemNetwork.tsx | 16 +++++--------- .../ui/modals/ForkProposalTemplateModal.tsx | 18 ++++++++++------ src/hooks/DAO/loaders/useFractalNode.ts | 15 +++++-------- src/hooks/DAO/useSearchDao.ts | 21 ++++--------------- src/pages/DAOController.tsx | 8 ++++--- src/pages/HomePage.tsx | 7 +++---- .../NetworkConfig/NetworkConfigProvider.tsx | 17 +++++---------- 7 files changed, 39 insertions(+), 63 deletions(-) diff --git a/src/components/ui/menus/AccountDisplay/MenuItemNetwork.tsx b/src/components/ui/menus/AccountDisplay/MenuItemNetwork.tsx index 90ea5cb844..bff751f812 100644 --- a/src/components/ui/menus/AccountDisplay/MenuItemNetwork.tsx +++ b/src/components/ui/menus/AccountDisplay/MenuItemNetwork.tsx @@ -1,6 +1,6 @@ import { Box, Flex, Select, Text } from '@chakra-ui/react'; import { useTranslation } from 'react-i18next'; -import { useSwitchChain, useAccount } from 'wagmi'; +import { useSwitchChain } from 'wagmi'; import { supportedChains, useNetworkConfig, @@ -12,14 +12,8 @@ import { export function MenuItemNetwork() { const { t } = useTranslation('menu'); const { chainId } = useNetworkConfig(); - const { isConnected } = useAccount(); const { switchChain } = useSwitchChain(); - // TODO: Allow switching chains even when account is not connected - if (!isConnected) { - return null; - } - return ( - {supportedChains.map(chain => ( + {supportedChains.map(supportedChain => ( ))} diff --git a/src/components/ui/modals/ForkProposalTemplateModal.tsx b/src/components/ui/modals/ForkProposalTemplateModal.tsx index 33ccdf447a..fb253bdde8 100644 --- a/src/components/ui/modals/ForkProposalTemplateModal.tsx +++ b/src/components/ui/modals/ForkProposalTemplateModal.tsx @@ -2,14 +2,13 @@ import { Box, Button, Divider } from '@chakra-ui/react'; import { ChangeEventHandler, useState, useCallback, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; -import { useAccount } from 'wagmi'; import { DAO_ROUTES } from '../../../constants/routes'; import useSubmitProposal from '../../../hooks/DAO/proposal/useSubmitProposal'; import { useIsSafe } from '../../../hooks/safe/useIsSafe'; import { validateAddress } from '../../../hooks/schemas/common/useValidationAddress'; import useSignerOrProvider from '../../../hooks/utils/useSignerOrProvider'; import { useFractal } from '../../../providers/App/AppProvider'; -import { disconnectedChain } from '../../../providers/NetworkConfig/NetworkConfigProvider'; +import { useNetworkConfig } from '../../../providers/NetworkConfig/NetworkConfigProvider'; import { ProposalTemplate } from '../../../types/createProposalTemplate'; import { InputComponent } from '../forms/InputComponent'; @@ -31,7 +30,7 @@ export default function ForkProposalTemplateModal({ const { t } = useTranslation('proposalTemplate'); const navigate = useNavigate(); const signerOrProvider = useSignerOrProvider(); - const { chain } = useAccount(); + const network = useNetworkConfig(); const { node: { proposalTemplatesHash }, } = useFractal(); @@ -50,7 +49,6 @@ export default function ForkProposalTemplateModal({ return false; } - const chainName = chain ? chain.name : disconnectedChain.name; const { validation: { address, isValidAddress }, } = await validateAddress({ address: inputValue, signerOrProvider }); @@ -67,13 +65,21 @@ export default function ForkProposalTemplateModal({ return false; } } else { - setError(t('errorFailedSearch', { ns: 'dashboard', chain: chainName })); + setError(t('errorFailedSearch', { ns: 'dashboard', chain: network.name })); return false; } } return isValidAddress; - }, [getCanUserCreateProposal, isSafe, t, inputValue, chain, isSafeLoading, signerOrProvider]); + }, [ + getCanUserCreateProposal, + inputValue, + isSafe, + isSafeLoading, + network.name, + signerOrProvider, + t, + ]); const handleSubmit = () => { navigate( diff --git a/src/hooks/DAO/loaders/useFractalNode.ts b/src/hooks/DAO/loaders/useFractalNode.ts index e50f5d1865..248bb2e5f2 100644 --- a/src/hooks/DAO/loaders/useFractalNode.ts +++ b/src/hooks/DAO/loaders/useFractalNode.ts @@ -1,15 +1,11 @@ import { useQuery } from '@apollo/client'; import { utils } from 'ethers'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { useAccount } from 'wagmi'; import { DAOQueryDocument, DAOQueryQuery } from '../../../../.graphclient'; import { useFractal } from '../../../providers/App/AppProvider'; import { useSafeAPI } from '../../../providers/App/hooks/useSafeAPI'; import { NodeAction } from '../../../providers/App/node/action'; -import { - disconnectedChain, - useNetworkConfig, -} from '../../../providers/NetworkConfig/NetworkConfigProvider'; +import { useNetworkConfig } from '../../../providers/NetworkConfig/NetworkConfigProvider'; import { Node } from '../../../types'; import { mapChildNodes } from '../../../utils/hierarchy'; import { useAsyncRetry } from '../../utils/useAsyncRetry'; @@ -127,18 +123,17 @@ export const useFractalNode = ({ daoAddress }: { daoAddress?: string }) => { [action, safeAPI, lookupModules, fetchSafeInfo, requestWithRetries], ); - const { chain } = useAccount(); - const chainId = chain ? chain.id : disconnectedChain.id; + const network = useNetworkConfig(); useEffect(() => { - if (daoAddress && chainId + daoAddress !== currentValidSafe.current) { + if (daoAddress && network.chainId + daoAddress !== currentValidSafe.current) { setNodeLoading(true); - setDAO(chainId, daoAddress); + setDAO(network.chainId, daoAddress); } if (!daoAddress) { currentValidSafe.current = undefined; setNodeLoading(false); } - }, [daoAddress, setDAO, currentValidSafe, chainId]); + }, [daoAddress, setDAO, currentValidSafe, network.chainId]); return { nodeLoading, errorLoading }; }; diff --git a/src/hooks/DAO/useSearchDao.ts b/src/hooks/DAO/useSearchDao.ts index 716912493a..10dcc32164 100644 --- a/src/hooks/DAO/useSearchDao.ts +++ b/src/hooks/DAO/useSearchDao.ts @@ -1,7 +1,6 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useAccount } from 'wagmi'; -import { disconnectedChain } from '../../providers/NetworkConfig/NetworkConfigProvider'; +import { useNetworkConfig } from '../../providers/NetworkConfig/NetworkConfigProvider'; import { useIsSafe } from '../safe/useIsSafe'; import useAddress from '../utils/useAddress'; @@ -13,7 +12,7 @@ export const useSearchDao = () => { const { address, isValidAddress, isAddressLoading } = useAddress(searchString); const { isSafe, isSafeLoading } = useIsSafe(address); const { t } = useTranslation('dashboard'); - const { chain } = useAccount(); + const network = useNetworkConfig(); useEffect(() => { setIsLoading(isAddressLoading === true || isSafeLoading === true); @@ -29,24 +28,12 @@ export const useSearchDao = () => { setErrorMessage(''); } else { if (isValidAddress) { - setErrorMessage( - t('errorFailedSearch', { chain: chain ? chain.name : disconnectedChain.name }), - ); + setErrorMessage(t('errorFailedSearch', { chain: network.name })); } else { setErrorMessage(t('errorInvalidSearch')); } } - }, [ - address, - isValidAddress, - searchString, - isSafe, - t, - isLoading, - errorMessage, - chain?.name, - chain, - ]); + }, [isLoading, isSafe, isValidAddress, network.name, searchString, t]); return { errorMessage, diff --git a/src/pages/DAOController.tsx b/src/pages/DAOController.tsx index af214199e0..f8006eeaca 100644 --- a/src/pages/DAOController.tsx +++ b/src/pages/DAOController.tsx @@ -8,13 +8,14 @@ import useDAOController from '../hooks/DAO/useDAOController'; import useDAOMetadata from '../hooks/DAO/useDAOMetadata'; import { useFractal } from '../providers/App/AppProvider'; import { - disconnectedChain, supportedChains, + useNetworkConfig, } from '../providers/NetworkConfig/NetworkConfigProvider'; function InvalidSafe() { - const { chain } = useAccount(); + const network = useNetworkConfig(); const { t } = useTranslation('common'); + return (
{t('errorSentryFallbackTitle')} - {t('invalidSafe1', { chain: chain ? chain.name : disconnectedChain.name })} + {t('invalidSafe1', { chain: network.name })} {t('invalidSafe2')} @@ -38,6 +39,7 @@ function InvalidSafe() { function InvalidChain() { const { t } = useTranslation(['common', 'menu']); const supportedChainNames = supportedChains.map(c => c.name).join(', '); + return (
diff --git a/src/providers/NetworkConfig/NetworkConfigProvider.tsx b/src/providers/NetworkConfig/NetworkConfigProvider.tsx index 0f3fa9fc23..904786c795 100644 --- a/src/providers/NetworkConfig/NetworkConfigProvider.tsx +++ b/src/providers/NetworkConfig/NetworkConfigProvider.tsx @@ -1,6 +1,5 @@ import { Context, createContext, ReactNode, useContext, useEffect, useState } from 'react'; -import { Chain } from 'viem'; -import { useAccount } from 'wagmi'; +import { useChainId } from 'wagmi'; import { NetworkConfig } from '../../types/network'; import { isProd } from '../../utils'; import { sepoliaConfig, mainnetConfig } from './networks'; @@ -16,8 +15,6 @@ export const supportedChains: NetworkConfig[] = isProd() ? [mainnetConfig, sepoliaConfig] : [sepoliaConfig, mainnetConfig, polygonConfig]; -export const disconnectedChain: Chain = supportedChains[0].wagmiChain; - const getNetworkConfig = (chainId: number) => { const foundChain = supportedChains.find(chain => chain.chainId === chainId); if (foundChain) { @@ -32,16 +29,12 @@ const getNetworkConfig = (chainId: number) => { }; export function NetworkConfigProvider({ children }: { children: ReactNode }) { - const { chain } = useAccount(); - const [config, setConfig] = useState( - getNetworkConfig(chain?.id || disconnectedChain.id), - ); + const chainId = useChainId(); + const [config, setConfig] = useState(getNetworkConfig(chainId)); useEffect(() => { - if (chain) { - setConfig(getNetworkConfig(chain?.id)); - } - }, [chain]); + setConfig(getNetworkConfig(chainId)); + }, [chainId]); return {children}; }