diff --git a/packages/crypto/src/contexts/Ethers/MetaMask/MetaMask.tsx b/packages/crypto/src/contexts/Ethers/MetaMask/MetaMask.tsx index fa722d62..5cb46bda 100644 --- a/packages/crypto/src/contexts/Ethers/MetaMask/MetaMask.tsx +++ b/packages/crypto/src/contexts/Ethers/MetaMask/MetaMask.tsx @@ -10,10 +10,14 @@ export interface Props { enabled?: boolean } +// TODO - separate out infura provider into new hook +// TODO - make single hook for metamask interaction + export const MetaMaskEthersLoader: React.FC> = ({ children, defaultChainId = 1, enabled = true }) => { const [metamaskConnector] = useState(new MetaMaskConnector()) - const currentAddress = useCurrentAddress(metamaskConnector, enabled) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [currentAddress, additionalAddresses] = useCurrentAddress(metamaskConnector) const chainId = useChainId(metamaskConnector, enabled) diff --git a/packages/crypto/src/contexts/Ethers/MetaMask/hooks/useCurrentAddress.tsx b/packages/crypto/src/contexts/Ethers/MetaMask/hooks/useCurrentAddress.tsx index c2ab8964..8bcc0cac 100644 --- a/packages/crypto/src/contexts/Ethers/MetaMask/hooks/useCurrentAddress.tsx +++ b/packages/crypto/src/contexts/Ethers/MetaMask/hooks/useCurrentAddress.tsx @@ -1,41 +1,31 @@ -import { Listener } from '@ethersproject/providers' import { EthAddress } from '@xylabs/eth-address' -import { useAsyncEffect } from '@xylabs/react-async-effect' -import { useEffect, useState } from 'react' +import { useMemo, useSyncExternalStore } from 'react' import { MetaMaskConnector } from '../../wallets' -export const useCurrentAddress = (metamaskConnector: MetaMaskConnector, enabled?: boolean) => { - const [currentAddress, setCurrentAddress] = useState() - - useAsyncEffect( - // eslint-disable-next-line react-hooks/exhaustive-deps - async () => { - const defaultAddress = await metamaskConnector.currentAddress() - setCurrentAddress((currentAddress) => (currentAddress === undefined && defaultAddress ? defaultAddress : undefined)) - }, - [metamaskConnector], - ) - - // watch for changes - useEffect(() => { - const accountsChangedListener: Listener = (accounts: string[]) => { - // setConnectError(undefined) - if (accounts.length > 0) { - setCurrentAddress(EthAddress.fromString(accounts[0])) - } else { - setCurrentAddress(undefined) - } +export const useCurrentAddressExternal = (metamaskConnector: MetaMaskConnector) => { + const { getSnapShot, subscribe } = useMemo(() => { + return { + getSnapShot: () => metamaskConnector.allowedAddresses, + subscribe: (onStoreChange: () => void) => { + metamaskConnector.onAccountsChanged(onStoreChange) + return () => { + metamaskConnector.removeEIP11193Listener('accountsChanged', onStoreChange) + } + }, } + }, [metamaskConnector]) - if (metamaskConnector) { - metamaskConnector.onAccountsChanged(accountsChangedListener) - } + return useSyncExternalStore(subscribe, getSnapShot) +} - return () => { - metamaskConnector.removeEIP11193Listener('accountsChanged', accountsChangedListener) - } - }, [enabled, metamaskConnector]) +export const useCurrentAddress = (metamaskConnector: MetaMaskConnector): [EthAddress | undefined, string[]] => { + const addresses = useCurrentAddressExternal(metamaskConnector) + + const [currentAddress, additionalAddresses] = useMemo( + () => [EthAddress.fromString(addresses[0]), addresses.slice(0, addresses.length)], + [addresses], + ) - return currentAddress + return [currentAddress, additionalAddresses] }