1
+ import { useEffect , useRef } from 'react' ;
1
2
import { JsonRpcSigner } from '@ethersproject/providers' ;
2
3
import WalletConnectProvider from '@walletconnect/web3-provider' ;
3
4
import { ethers } from 'ethers' ;
@@ -53,6 +54,11 @@ export interface ProviderProps {
53
54
* @type string
54
55
*/
55
56
rpcUrl ?: string ;
57
+ /**
58
+ * @dev To persist the cacheProvider functionality from web3modal
59
+ * @type boolean
60
+ */
61
+ cacheProvider ?: boolean ;
56
62
}
57
63
58
64
/**
@@ -61,15 +67,17 @@ export interface ProviderProps {
61
67
* @param network The network you want to connect to.
62
68
* @param infuraId Your Infura project ID. This is required if you want to support WalletConnect.
63
69
* @param extraWalletProviders An array of extra Wallet Providers you want to support.
70
+ * @param cacheProvider boolean flag to persist provider
64
71
*/
65
72
export const Provider : React . FC < ProviderProps > = ( {
66
73
children,
67
74
network,
68
75
infuraId,
69
76
extraWalletProviders = [ ] ,
70
77
rpcUrl = '' ,
78
+ cacheProvider = false ,
71
79
} ) => {
72
- const [ web3Modal , setWeb3Modal ] = useState < Web3Modal > ( ) ;
80
+ const web3Modal = useRef < Web3Modal > ( ) ;
73
81
const [ signer , setSigner ] = useState < null | JsonRpcSigner > ( ) ;
74
82
const [ error , setError ] = useState < string > ( ) ;
75
83
const [ provider , setProvider ] =
@@ -97,15 +105,9 @@ export const Provider: React.FC<ProviderProps> = ({
97
105
} ;
98
106
99
107
const connectWallet = useCallback ( async ( ) => {
108
+ if ( ! web3Modal . current ) return ;
100
109
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 ( ) ;
109
111
const provider = new ethers . providers . Web3Provider ( connection ) ;
110
112
setProvider ( provider ) ;
111
113
const chainId = await provider
@@ -133,7 +135,7 @@ export const Provider: React.FC<ProviderProps> = ({
133
135
connection . on ( 'accountsChanged' , async ( accounts : string [ ] ) => {
134
136
if ( accounts . length === 0 ) {
135
137
// The user has disconnected their account from Metamask
136
- web3Modal ?. clearCachedProvider ( ) ;
138
+ web3Modal . current ?. clearCachedProvider ( ) ;
137
139
disconnectWallet ( ) ;
138
140
return ;
139
141
}
@@ -151,16 +153,16 @@ export const Provider: React.FC<ProviderProps> = ({
151
153
} ) ;
152
154
153
155
connection . on ( 'disconnect' , async ( ) => {
154
- web3Modal ?. clearCachedProvider ( ) ;
156
+ web3Modal . current ?. clearCachedProvider ( ) ;
155
157
disconnectWallet ( ) ;
156
158
} ) ;
157
159
} catch ( err : any ) {
158
- setError ( err ?. message || err . toString ( ) ) ;
160
+ setError ( err ?. message || err ? .toString ( ) || 'An error occurred' ) ;
159
161
}
160
162
} , [ network , correctNetwork , infuraId , extraWalletProviders ] ) ;
161
163
162
164
const disconnectWallet = useCallback ( ( ) => {
163
- web3Modal ?. clearCachedProvider ( ) ;
165
+ web3Modal . current ?. clearCachedProvider ( ) ;
164
166
setSigner ( null ) ;
165
167
setUserAddress ( null ) ;
166
168
setConnected ( false ) ;
@@ -195,6 +197,20 @@ export const Provider: React.FC<ProviderProps> = ({
195
197
]
196
198
) ;
197
199
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
+
198
214
return (
199
215
< Web3Context . Provider value = { { ...value } } > { children } </ Web3Context . Provider >
200
216
) ;
0 commit comments