From 84a0e95c64de96482f631c99fbb3bbda1f029d9f Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Wed, 29 Jan 2025 19:05:18 +0100 Subject: [PATCH 1/3] Streamline switchChain logic --- src/components/Nabla/useSwapForm.tsx | 2 +- src/components/NetworkSelector/index.tsx | 2 +- src/contexts/network.tsx | 18 ++++++++++-------- src/hooks/offramp/useSubmitOfframp.ts | 8 ++------ 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/components/Nabla/useSwapForm.tsx b/src/components/Nabla/useSwapForm.tsx index 02aae44c..47496267 100644 --- a/src/components/Nabla/useSwapForm.tsx +++ b/src/components/Nabla/useSwapForm.tsx @@ -60,7 +60,7 @@ export const useSwapForm = () => { const network = getCaseSensitiveNetwork(initialValues.network); if (network !== selectedNetwork) { - setSelectedNetwork(network); + setSelectedNetwork(network, true); } const initialFromToken = getInputTokenDetails(network, initialValues.from as InputTokenType); diff --git a/src/components/NetworkSelector/index.tsx b/src/components/NetworkSelector/index.tsx index e909d5d3..b7882319 100644 --- a/src/components/NetworkSelector/index.tsx +++ b/src/components/NetworkSelector/index.tsx @@ -91,7 +91,7 @@ export const NetworkSelector = ({ disabled }: { disabled?: boolean }) => { useClickOutside(dropdownRef, () => setIsOpen(false)); const handleNetworkSelect = (network: Networks) => { - setSelectedNetwork(network); + setSelectedNetwork(network, true); setIsOpen(false); }; diff --git a/src/contexts/network.tsx b/src/contexts/network.tsx index 9a4cea0d..c9781a9d 100644 --- a/src/contexts/network.tsx +++ b/src/contexts/network.tsx @@ -10,7 +10,7 @@ import { useSep24Actions } from '../stores/sep24Store'; interface NetworkContextType { walletConnectPolkadotSelectedNetworkId: string; selectedNetwork: Networks; - setSelectedNetwork: (network: Networks) => void; + setSelectedNetwork: (network: Networks, resetState?: boolean) => Promise; networkSelectorDisabled: boolean; setNetworkSelectorDisabled: (disabled: boolean) => void; } @@ -38,21 +38,23 @@ export const NetworkProvider = ({ children }: NetworkProviderProps) => { const { resetOfframpState } = useOfframpActions(); const { cleanup: cleanupSep24Variables } = useSep24Actions(); - const { switchChain } = useSwitchChain(); + const { switchChainAsync } = useSwitchChain(); const setSelectedNetwork = useCallback( - (network: Networks) => { - resetOfframpState(); - cleanupSep24Variables(); + async (network: Networks, resetState: boolean = false) => { + if (resetState) { + resetOfframpState(); + cleanupSep24Variables(); + } setSelectedNetworkState(network); setSelectedNetworkLocalStorage(network); - // Will only switch chain on the EVM conneted wallet case. + // Will only switch chain on the EVM connected wallet case. if (isNetworkEVM(network)) { - switchChain({ chainId: getNetworkId(network) }); + await switchChainAsync({ chainId: getNetworkId(network) }); } }, - [switchChain, setSelectedNetworkLocalStorage, resetOfframpState, cleanupSep24Variables], + [switchChainAsync, setSelectedNetworkLocalStorage, resetOfframpState, cleanupSep24Variables], ); // Only run on first render diff --git a/src/hooks/offramp/useSubmitOfframp.ts b/src/hooks/offramp/useSubmitOfframp.ts index 057b40c4..43be1816 100644 --- a/src/hooks/offramp/useSubmitOfframp.ts +++ b/src/hooks/offramp/useSubmitOfframp.ts @@ -22,7 +22,7 @@ import { useSep24Actions } from '../../stores/sep24Store'; import { showToast, ToastMessage } from '../../helpers/notifications'; export const useSubmitOfframp = () => { - const { selectedNetwork } = useNetwork(); + const { selectedNetwork, setSelectedNetwork } = useNetwork(); const { switchChainAsync, switchChain } = useSwitchChain(); const { trackEvent } = useEventsContext(); const { address } = useVortexAccount(); @@ -48,7 +48,6 @@ export const useSubmitOfframp = () => { } (async () => { - switchChain({ chainId: polygon.id }); setOfframpStarted(true); trackEvent({ @@ -60,10 +59,7 @@ export const useSubmitOfframp = () => { }); try { - // For substrate, we only have AssetHub only now. Thus no need to change. - if (isNetworkEVM(selectedNetwork)) { - await switchChainAsync({ chainId: getNetworkId(selectedNetwork) }); - } + await setSelectedNetwork(selectedNetwork); setOfframpStarted(true); From d97b7b6e7b5a018936ebf87470abe8a635e28a7a Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Wed, 29 Jan 2025 19:09:51 +0100 Subject: [PATCH 2/3] Handle edge case with switchChainAsync never returning --- src/contexts/network.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/contexts/network.tsx b/src/contexts/network.tsx index c9781a9d..a8c66783 100644 --- a/src/contexts/network.tsx +++ b/src/contexts/network.tsx @@ -1,6 +1,6 @@ import { createContext } from 'preact'; import { useContext, useState, useEffect, useCallback } from 'preact/hooks'; -import { useSwitchChain } from 'wagmi'; +import { useAccount, useSwitchChain } from 'wagmi'; import { useLocalStorage, LocalStorageKeys } from '../hooks/useLocalStorage'; import { WALLETCONNECT_ASSETHUB_ID } from '../constants/constants'; import { useOfframpActions } from '../stores/offrampStore'; @@ -39,6 +39,7 @@ export const NetworkProvider = ({ children }: NetworkProviderProps) => { const { resetOfframpState } = useOfframpActions(); const { cleanup: cleanupSep24Variables } = useSep24Actions(); const { switchChainAsync } = useSwitchChain(); + const { chain: connectedEvmChain } = useAccount(); const setSelectedNetwork = useCallback( async (network: Networks, resetState: boolean = false) => { @@ -51,7 +52,11 @@ export const NetworkProvider = ({ children }: NetworkProviderProps) => { // Will only switch chain on the EVM connected wallet case. if (isNetworkEVM(network)) { - await switchChainAsync({ chainId: getNetworkId(network) }); + // Only switch chain if the network is different from the current one + // see https://github.com/wevm/wagmi/issues/3417 + if (!connectedEvmChain || connectedEvmChain.id !== getNetworkId(network)) { + await switchChainAsync({ chainId: getNetworkId(network) }); + } } }, [switchChainAsync, setSelectedNetworkLocalStorage, resetOfframpState, cleanupSep24Variables], From fea313eeabef9ec5431fc64209ff5c8d71f1351c Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Thu, 30 Jan 2025 10:27:36 +0100 Subject: [PATCH 3/3] Fix lint issues --- src/contexts/network.tsx | 6 +++--- src/hooks/offramp/useSubmitOfframp.ts | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/contexts/network.tsx b/src/contexts/network.tsx index a8c66783..d28d012d 100644 --- a/src/contexts/network.tsx +++ b/src/contexts/network.tsx @@ -18,7 +18,7 @@ interface NetworkContextType { const NetworkContext = createContext({ walletConnectPolkadotSelectedNetworkId: WALLETCONNECT_ASSETHUB_ID, selectedNetwork: Networks.AssetHub, - setSelectedNetwork: () => null, + setSelectedNetwork: async () => undefined, networkSelectorDisabled: false, setNetworkSelectorDisabled: () => null, }); @@ -42,7 +42,7 @@ export const NetworkProvider = ({ children }: NetworkProviderProps) => { const { chain: connectedEvmChain } = useAccount(); const setSelectedNetwork = useCallback( - async (network: Networks, resetState: boolean = false) => { + async (network: Networks, resetState = false) => { if (resetState) { resetOfframpState(); cleanupSep24Variables(); @@ -59,7 +59,7 @@ export const NetworkProvider = ({ children }: NetworkProviderProps) => { } } }, - [switchChainAsync, setSelectedNetworkLocalStorage, resetOfframpState, cleanupSep24Variables], + [connectedEvmChain, switchChainAsync, setSelectedNetworkLocalStorage, resetOfframpState, cleanupSep24Variables], ); // Only run on first render diff --git a/src/hooks/offramp/useSubmitOfframp.ts b/src/hooks/offramp/useSubmitOfframp.ts index 43be1816..d5c40f30 100644 --- a/src/hooks/offramp/useSubmitOfframp.ts +++ b/src/hooks/offramp/useSubmitOfframp.ts @@ -1,8 +1,5 @@ import { useCallback } from 'preact/compat'; -import { polygon } from 'wagmi/chains'; -import { useSwitchChain } from 'wagmi'; -import { getNetworkId, isNetworkEVM } from '../../helpers/networks'; import { useVortexAccount } from '../useVortexAccount'; import { useNetwork } from '../../contexts/network'; import { useEventsContext } from '../../contexts/events'; @@ -23,7 +20,6 @@ import { showToast, ToastMessage } from '../../helpers/notifications'; export const useSubmitOfframp = () => { const { selectedNetwork, setSelectedNetwork } = useNetwork(); - const { switchChainAsync, switchChain } = useSwitchChain(); const { trackEvent } = useEventsContext(); const { address } = useVortexAccount(); const { checkAndWaitForSignature, forceRefreshAndWaitForSignature } = useSiweContext(); @@ -138,7 +134,6 @@ export const useSubmitOfframp = () => { offrampStarted, offrampState, setOfframpInitiating, - switchChain, setOfframpStarted, trackEvent, selectedNetwork, @@ -150,7 +145,7 @@ export const useSubmitOfframp = () => { setInitialResponseSEP24, setUrlIntervalSEP24, cleanupSEP24, - switchChainAsync, + setSelectedNetwork, ], ); };