'My dapp doesn't detect when an user change their Metamask Account
I am in the process of building a dapp for a project. I have one last thing to adjust: detect when a user changes metamask account to reset the state but it doesn't work.
//Doesn't work
window.ethereum.on('accountsChanged', function (accounts) {
console.log('accountsChanges',accounts);
setDefaultAccount(null)
});
// This works perfectly
window.ethereum.on('chainChanged', (chainId) => {
if(chainId !== "0x13881") {
setErrorMessage("Please connect on testnet Polygon Mumbai")
} else {
setErrorMessage(null)
window.location.reload();
}
Thank for your help !
Solution 1:[1]
I was also struggling with the same issue. Being unable to find the answer in the docs anywhere. Until I'd realized that it's not meant to detect you switching from a connected account to a disconnected one.
In other words: it only detects it when you switch between accounts that are already connected to your Dapp. In that case - it functions perfectly. And detects an account change.
Go on ahead an test it on some popular Dapp out there. Connect just one of your accounts to it - then change it to another account on the same wallet, that is not yet connected - and it will also not be able to detect you changing it. But if you connect two accounts right away - it will detect you switching between them and reflect your changes on its interface.
I tested this with PCS.
Solution 2:[2]
this is the correct way of implementation:
useEffect(() => {
ethereum?.on("accountsChanged", handleAccountChange);
return () => {
ethereum?.removeListener("accountsChanged", handleAccountChange);
};
});
Now write a listener for account change
const handleAccountChange = (...args) => {
// you can console to see the args
const accounts = args[0] ;
// if no accounts that means we are not connected
if (accounts.length === 0) {
console.log("Please connect to metamask");
// our old data is not current connected account
// currentAccount account that you already fetched and assume you stored it in useState
} else if (accounts[0] !== currentAccount) {
// if account changed you should update the currentAccount so you return the updated the data
// assuming you have [currentAccount,setCurrentAccount]=useState
// however you are tracking the state currentAccount, you have to update it. in case of redux you have to dispatch update action etc
setCurrentAccount(accounts[0)
}
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Yilmaz |