Skip to content

Instantly share code, notes, and snippets.

@pi0neerpat
Created December 17, 2020 20:52
Show Gist options
  • Save pi0neerpat/9e58032aa8c2b078a4f2d51370730e41 to your computer and use it in GitHub Desktop.
Save pi0neerpat/9e58032aa8c2b078a4f2d51370730e41 to your computer and use it in GitHub Desktop.
Handling terrible metamask ux
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