Skip to content

Commit

Permalink
useExternalStore for account changes!!
Browse files Browse the repository at this point in the history
  • Loading branch information
jonesmac committed Nov 17, 2023
1 parent 96d30c1 commit aa0ba96
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 33 deletions.
6 changes: 5 additions & 1 deletion packages/crypto/src/contexts/Ethers/MetaMask/MetaMask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<PropsWithChildren<Props>> = ({ children, defaultChainId = 1, enabled = true }) => {
const [metamaskConnector] = useState<MetaMaskConnector>(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)

Expand Down
Original file line number Diff line number Diff line change
@@ -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<EthAddress>()

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]
}

0 comments on commit aa0ba96

Please sign in to comment.