1+ import { useEffect , useRef } from 'react' ;
12import { JsonRpcSigner } from '@ethersproject/providers' ;
23import WalletConnectProvider from '@walletconnect/web3-provider' ;
34import { ethers } from 'ethers' ;
@@ -53,6 +54,11 @@ export interface ProviderProps {
5354 * @type string
5455 */
5556 rpcUrl ?: string ;
57+ /**
58+ * @dev To persist the cacheProvider functionality from web3modal
59+ * @type boolean
60+ */
61+ cacheProvider ?: boolean ;
5662}
5763
5864/**
@@ -61,15 +67,17 @@ export interface ProviderProps {
6167 * @param network The network you want to connect to.
6268 * @param infuraId Your Infura project ID. This is required if you want to support WalletConnect.
6369 * @param extraWalletProviders An array of extra Wallet Providers you want to support.
70+ * @param cacheProvider boolean flag to persist provider
6471 */
6572export const Provider : React . FC < ProviderProps > = ( {
6673 children,
6774 network,
6875 infuraId,
6976 extraWalletProviders = [ ] ,
7077 rpcUrl = '' ,
78+ cacheProvider = false ,
7179} ) => {
72- const [ web3Modal , setWeb3Modal ] = useState < Web3Modal > ( ) ;
80+ const web3Modal = useRef < Web3Modal > ( ) ;
7381 const [ signer , setSigner ] = useState < null | JsonRpcSigner > ( ) ;
7482 const [ error , setError ] = useState < string > ( ) ;
7583 const [ provider , setProvider ] =
@@ -97,15 +105,9 @@ export const Provider: React.FC<ProviderProps> = ({
97105 } ;
98106
99107 const connectWallet = useCallback ( async ( ) => {
108+ if ( ! web3Modal . current ) return ;
100109 try {
101- const web3Modal = new Web3Modal ( {
102- providerOptions : Object . assign (
103- defaulProviderOptions ,
104- ...extraWalletProviders
105- ) ,
106- } ) ;
107- setWeb3Modal ( web3Modal ) ;
108- const connection = await web3Modal . connect ( ) ;
110+ const connection = await web3Modal . current . connect ( ) ;
109111 const provider = new ethers . providers . Web3Provider ( connection ) ;
110112 setProvider ( provider ) ;
111113 const chainId = await provider
@@ -133,7 +135,7 @@ export const Provider: React.FC<ProviderProps> = ({
133135 connection . on ( 'accountsChanged' , async ( accounts : string [ ] ) => {
134136 if ( accounts . length === 0 ) {
135137 // The user has disconnected their account from Metamask
136- web3Modal ?. clearCachedProvider ( ) ;
138+ web3Modal . current ?. clearCachedProvider ( ) ;
137139 disconnectWallet ( ) ;
138140 return ;
139141 }
@@ -151,16 +153,16 @@ export const Provider: React.FC<ProviderProps> = ({
151153 } ) ;
152154
153155 connection . on ( 'disconnect' , async ( ) => {
154- web3Modal ?. clearCachedProvider ( ) ;
156+ web3Modal . current ?. clearCachedProvider ( ) ;
155157 disconnectWallet ( ) ;
156158 } ) ;
157159 } catch ( err : any ) {
158- setError ( err ?. message || err . toString ( ) ) ;
160+ setError ( err ?. message || err ? .toString ( ) || 'An error occurred' ) ;
159161 }
160162 } , [ network , correctNetwork , infuraId , extraWalletProviders ] ) ;
161163
162164 const disconnectWallet = useCallback ( ( ) => {
163- web3Modal ?. clearCachedProvider ( ) ;
165+ web3Modal . current ?. clearCachedProvider ( ) ;
164166 setSigner ( null ) ;
165167 setUserAddress ( null ) ;
166168 setConnected ( false ) ;
@@ -195,6 +197,20 @@ export const Provider: React.FC<ProviderProps> = ({
195197 ]
196198 ) ;
197199
200+ useEffect ( ( ) => {
201+ web3Modal . current = new Web3Modal ( {
202+ cacheProvider,
203+ providerOptions : Object . assign (
204+ defaulProviderOptions ,
205+ ...extraWalletProviders
206+ ) ,
207+ } ) ;
208+
209+ if ( web3Modal . current . cachedProvider ) {
210+ connectWallet ( ) ;
211+ }
212+ } , [ ] ) ;
213+
198214 return (
199215 < Web3Context . Provider value = { { ...value } } > { children } </ Web3Context . Provider >
200216 ) ;
0 commit comments