From 4544f7a98130a247193efb8735f438156a58b3d4 Mon Sep 17 00:00:00 2001 From: Hrik Bhowal Date: Mon, 6 Mar 2023 12:36:58 -0500 Subject: [PATCH] eager connect --- client/components/AccountStatusDropdown.tsx | 3 + client/pages/_app.tsx | 2 + client/utils/useEagerConnect.ts | 100 ++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 client/utils/useEagerConnect.ts diff --git a/client/components/AccountStatusDropdown.tsx b/client/components/AccountStatusDropdown.tsx index 83221ee3..bbe76250 100644 --- a/client/components/AccountStatusDropdown.tsx +++ b/client/components/AccountStatusDropdown.tsx @@ -32,6 +32,9 @@ const AccountStatusDropdown = ({ const disconnect = () => { setOpen(false); deactivate(); + // To clear state + delete localStorage.walletconnect; + localStorage.setItem("eagerConnect", "false"); resetWeb3State(); }; diff --git a/client/pages/_app.tsx b/client/pages/_app.tsx index c22dfd84..e2257b2a 100644 --- a/client/pages/_app.tsx +++ b/client/pages/_app.tsx @@ -14,6 +14,7 @@ import { GTM_ID, pageview } from "../lib/gtm"; import { withWeb3Provider } from "hoc"; import { useWeb3React } from "@web3-react/core"; import { useStore } from "utils/store"; +import useEagerConnect from "utils/useEagerConnect"; export function App({ Component, pageProps }) { const router = useRouter(); @@ -33,6 +34,7 @@ export function App({ Component, pageProps }) { if (!account) resetWeb3State(); }, [account]); + useEagerConnect(); useContracts(); useTotalBalances(); useAccountBalances(); diff --git a/client/utils/useEagerConnect.ts b/client/utils/useEagerConnect.ts new file mode 100644 index 00000000..18b58d83 --- /dev/null +++ b/client/utils/useEagerConnect.ts @@ -0,0 +1,100 @@ +import { useWeb3React } from "@web3-react/core"; +import { useEffect, useState } from "react"; +import { + gnosisConnector, + injectedConnector, + ledgerConnector, +} from "./connectors"; +import { useStore } from "./store"; + +function useEagerConnect() { + const { activate, active } = useWeb3React(); + + const [triedEager, setTriedEager] = useState(false); + const [triedSafeMultisig, setTriedSafeMultisig] = useState(false); + const [isSafeMultisig, setIsSafeMultisig] = useState(false); + + // Attempt to use Gnosis Safe Multisig if available + useEffect(() => { + async function attemptSafeConnection() { + if (!process.browser) return; + + const gconnector = gnosisConnector(); + // OK to use Gnosis Safe? + const canUseGnosisSafe = await gconnector?.isSafeApp(); + + try { + await activate(gconnector!, undefined, true); + } catch (error) { + // Outside of Safe context + console.debug(error); + setTriedSafeMultisig(true); + return; + } + + useStore.setState({ connectorName: "Gnosis" }); + + setIsSafeMultisig(true); + setTriedSafeMultisig(true); + } + + attemptSafeConnection(); + }, [process.browser]); // Try this when Safe multisig connector is started + + // Attempt to use injectedConnector connector + useEffect(() => { + async function attemptEagerConnection() { + // Must try Safe multisig before injectedConnector connector, don't do anything + // further if using Safe multisig + if (!triedSafeMultisig || isSafeMultisig) return; + + const eagerConnect = localStorage.getItem("eagerConnect"); + // Local storage request we don't try eager connect + if (eagerConnect === "false") return; + + if (eagerConnect === "MetaMask" || eagerConnect === "true") { + const canUseInjected = + !triedEager && + injectedConnector && + (await injectedConnector.isAuthorized()); + if (!canUseInjected) return; + + try { + await activate(injectedConnector, undefined, true); + } catch (error) { + console.debug(error); + return; + } finally { + setTriedEager(true); + } + + useStore.setState({ connectorName: "Metamask" }); + } else if (eagerConnect === "Ledger") { + try { + await ledgerConnector.activate(); + const ledgerDerivationPath = localStorage.getItem( + "ledgerDerivationPath" + ); + const ledgerAccount = localStorage.getItem("ledgerAccount"); + if (ledgerDerivationPath) { + await ledgerConnector.setPath(ledgerDerivationPath); + } + if (ledgerAccount) { + await ledgerConnector.setAccount(ledgerAccount); + } + await activate(ledgerConnector, undefined, true); + } catch (error) { + console.debug(error); + return; + } finally { + setTriedEager(true); + } + useStore.setState({ connectorName: "Ledger" }); + } + } + attemptEagerConnection(); + }, [triedSafeMultisig]); // Try this only after Safe multisig has been attempted + return triedEager; +} + +export default useEagerConnect;