Skip to content

Commit

Permalink
Merge pull request #218 from PolymathNetwork/fix/MSDK-238-metamask-br…
Browse files Browse the repository at this point in the history
…eaking-changes

fix: future proof against metamask breaking changes
  • Loading branch information
VictorVicente authored Oct 26, 2020
2 parents 24f67a0 + 47e9727 commit 0e65f1a
Showing 1 changed file with 19 additions and 39 deletions.
58 changes: 19 additions & 39 deletions src/browserUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import { ErrorCode } from './types';
import { delay } from './utils';

export enum BrowserSupport {
NoMetamask = 'NoMetamask',
MetamaskLegacy = 'MetamaskLegacy',
MetamaskModern = 'MetamaskModern',
MetamaskDisabled = 'MetamaskDisabled',
MetamaskEnabled = 'MetamaskEnabled',
None = 'None',
}

interface Ethereum extends Provider {
networkVersion: string;
_metamask?: {
isApproved: () => Promise<boolean>;
isUnlocked: () => Promise<boolean>;
};
enable(): Promise<any>;
request(payload: { method: string }): Promise<any>;
}

interface Web3VersionAPI {
Expand All @@ -35,9 +34,6 @@ interface ExtendedWindow extends Window {
interface WindowWithEthereum extends ExtendedWindow {
ethereum: Ethereum;
}
interface WindowWithWeb3 extends ExtendedWindow {
web3: InjectedWeb3;
}

/**
* Returns the browser support for Ethereum
Expand All @@ -52,34 +48,24 @@ export function getBrowserSupport() {
const win = window as ExtendedWindow;

if (win.ethereum) {
return BrowserSupport.MetamaskModern;
}
if (win.web3) {
return BrowserSupport.MetamaskLegacy;
return BrowserSupport.MetamaskEnabled;
}
return BrowserSupport.NoMetamask;
return BrowserSupport.MetamaskDisabled;
}

/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* @hidden
*/
function isModern(obj: any): obj is WindowWithEthereum {
return getBrowserSupport() === BrowserSupport.MetamaskModern;
}

/**
* @hidden
*/
function isLegacy(obj: any): obj is WindowWithWeb3 {
return getBrowserSupport() === BrowserSupport.MetamaskLegacy;
function isWindowWithEthereum(obj: any): obj is WindowWithEthereum {
return getBrowserSupport() === BrowserSupport.MetamaskEnabled;
}

/**
* @hidden
*/
function isUnsupported(obj: any): obj is ExtendedWindow {
return getBrowserSupport() === BrowserSupport.NoMetamask;
function isExtendedWindow(obj: any): obj is ExtendedWindow {
return getBrowserSupport() === BrowserSupport.MetamaskDisabled;
}
/* eslint-enable @typescript-eslint/no-unused-vars */

Expand All @@ -95,18 +81,14 @@ export async function getInjectedProvider(): Promise<Provider | undefined> {

const win = (window as any) as ExtendedWindow;

if (isModern(win)) {
if (isWindowWithEthereum(win)) {
const injectedProvider = win.ethereum;
try {
await injectedProvider.enable();
await injectedProvider.request({ method: 'eth_requestAccounts' });
return injectedProvider;
} catch (err) {
throw new PolymathError({ code: ErrorCode.UserDeniedAccess });
}
} else if (isLegacy(win)) {
const injectedWeb3 = win.web3;
const web3Provider = injectedWeb3.currentProvider;
return web3Provider;
} else {
throw new PolymathError({ code: ErrorCode.MetamaskNotInstalled });
}
Expand Down Expand Up @@ -135,10 +117,8 @@ export async function getNetworkId(): Promise<number | null> {

let rawNetworkId: string | undefined;

if (isModern(win)) {
if (isWindowWithEthereum(win)) {
rawNetworkId = win.ethereum.networkVersion;
} else if (isLegacy(win)) {
rawNetworkId = win.web3.version.network;
} else {
return null;
}
Expand All @@ -163,16 +143,16 @@ export async function getCurrentAddress() {
throw new PolymathError({ code: ErrorCode.NonBrowserEnvironment });
}

if (isModern(win)) {
if (isWindowWithEthereum(win)) {
// Special check for Metamask to know if it is locked or not
const metamask = win.ethereum._metamask;
if (metamask) {
const isApproved = await metamask.isApproved();
if (isApproved && !accounts.length) {
const isUnlocked = await metamask.isUnlocked();
if (isUnlocked && !accounts.length) {
throw new PolymathError({ code: ErrorCode.WalletIsLocked });
}
}
} else if (isUnsupported(win)) {
} else if (isExtendedWindow(win)) {
throw new PolymathError({ code: ErrorCode.IncompatibleBrowser });
}

Expand All @@ -187,7 +167,7 @@ export async function getCurrentAddress() {
* @returns an unsubscribe function
*/
export function onAddressChange(cb: (newAddress: string, previousAddress?: string) => void) {
if (isUnsupported(window as ExtendedWindow)) {
if (isExtendedWindow(window)) {
// eslint-disable-next-line no-console
console.warn('"onAddressChange" Was called, but the current browser does not support Ethereum');
return () => {};
Expand Down Expand Up @@ -223,7 +203,7 @@ export function onAddressChange(cb: (newAddress: string, previousAddress?: strin
* @returns an unsubscribe function
*/
export function onNetworkChange(cb: (newNetwork: number, previousNetwork?: number) => void) {
if (isUnsupported(window as ExtendedWindow)) {
if (isExtendedWindow(window)) {
// eslint-disable-next-line no-console
console.warn('"onNetworkChange" Was called, but the current browser does not support Ethereum');
return () => {};
Expand Down

0 comments on commit 0e65f1a

Please sign in to comment.