9

When a user changes to a different account in metamask, is there a way to detect it asynchronously in code?

I currently use

this.web3.eth.getAccounts((err, accs) => {   
  this.account = accs[0];
});  

but when the account is changed, it still picks up the previous one. Refreshing the page is not a way to go. Did anyone face this and has a solution?

| improve this question | | | | |
  • Unfortunately, the method most people used is polling for changes using setIntervals. The only other option is checking if accounts match before each call. – ReyHaynes Mar 15 '18 at 12:50
12

As suggested by Metamask FAQs this might be an option:

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

edit

In the newer version metamask exposes an events that could be used to detect whether there's an account change as per new doc

window.ethereum.on('accountsChanged', function (accounts) {
  // Time to reload your interface with accounts[0]!
})
| improve this answer | | | | |
  • Unfortunately at the moment, checking in a loop is the only supported method. – DanF Mar 15 '18 at 16:29
  • Be careful though, I had a problem where I was always matching the if condition because the account I get was always lowercase. – Antoine Delia Jul 19 '18 at 14:14
  • I use and suggest to use onFocus event to handle this issue. – Vanja Dev Jul 13 '19 at 18:39
  • Is there a similar solution for the TronLink extension (tronWeb)? – Dmytro Zarezenko May 5 at 12:35
23

Using web3 version 1.0.0, the metamask provider exposes an 'update' event you can listen to on it's publicConfigStore.

web3.currentProvider.publicConfigStore.on('update', callback);

Your callback will be passed an object with 'selectedAddress' and 'networkVersion' whenever those attributes change.

| improve this answer | | | | |
  • 3
    Hi Brian, where can I find documentation about the update event? Have searched the web3 1.0 docs. Thanks. – Vindberg Nov 23 '18 at 19:38
14

From new metamask docs:

https://metamask.github.io/metamask-docs/Advanced_Concepts/Provider_API#ethereum.on(eventname%2C-callback)

window.ethereum.on('accountsChanged', function (accounts) {
  // Time to reload your interface with accounts[0]!
})

window.ethereum.on('networkChanged', function (netId) {
  // Time to reload your interface with netId
})

you can also prevent metamask from automatically reloading web page

window.onbeforeunload = function() {
  return "Prevent reload"
}
| improve this answer | | | | |
  • Is there a similar solution for the TronLink extension (tronWeb)? – Dmytro Zarezenko May 5 at 12:35
1

You could put in useEffect a listenEvent like below:

useEffect(() => {
    async function listenMMAccount() {
      window.ethereum.on("accountsChanged", async function() {
        // Time to reload your interface with accounts[0]!
        accounts = await web3.eth.getAccounts();
        // accounts = await web3.eth.getAccounts();
        console.log(accounts);
      });
    }
    listenMMAccount();
  }, []);
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.