Skip to content

Commit 5e89859

Browse files
authored
feat(useWallet): add correctNetwork flag (#74)
* feat(useWallet): add correctNetwork flag * Remove unused import
1 parent 07e8546 commit 5e89859

File tree

8 files changed

+162
-35
lines changed

8 files changed

+162
-35
lines changed

packages/components/src/components/Address/Address.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { Address } from '.';
33

4-
import { useWallet, Provider } from '@web3-ui/hooks';
4+
import { useWallet, Provider, NETWORKS } from '@web3-ui/hooks';
55
import { Button } from '@chakra-ui/react';
66

77
export default {
@@ -25,7 +25,7 @@ const AddressUsingProvider = () => {
2525
};
2626

2727
export const WithWallet = () => (
28-
<Provider network='rinkeby'>
28+
<Provider network={NETWORKS.rinkeby}>
2929
<AddressUsingProvider />
3030
</Provider>
3131
);

packages/components/src/components/AddressInput/AddressInput.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { AddressInput } from '.';
33
import { ethers } from 'ethers';
4-
import { Provider, useWallet } from '@web3-ui/hooks';
4+
import { NETWORKS, Provider, useWallet } from '@web3-ui/hooks';
55
import { Text } from '@chakra-ui/layout';
66

77
export default {
@@ -41,7 +41,7 @@ const Component = ({ ...props }) => {
4141
export const Default = () => <Component />;
4242
export const UsingWeb3Hooks = () => {
4343
return (
44-
<Provider network='mainnet'>
44+
<Provider network={NETWORKS.mainnet}>
4545
<WithUseWallet />
4646
</Provider>
4747
);

packages/hooks/src/Provider.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import React from 'react';
22
import { render } from '@testing-library/react';
33

44
import { Provider } from './Provider';
5+
import { NETWORKS } from '.';
56

67
describe('Provider', () => {
78
it('renders without throwing', () => {
8-
const { container } = render(<Provider network='rinkeby' />);
9+
const { container } = render(<Provider network={NETWORKS.rinkeby} />);
910
expect(container).toBeInTheDocument();
1011
});
1112
});

packages/hooks/src/Provider.tsx

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ export interface Web3ContextType {
99
signer?: JsonRpcSigner | null;
1010
userAddress?: string | null;
1111
disconnectWallet?: () => void;
12-
network: string;
13-
chainId?: number;
12+
chainId?: number | null;
1413
connected: boolean;
1514
provider?: ethers.providers.Web3Provider | null;
15+
correctNetwork: boolean;
1616
}
1717

1818
export const Web3Context = React.createContext<Web3ContextType | undefined>(undefined);
1919

2020
export interface ProviderProps {
2121
/**
2222
* @dev The network you want to connect to.
23-
* @example 'mainnet'
23+
* @example NETWORKS.mainnet
2424
* @type string
2525
*/
26-
network: string;
26+
network: number;
2727
/**
2828
* @dev Your Infura project ID. This is required if you want to support WalletConnect.
2929
* @type string
@@ -39,15 +39,16 @@ export interface ProviderProps {
3939
*/
4040
export const Provider: React.FC<ProviderProps> = ({ children, network, infuraId }) => {
4141
const [signer, setSigner] = React.useState<null | JsonRpcSigner>();
42-
const [provider, setProvider] = React.useState<ethers.providers.Web3Provider>();
42+
const [provider, setProvider] = React.useState<ethers.providers.Web3Provider | null>();
4343
const [userAddress, setUserAddress] = React.useState<null | string>();
4444
const [web3Modal, setWeb3Modal] = React.useState<Web3Modal>();
45-
const [chainId, setChainId] = React.useState<number>();
45+
const [chainId, setChainId] = React.useState<number | null>();
4646
const [connected, setConnected] = React.useState<boolean>(false);
47+
const [correctNetwork, setCorrectNetwork] = React.useState<boolean>(true);
48+
const [connection, setConnection] = React.useState<any>();
4749

4850
const connectWallet = React.useCallback(async () => {
4951
const web3Modal = new Web3Modal({
50-
network,
5152
providerOptions: {
5253
walletconnect: {
5354
package: WalletConnectProvider,
@@ -57,16 +58,61 @@ export const Provider: React.FC<ProviderProps> = ({ children, network, infuraId
5758
},
5859
},
5960
});
61+
setWeb3Modal(web3Modal);
6062
const connection = await web3Modal.connect();
63+
setConnection(connection);
6164
const provider = new ethers.providers.Web3Provider(connection);
65+
setProvider(provider);
66+
const chainId = await provider.getNetwork().then((network) => network.chainId);
67+
setChainId(chainId);
68+
setCorrectNetwork(chainId === network);
6269
const signer = provider.getSigner();
63-
setWeb3Modal(web3Modal);
6470
setSigner(signer);
71+
setUserAddress(await signer.getAddress());
72+
setConnected(true);
73+
74+
connection.on('chainChanged', onNetworkChange);
75+
connection.on('accountsChanged', onAccountsChanged);
76+
connection.on('disconnect', onDisconnect);
77+
}, [
78+
Web3Modal,
79+
web3Modal,
80+
WalletConnectProvider,
81+
network,
82+
infuraId,
83+
ethers,
84+
correctNetwork,
85+
connection,
86+
]);
87+
88+
const onNetworkChange = async (newChainId: string) => {
89+
const formattedChainId = +newChainId.split('0x')[1];
90+
setChainId(formattedChainId);
91+
setCorrectNetwork(formattedChainId === network);
92+
const provider = new ethers.providers.Web3Provider(connection);
6593
setProvider(provider);
94+
const signer = provider.getSigner();
95+
setSigner(signer);
6696
setUserAddress(await signer.getAddress());
67-
setChainId(await signer.getChainId());
6897
setConnected(true);
69-
}, [Web3Modal, web3Modal, WalletConnectProvider, network, infuraId, ethers]);
98+
};
99+
100+
const onAccountsChanged = async () => {
101+
const provider = new ethers.providers.Web3Provider(connection);
102+
setProvider(provider);
103+
const chainId = await provider.getNetwork().then((network) => network.chainId);
104+
setChainId(chainId);
105+
setCorrectNetwork(chainId === network);
106+
const signer = provider.getSigner();
107+
setSigner(signer);
108+
setUserAddress(await signer.getAddress());
109+
setConnected(true);
110+
};
111+
112+
const onDisconnect = async () => {
113+
web3Modal?.clearCachedProvider();
114+
disconnectWallet();
115+
};
70116

71117
const disconnectWallet = React.useCallback(() => {
72118
web3Modal?.clearCachedProvider();
@@ -85,8 +131,19 @@ export const Provider: React.FC<ProviderProps> = ({ children, network, infuraId
85131
provider,
86132
network,
87133
chainId,
134+
correctNetwork,
88135
}),
89-
[connectWallet, signer, userAddress, web3Modal, connected, provider, network, chainId]
136+
[
137+
connectWallet,
138+
signer,
139+
userAddress,
140+
web3Modal,
141+
connected,
142+
provider,
143+
network,
144+
chainId,
145+
correctNetwork,
146+
]
90147
);
91148

92149
return <Web3Context.Provider value={{ ...value }}>{children}</Web3Context.Provider>;

packages/hooks/src/constants.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export const NETWORKS = {
2+
mainnet: 1,
3+
ropsten: 3,
4+
rinkeby: 4,
5+
goerli: 5,
6+
kovan: 42,
7+
BSC: 56,
8+
BSCTestnet: 97,
9+
xdai: 100,
10+
polygon: 137,
11+
theta: 361,
12+
thetaTestnet: 365,
13+
moonriver: 1285,
14+
mumbai: 80001,
15+
harmony: 1666600000,
16+
palm: 11297108109,
17+
localhost: 1337,
18+
hardhat: 31337,
19+
fantom: 250,
20+
avalanche: 43114,
21+
songbird: 19,
22+
moonbaseAlpha: 1287,
23+
};
24+
25+
export const CHAIN_ID_TO_NETWORK = {
26+
1: 'mainnet',
27+
3: 'ropsten',
28+
4: 'rinkeby',
29+
5: 'goerli',
30+
42: 'kovan',
31+
56: 'BSC',
32+
97: 'BSCTestnet',
33+
100: 'xdai',
34+
137: 'polygon',
35+
361: 'theta',
36+
365: 'thetaTestnet',
37+
1285: 'moonriver',
38+
80001: 'mumbai',
39+
1666600000: 'harmony',
40+
11297108109: 'palm',
41+
1337: 'localhost',
42+
31337: 'hardhat',
43+
250: 'fantom',
44+
43114: 'avalanche',
45+
19: 'songbird',
46+
1287: 'moonbaseAlpha',
47+
};

packages/hooks/src/hooks/useWallet.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { CHAIN_ID_TO_NETWORK, NETWORKS } from '..';
23
import { Web3Context } from '../Provider';
34

45
/**
@@ -8,27 +9,40 @@ export function useWallet() {
89
const context = React.useContext(Web3Context);
910
const [ens, setEns] = React.useState<string>();
1011

12+
if (!context) {
13+
throw new Error('No Web3Context found');
14+
}
15+
16+
const {
17+
connectWallet,
18+
disconnectWallet,
19+
userAddress,
20+
chainId,
21+
signer,
22+
connected,
23+
provider,
24+
correctNetwork,
25+
} = context;
26+
1127
React.useEffect(() => {
12-
if (context) {
13-
const { userAddress, provider } = context;
14-
if (userAddress && provider) {
15-
provider.lookupAddress(userAddress).then((address) => {
16-
setEns(address as string);
17-
});
18-
}
28+
if (userAddress && provider && chainId === NETWORKS.mainnet) {
29+
provider.lookupAddress(userAddress).then((address) => {
30+
setEns(address as string);
31+
});
1932
}
20-
}, [context?.userAddress, context?.provider]);
33+
}, [userAddress, provider]);
2134

2235
return {
23-
connectWallet: context?.connectWallet,
24-
disconnectWallet: context?.disconnectWallet,
36+
connectWallet,
37+
disconnectWallet,
2538
connection: {
26-
userAddress: context?.userAddress,
27-
network: context?.network,
28-
signer: context?.signer,
39+
userAddress,
40+
network: CHAIN_ID_TO_NETWORK[chainId as number],
41+
signer,
2942
ens,
3043
},
31-
connected: context?.connected,
32-
provider: context?.provider,
44+
connected,
45+
provider,
46+
correctNetwork,
3347
};
3448
}

packages/hooks/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { useWallet } from './hooks';
22
export { useTokenBalance } from './hooks/useTokenBalance';
33
export { Provider, Web3Context } from './Provider';
44
export type { ProviderProps, Web3ContextType } from './Provider';
5+
export { NETWORKS, CHAIN_ID_TO_NETWORK } from './constants';
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
22
import { Button } from '@chakra-ui/react';
3-
import { Provider, useWallet } from '..';
3+
import { NETWORKS, Provider, useWallet } from '..';
44

55
export default {
66
title: 'Hooks/useWallet',
77
};
88

99
const DefaultUsingProvider = () => {
10-
const { connection, connectWallet, disconnectWallet, connected } = useWallet();
10+
const { connection, connectWallet, disconnectWallet, connected, correctNetwork } = useWallet();
11+
12+
useEffect(() => {
13+
if (!correctNetwork) {
14+
alert('Please connect to the correct network');
15+
}
16+
}, [correctNetwork]);
1117

1218
if (connected) {
1319
return (
1420
<div>
1521
<Button onClick={disconnectWallet}>Disconnect wallet</Button>
1622
<p>{connection.ens || connection.userAddress}</p>
23+
<p>Connected to the correct network: {correctNetwork ? 'Yes' : 'no'}</p>
1724
</div>
1825
);
1926
}
@@ -22,7 +29,7 @@ const DefaultUsingProvider = () => {
2229
};
2330

2431
export const Default = () => (
25-
<Provider network='rinkeby'>
32+
<Provider network={NETWORKS.rinkeby}>
2633
<DefaultUsingProvider />
2734
</Provider>
2835
);

0 commit comments

Comments
 (0)