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

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

Closed
re2005 opened this issue May 25, 2023 · 10 comments
Closed

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

re2005 opened this issue May 25, 2023 · 10 comments
Assignees
Labels
Sev2-normal Normal severity; minor loss of service or inconvenience. team-wallet-api-platform type-bug

Comments

@re2005
Copy link

re2005 commented May 25, 2023

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
@anaamolnar
Copy link

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

@yonigoldberg
Copy link

We noticed this issue as well

@vandan
Copy link

vandan commented Jun 1, 2023

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?

@re2005
Copy link
Author

re2005 commented Jun 1, 2023

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

@jiexi
Copy link
Contributor

jiexi commented Jun 5, 2023

  • 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

@jiexi
Copy link
Contributor

jiexi commented Jun 14, 2023

In summary so far:

  • this bug only seems to occur on chrome(ium?) due to the prerender feature
  • prerendered pages are loaded and rendered in the background when the user types in a url (but does not hit enter) for a page that they already have open in another tab
  • prerendered pages have fully functional inpage <=> extension connection until the user presses enter in the url bar and the page becomes active and visible
  • Following the reproduction steps in the comment above, you can expect to see the following behavior regarding connection stream for the second tab:

Attempted fixes:

  • checking document.prerendering and/or awaiting the prerenderingchange event on the document object to delay the inpage stream creation until after the page changes from prerendered to active
    • works, but breaks dapps that do not wait for the ethereum window object to be available much later in the page load process
  • https://github.com/MetaMask/json-rpc-middleware-stream/pull/47/files
    • the fix above seems unrelated to this prerender stream bug in particular

EDIT:

  • As far as I can tell, contentscript is never notified that the contentscript -> background connection is broken in the stream here. However, the background script is notified that the connection received here is broken. Not sure how contentscript would know to reestablish a connection if it is never notified the connection is broken in the first place
  • Using Google Chrome 114 with MM versions
    • 10.29.0 bug is present
    • 10.23.0 ...
    • 10.18.0
    • 10.10.0
    • 10.5.0
    • 9.8.4
    • 8.1.11 bug is present
    • 7.7.9 bug no longer present
  • Using develop branch (commit 46a2604d) on the current Google Chrome versions
    • 102.0.5005.61 (pre prerender) works
    • 107.0.5304.110 (prerender added) ...
    • 109.0.5414.119
    • 110.0.5481.177
    • 111.0.5563.146 (full prerender menu available)
    • 112.0.5615.137
    • 113.0.5672.126 broken 👀
    • 114.0.5735.133 (current) still broken, of course

@jiexi
Copy link
Contributor

jiexi commented Jun 16, 2023

Slimmed down reproduction branch here jl/mme-17339/stream-skeleton-chrome-bug

video in slack (was too large for github)

@jiexi
Copy link
Contributor

jiexi commented Jun 21, 2023

Chrome bug report submitted here. Will work on a fix meanwhile

@jiexi jiexi mentioned this issue Jun 22, 2023
8 tasks
@jiexi
Copy link
Contributor

jiexi commented Jun 22, 2023

Workaround here

@jiexi
Copy link
Contributor

jiexi commented Jun 27, 2023

Workaround merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Sev2-normal Normal severity; minor loss of service or inconvenience. team-wallet-api-platform type-bug
Projects
None yet
Development

No branches or pull requests

6 participants
@yonigoldberg @jiexi @vandan @re2005 @anaamolnar and others