Created
December 17, 2020 20:52
-
-
Save pi0neerpat/9e58032aa8c2b078a4f2d51370730e41 to your computer and use it in GitHub Desktop.
Handling terrible metamask ux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Web3Provider } from "@ethersproject/providers"; | |
import { | |
isWeb3EnabledBrowser, | |
getErrorResponse, | |
isMobile, | |
WALLET_LINK_ID, | |
METAMASK_ID | |
} from "../general"; | |
const deepLinks = { | |
[METAMASK_ID]: "metamask:spendless.io/login", | |
[WALLET_LINK_ID]: "****************" | |
}; | |
export function isToshi() { | |
return ( | |
typeof window !== "undefined" && | |
window.web3 && | |
window.web3.currentProvider.isToshi | |
); | |
} | |
export function isMetaMask() { | |
return isWeb3EnabledBrowser() && window.ethereum.isMetaMask; | |
} | |
export const unlockBrowser = async ({ | |
debug, | |
silent, | |
isReturningUser, | |
onNetworkChange, | |
walletType | |
}) => { | |
try { | |
if (!isWeb3EnabledBrowser()) { | |
if (isMobile()) window.open(deepLinks[walletType]); | |
return { hasWallet: false, isUnlocked: false }; | |
} | |
if (silent) { | |
// TODO: use a better check for unlocking other wallets besides metamask | |
const isUnlocked = await window.ethereum._metamask.isUnlocked(); | |
if (!isUnlocked) | |
return { | |
hasWallet: true, | |
isUnlocked: false, | |
...getErrorResponse( | |
"Silent unlock failed for metamask since wallet is locked.", | |
"unlockBrowser" | |
) | |
}; | |
} | |
window.ethereum.autoRefreshOnNetworkChange = false; | |
try { | |
// Note: not "ethereum.on" is supported in all wallets, so we must not throw an error | |
window.ethereum.on("chainChanged", onNetworkChange); | |
// TODO: remove networkChanged listener once MetaMask v8 rollout is complete | |
// Unless other wallets rely on it too. | |
window.ethereum.on("networkChanged", onNetworkChange); | |
} catch (error) { | |
if (debug) | |
/* eslint-disable-next-line no-console */ | |
console.log(getErrorResponse(error, "unlockBrowser").error.message); | |
} | |
let walletAddress; | |
if (walletType === WALLET_LINK_ID) { | |
walletAddress = await window.ethereum.enable(); | |
} else { | |
walletAddress = await window.ethereum.request({ | |
method: "eth_requestAccounts", | |
params: [ | |
{ | |
eth_accounts: {} | |
} | |
] | |
}); | |
} | |
// Can be used to get wallet address without unlocking | |
// But only if they've previously connected a wallet | |
// const { | |
// "0": { caveats } | |
// } = await window.ethereum.request({ | |
// method: "wallet_getPermissions", | |
// params: [ | |
// { | |
// eth_accounts: {} | |
// } | |
// ] | |
// }); | |
// const walletAddress = caveats[1].value; | |
// Don't request a permission change if user has already connected MetaMask | |
// They only need to unlock their wallet. | |
if (!isReturningUser) { | |
// Note: not supported in MetaMask Mobile, so we must not throw an error | |
try { | |
await window.ethereum.request({ | |
method: "wallet_requestPermissions", | |
params: [ | |
{ | |
eth_accounts: {} | |
} | |
] | |
}); | |
} catch (error) { | |
if (debug) | |
/* eslint-disable-next-line no-console */ | |
console.log(getErrorResponse(error, "unlockBrowser").error.message); | |
} | |
} | |
const walletProvider = new Web3Provider(window.ethereum); | |
const network = await walletProvider.getNetwork(); | |
if (debug) | |
/* eslint-disable-next-line no-console */ | |
console.log( | |
"Web3Browser wallet loaded: ", | |
JSON.stringify({ walletAddress, network }) | |
); | |
return { | |
hasWallet: true, | |
isUnlocked: true, | |
walletType, | |
walletAddress: walletAddress[0], | |
network, | |
walletProvider | |
}; | |
} catch (error) { | |
if (isWeb3EnabledBrowser()) { | |
if (debug) | |
/* eslint-disable-next-line no-console */ | |
console.log("Web3 detected in browser, but wallet unlock failed"); | |
return { | |
hasWallet: true, | |
isUnlocked: false, | |
...getErrorResponse(error, "unlockBrowser") | |
}; | |
} | |
return { | |
hasWallet: false, | |
isUnlocked: false, | |
...getErrorResponse(error, "unlockBrowser") | |
}; | |
} | |
}; | |
export const disconnectBrowser = ({ debug }) => { | |
if (debug) | |
/* eslint-disable-next-line no-console */ | |
console.log( | |
"Warning: To truly disconnect MetaMask/Browser Wallet, user must manually remove permissions in the wallet settings. See https://github.com/MetaMask/metamask-extension/issues/8956#issuecomment-656778369" | |
); | |
// TODO: implement once possible for metamask using API | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment