1
1
import { JsonRpcSigner } from '@ethersproject/providers/src.ts/json-rpc-provider' ;
2
2
import WalletConnectProvider from '@walletconnect/web3-provider' ;
3
3
import { ethers } from 'ethers' ;
4
- import React from 'react' ;
4
+ import React , { createContext , useCallback , useMemo , useState } from 'react' ;
5
5
import Web3Modal , { IProviderOptions } from 'web3modal' ;
6
6
import { StaticJsonRpcProvider } from '@ethersproject/providers' ;
7
7
import { useReadOnlyProvider } from './hooks' ;
8
8
9
9
export interface Web3ContextType {
10
- connectWallet ?: ( ) => void ;
10
+ connectWallet ?: ( ) => Promise < void > ;
11
11
signer ?: JsonRpcSigner | null ;
12
12
userAddress ?: string | null ;
13
13
disconnectWallet ?: ( ) => void ;
14
+ error ?: string ;
14
15
chainId ?: number | null ;
15
16
connected : boolean ;
16
17
provider ?: ethers . providers . Web3Provider | null ;
@@ -19,7 +20,7 @@ export interface Web3ContextType {
19
20
readOnlyProvider ?: StaticJsonRpcProvider ;
20
21
}
21
22
22
- export const Web3Context = React . createContext < Web3ContextType | undefined > (
23
+ export const Web3Context = createContext < Web3ContextType | undefined > (
23
24
undefined
24
25
) ;
25
26
@@ -68,71 +69,43 @@ export const Provider: React.FC<ProviderProps> = ({
68
69
extraWalletProviders = [ ] ,
69
70
rpcUrl = '' ,
70
71
} ) => {
71
- const [ signer , setSigner ] = React . useState < null | JsonRpcSigner > ( ) ;
72
+ const [ web3Modal , setWeb3Modal ] = useState < Web3Modal > ( ) ;
73
+ const [ signer , setSigner ] = useState < null | JsonRpcSigner > ( ) ;
74
+ const [ error , setError ] = useState < string > ( ) ;
72
75
const [ provider , setProvider ] =
73
- React . useState < ethers . providers . Web3Provider | null > ( ) ;
74
- const [ userAddress , setUserAddress ] = React . useState < null | string > ( ) ;
75
- const [ web3Modal , setWeb3Modal ] = React . useState < Web3Modal > ( ) ;
76
- const [ chainId , setChainId ] = React . useState < number | null > ( ) ;
77
- const [ connected , setConnected ] = React . useState < boolean > ( false ) ;
78
- const [ correctNetwork , setCorrectNetwork ] = React . useState < boolean > ( true ) ;
76
+ useState < ethers . providers . Web3Provider | null > ( ) ;
77
+ const [ userAddress , setUserAddress ] = useState < null | string > ( ) ;
78
+ const [ chainId , setChainId ] = useState < number | null > ( ) ;
79
+ const [ connected , setConnected ] = useState < boolean > ( false ) ;
80
+ const [ correctNetwork , setCorrectNetwork ] = useState < boolean > ( true ) ;
79
81
const readOnlyProvider = useReadOnlyProvider ( rpcUrl ) ;
80
82
81
- const connectWallet = React . useCallback ( async ( ) => {
82
- const defaulProviderOptions = {
83
- walletconnect : {
84
- package : WalletConnectProvider ,
85
- options : {
86
- bridge : 'https://polygon.bridge.walletconnect.org' ,
87
- infuraId,
88
- rpc : {
89
- 1 : `https://mainnet.infura.io/v3/${ infuraId } ` , // mainnet // For more WalletConnect providers: https://docs.walletconnect.org/quick-start/dapps/web3-provider#required
90
- 4 : `https://rinkeby.infura.io/v3/${ infuraId } ` ,
91
- 42 : `https://kovan.infura.io/v3/${ infuraId } ` ,
92
- 100 : 'https://dai.poa.network' , // xDai
93
- } ,
83
+ const defaulProviderOptions = {
84
+ walletconnect : {
85
+ package : WalletConnectProvider ,
86
+ options : {
87
+ bridge : 'https://polygon.bridge.walletconnect.org' ,
88
+ infuraId,
89
+ rpc : {
90
+ 1 : `https://mainnet.infura.io/v3/${ infuraId } ` , // mainnet // For more WalletConnect providers: https://docs.walletconnect.org/quick-start/dapps/web3-provider#required
91
+ 4 : `https://rinkeby.infura.io/v3/${ infuraId } ` ,
92
+ 42 : `https://kovan.infura.io/v3/${ infuraId } ` ,
93
+ 100 : 'https://dai.poa.network' , // xDai
94
94
} ,
95
95
} ,
96
- } ;
97
- const web3Modal = new Web3Modal ( {
98
- providerOptions : Object . assign (
99
- defaulProviderOptions ,
100
- ...extraWalletProviders
101
- ) ,
102
- } ) ;
103
- setWeb3Modal ( web3Modal ) ;
104
- const connection = await web3Modal . connect ( ) ;
105
- const provider = new ethers . providers . Web3Provider ( connection ) ;
106
- setProvider ( provider ) ;
107
- const chainId = await provider
108
- . getNetwork ( )
109
- . then ( ( network ) => network . chainId ) ;
110
- setChainId ( chainId ) ;
111
- setCorrectNetwork ( chainId === network ) ;
112
- const signer = provider . getSigner ( ) ;
113
- setSigner ( signer ) ;
114
- setUserAddress ( await signer . getAddress ( ) ) ;
115
- setConnected ( true ) ;
96
+ } ,
97
+ } ;
116
98
117
- connection . on ( 'chainChanged' , async ( newChainId : string ) => {
118
- const formattedChainId = + newChainId . split ( '0x' ) [ 1 ] ;
119
- setChainId ( formattedChainId ) ;
120
- setCorrectNetwork ( formattedChainId === network ) ;
121
- const provider = new ethers . providers . Web3Provider ( connection ) ;
122
- setProvider ( provider ) ;
123
- const signer = provider . getSigner ( ) ;
124
- setSigner ( signer ) ;
125
- setUserAddress ( await signer . getAddress ( ) ) ;
126
- setConnected ( true ) ;
127
- } ) ;
128
-
129
- connection . on ( 'accountsChanged' , async ( accounts : string [ ] ) => {
130
- if ( accounts . length === 0 ) {
131
- // The user has disconnected their account from Metamask
132
- web3Modal ?. clearCachedProvider ( ) ;
133
- disconnectWallet ( ) ;
134
- return ;
135
- }
99
+ const connectWallet = useCallback ( async ( ) => {
100
+ 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 ( ) ;
136
109
const provider = new ethers . providers . Web3Provider ( connection ) ;
137
110
setProvider ( provider ) ;
138
111
const chainId = await provider
@@ -144,36 +117,63 @@ export const Provider: React.FC<ProviderProps> = ({
144
117
setSigner ( signer ) ;
145
118
setUserAddress ( await signer . getAddress ( ) ) ;
146
119
setConnected ( true ) ;
147
- } ) ;
148
120
149
- connection . on ( 'disconnect' , async ( ) => {
150
- web3Modal ?. clearCachedProvider ( ) ;
151
- disconnectWallet ( ) ;
152
- } ) ;
153
- } , [
154
- Web3Modal ,
155
- web3Modal ,
156
- WalletConnectProvider ,
157
- network ,
158
- infuraId ,
159
- ethers ,
160
- correctNetwork ,
161
- ] ) ;
121
+ connection . on ( 'chainChanged' , async ( newChainId : string ) => {
122
+ const formattedChainId = + newChainId . split ( '0x' ) [ 1 ] ;
123
+ setChainId ( formattedChainId ) ;
124
+ setCorrectNetwork ( formattedChainId === network ) ;
125
+ const provider = new ethers . providers . Web3Provider ( connection ) ;
126
+ setProvider ( provider ) ;
127
+ const signer = provider . getSigner ( ) ;
128
+ setSigner ( signer ) ;
129
+ setUserAddress ( await signer . getAddress ( ) ) ;
130
+ setConnected ( true ) ;
131
+ } ) ;
132
+
133
+ connection . on ( 'accountsChanged' , async ( accounts : string [ ] ) => {
134
+ if ( accounts . length === 0 ) {
135
+ // The user has disconnected their account from Metamask
136
+ web3Modal ?. clearCachedProvider ( ) ;
137
+ disconnectWallet ( ) ;
138
+ return ;
139
+ }
140
+ const provider = new ethers . providers . Web3Provider ( connection ) ;
141
+ setProvider ( provider ) ;
142
+ const chainId = await provider
143
+ . getNetwork ( )
144
+ . then ( ( network ) => network . chainId ) ;
145
+ setChainId ( chainId ) ;
146
+ setCorrectNetwork ( chainId === network ) ;
147
+ const signer = provider . getSigner ( ) ;
148
+ setSigner ( signer ) ;
149
+ setUserAddress ( await signer . getAddress ( ) ) ;
150
+ setConnected ( true ) ;
151
+ } ) ;
152
+
153
+ connection . on ( 'disconnect' , async ( ) => {
154
+ web3Modal ?. clearCachedProvider ( ) ;
155
+ disconnectWallet ( ) ;
156
+ } ) ;
157
+ } catch ( err : any ) {
158
+ setError ( err ?. message || err . toString ( ) ) ;
159
+ }
160
+ } , [ network , correctNetwork , infuraId , extraWalletProviders ] ) ;
162
161
163
- const disconnectWallet = React . useCallback ( ( ) => {
162
+ const disconnectWallet = useCallback ( ( ) => {
164
163
web3Modal ?. clearCachedProvider ( ) ;
165
164
setSigner ( null ) ;
166
165
setUserAddress ( null ) ;
167
166
setConnected ( false ) ;
168
167
} , [ web3Modal ] ) ;
169
168
170
- const value = React . useMemo (
169
+ const value = useMemo (
171
170
( ) => ( {
172
171
connectWallet,
173
172
signer,
174
173
userAddress,
175
174
disconnectWallet,
176
175
connected,
176
+ error,
177
177
provider,
178
178
network,
179
179
chainId,
@@ -184,6 +184,7 @@ export const Provider: React.FC<ProviderProps> = ({
184
184
connectWallet ,
185
185
signer ,
186
186
userAddress ,
187
+ error ,
187
188
web3Modal ,
188
189
connected ,
189
190
provider ,
0 commit comments