Web3 Default Account – Better Patterns for Detection with Metamask

javascriptmetamaskweb3-providersweb3js

Context: I want to use blockies to render an identicon on the page, i get the defaultAccount from web3, for this, the user has to be logged on to metamask with a selected address from his wallet.

The problem: the web app seems to not detect the web3 object on the load event of the page, wchih is the recommended place to detect it.

The code: below is inspired from recommendations at:

https://github.com/MetaMask/metamask-plugin/issues/1158

https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#partly_sunny-web3—ethereum-browser-environment-check

I keep having intermittent behaviour, sometimes web3 is there and sometimes it is not, the only solution I can think of is to have a timer, but that seems to me a bit too simplistic, I would prefer something more elegant.

Question: Is there a better solution to detect the defaultAccount from web3 when the page loads?

 function startApp() { 
        GenerateIdenticon();  
}  


window.addEventListener('load', function () { 

// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {

    // Use Mist/MetaMask's provider
    window.web3 = new Web3(web3.currentProvider); 
    if (web3.currentProvider.isMetaMask === true) {
        if (typeof web3.eth.defaultAccount === 'undefined') {
            document.body.innerHTML = '<body><h1>Oops! Your browser does not support Ethereum Ðapps.</h1></body>';   
        }
        else {
            startApp();
        }
    }
    else {
         alert('No web3? Please use google chrome and metamask plugin to enter this Dapp!', null, null);
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
       window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

Best Answer

The one method that is more reliable than the in-page accounts array is web3.eth.getAccounts(accounts => console.log(accounts[0])).

This will asynchronously request the accounts array, and call back whenever it's available.

Related Topic