MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites

Home Page:https://metamask.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unresponsive window.ethereum.request() on SPA Applications (React & Vue)

re2005 opened this issue · comments

Describe the bug

Seems that SPA (React, Vue) and Metamask are having this issue.
I've tested this behaivour on many websites and it seems consistent every time.

As example Uniswap built in React
https://app.uniswap.org

On a previous connected session Metamask usually connected automatically if that site have already been approved.

So lets say, if you call:

await window.ethereum.request({
      method: 'eth_requestAccounts',
      params: [{ eth_accounts: {} }],
    })

It will return your connected address in a Array format.

So far so good, the issue comes when you return to that same website, and than calling await window.ethereum.request(...) is not responsive anymore.

Interesting is that same never happens on websites SSR, but mostly happens when is a SPA.

Steps to reproduce

  1. Go to https://app.uniswap.org (or any other React or Vue project)
  2. Connect your wallet
  3. Open a new tab and paste the address https://app.uniswap.org again.
  4. Repeat the process until you see that Uniswap won't automatically connect
  5. Once that happens open the Console and try yo fetch your accounts
await window.ethereum.request({
      method: 'eth_requestAccounts',
      params: [{ eth_accounts: {} }],
    })

You will notice that Metamask doesn't return anything.

To fix, refresh the page, and it will work as expected

Error messages or log output

No response

Version

v10.30.4

Build type

None

Browser

Chrome

Operating system

MacOS

Hardware wallet

No response

Additional context

Screen.Recording.2023-05-25.at.16.40.23.mov
commented

Hello, @re2005. Thanks for reporting! I will pass this on to the team.

We noticed this issue as well

commented

There are typically no params passed into eth_requestAccounts.
https://docs.metamask.io/wallet/get-started/access-accounts/

You would then use wallet_getPermissions to retrieve the accounts that the dapp already has permissions for.
https://docs.metamask.io/wallet/reference/rpc-api/#wallet_getpermissions

Does changing that help?

Thanks @vandan.
Calling
window.ethereum.request({method: 'wallet_getPermissions'})
or
window.ethereum.request({method: 'eth_requestAccounts'})

Doesn't return anything.

Curious is that the ethereum object is still available.

But the method request never respond.

also tried:
await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x1' }] })

But no success.

Screenshot 2023-06-01 at 20 31 57
commented
  • occurs on webpages without react
  • webpages do not need to interact with the ethereum window object
  • no accounts need to be permitted
  • wallet does not have to be unlocked
  • refreshing the same page over and over does not cause the bug
  • occurs even if different domains are opened across multiple tabs

Cannot reproduce on Firefox 113.0.2
Can reproduce on Chrome 114.0.5735.90

Page load requests/responses

Send: {method: 'metamask_getProviderState', params: undefined, jsonrpc: '2.0', id: 965688104}
Receive: {isUnlocked: false, chainId: '0x5', networkVersion: '5'}
Send: {jsonrpc: '2.0', id: 965688105, method: 'metamask_sendDomainMetadata', params: {…}}
Receive: {id: 965688104, jsonrpc: '2.0', result:  
{isUnlocked: false, chainId: '0x5', networkVersion: '5', accounts: Array(0)}}
MetaMask: Connected to chain with ID "0x5".
Receive: {id: 965688105, jsonrpc: '2.0', result: true}

# Broken sessions will not receive the next following messages
# EDIT: the above is false. broken sessions can receive these messages too. Just depends how early the connection between page and extension is broken
Receive: {isUnlocked: false, chainId: '0x5', networkVersion: '5'}
Receive: {method: 'metamask_chainChanged', params: {chainId: '0x5', networkVersion: '5'}}

EDIT:

  • In chrome, right clicking and duplicating the tab makes it so that the bug does not occur
    • Seems to be related to injection of ethereum provider on the chrome new tab page
    • pages that have been visited before seem to get eagerly loaded when typed into the url bar, even before hitting enter

EDIT2:

  • In chrome, disabling page preloading prevents the bug from occuring
    • Settings -> Privacy and security -> Cookies and other site data -> Preload pages -> No preloading

EDIT3:

Minimum steps to reproduce:

  • Ensure chrome settings has preloading set to standard
  • Kill chrome application
  • Start chrome
  • Visit https://metamask.github.io/test-dapp/
  • Open a new tab (ctrl/cmd + T, not duplicate)
  • Type in https://metamask.github.io/test-dapp/, but do not hit enter yet
  • Wait 5 seconds (happens more quickly, but for reproducibility we will wait longer)
  • Hit enter
  • Unlock wallet if needed
  • Test page connections

Your first tab will respond to rpc calls as normal
Your second tab will not respond to rpc calls and is broken

EDIT4:

Relevant documentation for chrome prerender