/ common / features / handleMetaMaskPolling.ts
handleMetaMaskPolling.ts
 1  import { Store } from 'redux';
 2  
 3  import { Web3Wallet } from 'libs/wallet';
 4  import { AppState } from './reducers';
 5  import * as configNetworksSelectors from './config/networks/selectors';
 6  import { walletSelectors } from './wallet';
 7  
 8  export const METAMASK_POLLING_INTERVAL: number = 1000;
 9  
10  export const getActualChainId = (): Promise<string> =>
11    new Promise((resolve, reject) => {
12      const { web3 } = window as any;
13  
14      if (!web3) {
15        reject('Web3 not found.');
16      }
17  
18      return web3.version.getNetwork(
19        (err: Error, network: string) => (err ? reject(err) : resolve(network))
20      );
21    });
22  
23  /**
24   * @desc
25   * MetaMask no longer refreshes the page automatically on network change,
26   * so we must poll to ensure the network is the same as the locally stored version.
27   * @see https://medium.com/metamask/breaking-change-no-longer-reloading-pages-on-network-change-4a3e1fd2f5e7
28   */
29  export default async function handleMetaMaskPolling(store: Store<AppState>): Promise<boolean> {
30    const state = store.getState();
31  
32    try {
33      // Locally stored network.
34      const web3Wallet = walletSelectors.getWalletInst(state);
35  
36      // MetaMask's actual network.
37      const actualChainId = await getActualChainId();
38      const actualNetwork = configNetworksSelectors.getNetworkByChainId(state, actualChainId);
39  
40      if (
41        web3Wallet &&
42        (web3Wallet as Web3Wallet).network &&
43        actualNetwork &&
44        (web3Wallet as Web3Wallet).network !== actualNetwork.id
45      ) {
46        window.location.reload();
47  
48        return true;
49      }
50    } catch (error) {
51      window.location.reload();
52  
53      return true;
54    }
55  
56    return false;
57  }