Metamask-extension: web3.eth.accounts[0] not changing on account switch

Created on 3 Oct 2017  路  14Comments  路  Source: MetaMask/metamask-extension

when running the code

var account = web3.eth.accounts[0]; setInterval(function() { if (web3.eth.accounts[0] !== account) { account = web3.eth.accounts[0]; window.location.reload(); } }, 100);

The page would auto-refresh when accounts change. This functionality broke, and it appears to be because the web3.eth.accounts[0] isn't being updated to the new address when I change to a different account in the metamask window.

T00-bug

Most helpful comment

web3.eth.getAccounts(console.log) reflects the change so we are just using that for now as a workaround whenever we need the current account address.

All 14 comments

I thought I had gotten it to reproduce but once the background process reloaded it stopped happening what version are you on @mbeylin ? also is it always a problem?

@frankiebee version is 3.10.8, and it seems to always happen (can't get it to function as it's supposed to, no matter how many times I try).

I'm also on 3.10.8 and experiencing this. Just recently web3.eth.accounts[0] stopped ever updating from what it is initially set to.

I'm getting an issue that might be related to this - #2140 . web3.eth.accounts[0] isn't set on load event anymore.

I'm having the same issue. The code provided in the description used to work just a few days ago.

I am noticing the same behaviour with the web3.version.network changes not being updated.

I spent most of the day today trying to trace this down. Here are my notes:

  • The problem initially seemed intermittent, sometimes I couldn't get it to stop, sometimes I couldn't get it to start.
  • We initially thought this was maybe related to some recent changes to how we emit account-changing events, but logging the background process showed that suspicion was unfounded, account selections & network changes are firing in the background as usual, and being written to our port-stream.
  • After a fresh reload of the background process, the next page seems to get its in-page data updated correctly, making it seem like maybe an issue with adding subsequent listeners.
  • If it were really a problem with listeners, then our popup wouldn't get data updates either, but it does.

I need to get ready for the EthWaterloo hackathon now, so hopefully this helps the next effort.

I can send transactions successfully with the first account I load the page with, but when I switch accounts I get this error (the address below is the one I switched from, and not the current one in the MetaMask UI):
Error: Unknown address - unable to sign transaction for this address: "0x8acb71431fd017ac95d5da5fc5d73ad72adc877c"
at Object.InvalidResponse (inpage.js:13995)
at inpage.js:13995
at inpage.js:9899
at completeRequest (inpage.js:9950)
at inpage.js:673
at replenish (inpage.js:1193)
at iterateeCallback (inpage.js:1183)
at inpage.js:1158
at inpage.js:9827
at inpage.js:9923
Those last two errors come from the the line done(); in createIdRemapMiddleware() and return handler(next); in runReturnHandlers(cb)

Also it may not be related, but I experienced the same sort of problem when I was getting the "TOO MANY LISTENERS" error a few weeks ago

I have also gotten the above error, and I found it was caused by the application state using an old version of accounts to sign the transaction, and not the most up to date version in Metamask (since web3.eth.accounts[0] was never updated)

@mbeylin is correct, that error is thrown if a non-selected address is requested to send a transaction, as the error message suggests.

web3.eth.getAccounts(console.log) reflects the change so we are just using that for now as a workaround whenever we need the current account address.

Closing old issue, will reopen if the problem persists.

@tmashuang what's the final solution if I want to get accouts[0] with metamask switch account? web3.eth.getAccounts(console.log) ? If yes, could you pls give some example?

@jacktang Yes, the web3.eth.getAccounts() method is very reliable. You might check in an occasional loop:

let account
setTimeout(() => {
  web3.eth.getAccounts((err, accounts) => {
    if (err) return
    account = accounts[0]
    accountFound()
  })
}, 1000)
Was this page helpful?
0 / 5 - 0 ratings