MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites
https://metamask.io
Other
12.04k stars 4.92k forks source link

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

Closed re2005 closed 1 year ago

re2005 commented 1 year ago

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

https://github.com/MetaMask/metamask-extension/assets/2920357/5bc37d35-b357-4ffd-9a8f-e6b0e4be37c1

anaamolnar commented 1 year ago

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

yonigoldberg commented 1 year ago

We noticed this issue as well

vandan commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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:

EDIT2:

EDIT3:

Minimum steps to reproduce:

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 commented 1 year ago

In summary so far:

Attempted fixes:

EDIT:

jiexi commented 1 year ago

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

video in slack (was too large for github)

jiexi commented 1 year ago

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

jiexi commented 1 year ago

Workaround here

jiexi commented 1 year ago

Workaround merged