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 }