Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Metamask closes another Chrome extension popup after calling eth.requestAccounts #15789

Closed
sunxivincent opened this issue Sep 11, 2022 · 4 comments

Comments

@sunxivincent
Copy link

Describe the bug

I am building a chrome extension using react and calling Metamask for fetching user's account. I am using metamask-extension-provider instead of window.ethereum as suggested so I can communicate with the chain using Metamask.
Below sample code shows a button click event handler and I am expecting after signing with Metamask, user can go back to extension popup's main page showing they have been connected.

const createMetaMaskProvider = require("metamask-extension-provider");
const provider = createMetaMaskProvider();
const onClick = async() => {
  setLoading(true);
  const web3 = new Web3(provider); 
  const accounts = await web3.eth.requestAccounts();
  const account = accounts[0];
  await web3.eth.personal.sign(XXX, account.toLowerCase(), "");
  setLoading(false);
};
  return <LoginWall onClick={onClick}></LoginWall>;

however the Metamask closed both itself and my chrome extension popup. After diving into the metamask code a little bit, I am suspicious there are perhaps window management logic controlling popup's on and off which fails to consider such scenario?
https://github.com/MetaMask/metamask-storybook/blob/master/scripts/background.js#L489

Steps to reproduce

  1. create a sample chrome extension that uses metamask-extension-provider to requestAccounts
  2. after user unlocks Metamask, both Metamask and sample chrome extension popup closed. The expected behavior should be metamask closed while sample chrome extension remains open.

Error messages or log output

No response

Version

10.18.4

Build type

No response

Browser

Chrome

Operating system

MacOS

Hardware wallet

No response

Additional context

MetaMask/extension-provider#26 this issue may be relevant

@seaona
Copy link
Contributor

seaona commented Sep 14, 2022

Thank you for your report @sunxivincent. I could reproduce the issue and we are now investigating it.

test-extension-mm-connection.webm

@sunxivincent
Copy link
Author

@seaona One thing I have noticed is that if I open the chrome debugger view, the feature works as expected. I am suspecting it is related to failing to control the correct view open/close.

@bschorchit
Copy link

It seems this might be a platform behavior that we don't control.

The browser action popup will go away when your mouse no longer hovers over it. This is a platform behavior that we don't control. In that example video, your mouse was no longer over the popup when it was brought back into the foreground, causing it to close.

@sunxivincent
Copy link
Author

I am creating a workaround for this and hopefully it will benefit future people that has similar issue. The workaround is basically creating a pseudo window when invoking Metamask in your own chrome extension popup. And always focus this window (you may add some UI to remind user not to close it when applying your business logic) I am pasting my code in below. My future thought would be in Metamask side it exposes an option that allows its client to control whether or not closing up the Metamask after it finishes signing, rather than it closing the window for all the cases (which will end up closing up the caller extension popup as well). But I am leaving this suggestion to the community.

const POPUP_WINDOW_ID = “XXX”;

export async function updateOrCreateFakeWindow(callback) {
  const windowId = Number(window.localStorage.getItem(POPUP_WINDOW_ID));
  let currentWindow = null;
  try {
    currentWindow = windowId ? await chrome.windows.get(windowId) : null;
  } catch (error) {}

  if (currentWindow) {
    chrome.windows.update(
      windowId,
      {
        focused: true,
        width: 1,
        height: 1,
      },
      callback
    );
  } else {
    chrome.windows.create(
      {
        focused: true,
        width: 1,
        height: 1,
        url: "about:blank",
      },
      (w) => {
        window.localStorage.setItem(POPUP_WINDOW_ID, w.id);
        callback();
      }
    );
  }
}

===== In your main logic file ====

const handleConnection = () => {
    updateOrCreateFakeWindow(async () => {
      const accounts = await web3.eth.requestAccounts();
      const account = accounts[0];
      web3.eth.personal
        .sign(
          “”,
          account.toLowerCase(),
          ""
        )
        .then(() => {})
        .catch((e) => {});
    });
  };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants