diff --git a/.changeset/strange-carrots-wonder.md b/.changeset/strange-carrots-wonder.md new file mode 100644 index 00000000..0572ce24 --- /dev/null +++ b/.changeset/strange-carrots-wonder.md @@ -0,0 +1,5 @@ +--- +'@web3-ui/hooks': minor +--- + +[hooks] `` now exposes a `cacheProvider` prop to allow persistence with Web3Modal. diff --git a/packages/hooks/src/Provider.tsx b/packages/hooks/src/Provider.tsx index 7ac3be53..c9f7adce 100644 --- a/packages/hooks/src/Provider.tsx +++ b/packages/hooks/src/Provider.tsx @@ -1,3 +1,4 @@ +import { useEffect, useRef } from 'react'; import { JsonRpcSigner } from '@ethersproject/providers'; import WalletConnectProvider from '@walletconnect/web3-provider'; import { ethers } from 'ethers'; @@ -53,6 +54,11 @@ export interface ProviderProps { * @type string */ rpcUrl?: string; + /** + * @dev To persist the cacheProvider functionality from web3modal + * @type boolean + */ + cacheProvider?: boolean; } /** @@ -61,6 +67,7 @@ export interface ProviderProps { * @param network The network you want to connect to. * @param infuraId Your Infura project ID. This is required if you want to support WalletConnect. * @param extraWalletProviders An array of extra Wallet Providers you want to support. + * @param cacheProvider boolean flag to persist provider */ export const Provider: React.FC = ({ children, @@ -68,8 +75,9 @@ export const Provider: React.FC = ({ infuraId, extraWalletProviders = [], rpcUrl = '', + cacheProvider = false, }) => { - const [web3Modal, setWeb3Modal] = useState(); + const web3Modal = useRef(); const [signer, setSigner] = useState(); const [error, setError] = useState(); const [provider, setProvider] = @@ -97,15 +105,9 @@ export const Provider: React.FC = ({ }; const connectWallet = useCallback(async () => { + if (!web3Modal.current) return; try { - const web3Modal = new Web3Modal({ - providerOptions: Object.assign( - defaulProviderOptions, - ...extraWalletProviders - ), - }); - setWeb3Modal(web3Modal); - const connection = await web3Modal.connect(); + const connection = await web3Modal.current.connect(); const provider = new ethers.providers.Web3Provider(connection); setProvider(provider); const chainId = await provider @@ -133,7 +135,7 @@ export const Provider: React.FC = ({ connection.on('accountsChanged', async (accounts: string[]) => { if (accounts.length === 0) { // The user has disconnected their account from Metamask - web3Modal?.clearCachedProvider(); + web3Modal.current?.clearCachedProvider(); disconnectWallet(); return; } @@ -151,16 +153,16 @@ export const Provider: React.FC = ({ }); connection.on('disconnect', async () => { - web3Modal?.clearCachedProvider(); + web3Modal.current?.clearCachedProvider(); disconnectWallet(); }); } catch (err: any) { - setError(err?.message || err.toString()); + setError(err?.message || err?.toString() || 'An error occurred'); } }, [network, correctNetwork, infuraId, extraWalletProviders]); const disconnectWallet = useCallback(() => { - web3Modal?.clearCachedProvider(); + web3Modal.current?.clearCachedProvider(); setSigner(null); setUserAddress(null); setConnected(false); @@ -195,6 +197,20 @@ export const Provider: React.FC = ({ ] ); + useEffect(() => { + web3Modal.current = new Web3Modal({ + cacheProvider, + providerOptions: Object.assign( + defaulProviderOptions, + ...extraWalletProviders + ), + }); + + if (web3Modal.current.cachedProvider) { + connectWallet(); + } + }, []); + return ( {children} ); diff --git a/packages/hooks/src/stories/UseContract.stories.tsx b/packages/hooks/src/stories/UseContract.stories.tsx index 52fb9e60..afcf8dce 100644 --- a/packages/hooks/src/stories/UseContract.stories.tsx +++ b/packages/hooks/src/stories/UseContract.stories.tsx @@ -141,7 +141,7 @@ const Default = () => { }; storiesOf('Hooks/useWriteContract', module).add('Default', () => ( - + ));