diff --git a/src/provider/index.ts b/src/provider/index.ts index b54b7b1c..0d16636e 100644 --- a/src/provider/index.ts +++ b/src/provider/index.ts @@ -10,5 +10,4 @@ export * from './use-errors'; export * from './use-debounce'; export * from './use-local-storage'; export * from './use-masa'; -export * from './use-metamask'; export * from './use-network-switch'; diff --git a/src/provider/use-metamask.ts b/src/provider/use-metamask.ts deleted file mode 100644 index e2bb3c04..00000000 --- a/src/provider/use-metamask.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useMasa } from './use-masa'; -import { Maybe } from '@metamask/providers/dist/utils'; -import { useLocalStorage } from './use-local-storage'; -import { MetaMaskInpageProvider } from '@metamask/providers'; -import { providers } from 'ethers'; - -export const getWeb3Provider = (): providers.Web3Provider | undefined => { - if ( - typeof window !== 'undefined' && - typeof window?.ethereum !== 'undefined' - ) { - return new providers.Web3Provider( - window?.ethereum as unknown as providers.ExternalProvider - ); - } - - return; -}; - -export const useMetamask = ({ - disabled, -}: { - disabled?: boolean; -}): { connectMetamask: () => void } => { - const [connectedAccounts, setConnectedAccounts] = useState([]); - const { setSigner, handleLogout, walletAddress, verbose, isLoggedIn } = - useMasa(); - const { localStorageSet, localStorageGet } = useLocalStorage(); - - const metamaskStorageKey = 'masa-react-metamask-connected'; - - // use metamask can only be used inside the scope of masa-react - // otherwise everything from useMasa is undefined - if (Object.keys(useMasa()).length < 1) { - throw new Error( - 'useMetamask() must be used inside the Masa provider scope!' - ); - } - - /** - * Connect to metamask - */ - const connectMetamask = useCallback(async (): Promise => { - let metamaskConnected: boolean = - localStorageGet(metamaskStorageKey) || false; - - if (!disabled && window?.ethereum && !walletAddress) { - let accounts: Maybe; - - try { - accounts = await window?.ethereum?.request({ - method: 'eth_requestAccounts', - }); - - if (verbose) { - console.info({ accounts }); - } - } catch (error) { - if (error instanceof Error) { - console.error('Failed to connect to metamask!', error.message); - } - } - - if (accounts && Array.isArray(accounts)) { - const signer = getWeb3Provider()?.getSigner(); - - if (signer && accounts.length > 0 && setSigner) { - setSigner(signer); - metamaskConnected = true; - localStorageSet(metamaskStorageKey, true); - } else { - console.error('Unable to get signer from metamask'); - } - } else { - console.error('No accounts returned from metamask'); - } - } - - if (verbose) { - console.info({ metamaskConnected }); - } - - return metamaskConnected; - }, [ - disabled, - verbose, - setSigner, - localStorageGet, - localStorageSet, - walletAddress, - ]); - - /** - * Disconnect from metamask - */ - const disconnectMetamask = useCallback(async (): Promise => { - localStorageSet(metamaskStorageKey, false); - - if (isLoggedIn) { - await handleLogout?.(); - } - }, [isLoggedIn, handleLogout, localStorageSet]); - - /** - * try to connect metamask on page load - */ - useEffect(() => { - const connectMetamaskOnPageLoad = async (): Promise => { - const metamaskConnected: boolean | undefined = - localStorageGet(metamaskStorageKey); - - if (!metamaskConnected) { - return; - } - - try { - await connectMetamask(); - } catch (error) { - if (error instanceof Error) { - console.error('Connect failed!', error.message); - } - } - }; - - void connectMetamaskOnPageLoad(); - }, [connectMetamask, localStorageGet]); - - /** - * disconnect metamask on wallet change - */ - useEffect(() => { - const disconnectMetamaskOnWalletChange = async (): Promise => { - if ( - walletAddress && - connectedAccounts.length > 0 && - !connectedAccounts - .map((account: string) => account.toLowerCase()) - .includes(walletAddress.toLowerCase()) - ) { - await disconnectMetamask(); - } - }; - - void disconnectMetamaskOnWalletChange(); - }, [connectedAccounts, disconnectMetamask, walletAddress, setSigner]); - - /** - * wire up metamask event listeners - */ - useEffect(() => { - if (typeof window !== 'undefined') { - /** - * on accounts change - */ - (window.ethereum as unknown as MetaMaskInpageProvider)?.on( - 'accountsChanged', - async (accounts: unknown): Promise => { - const accountsArray = accounts as string[]; - - if (accountsArray.length === 0) { - // no accounts, disconnect metamask - await disconnectMetamask(); - // drop provider - setSigner?.(); - } - - // update accounts - setConnectedAccounts(accountsArray); - } - ); - - /** - * on network / chain changed - */ - (window.ethereum as unknown as MetaMaskInpageProvider)?.on( - 'chainChanged', - () => { - setSigner?.(getWeb3Provider()?.getSigner()); - } - ); - } - }, [setSigner, setConnectedAccounts, disconnectMetamask]); - - return { connectMetamask }; -};