15

I want to know what provider the user is using (Metamaks, Mist...)so I can give better user experience. E.g. Give tips on how to unlock an account

I'm currently doing this, but is far from elegant. Is there a more correct/reliable way achieve the same?

getProviderName=()=>
{
    let providerName = "UNKNOWN"

    if(window.web3.currentProvider.constructor.name === "MetamaskInpageProvider")        
        providerName = "METAMASK"

    else if(window.web3.currentProvider.constructor.name === "EthereumProvider")        
        providerName = "MIST"

    else if(window.web3.currentProvider.constructor.name === "o")        
        providerName = "PARITY"

    else if(window.web3.currentProvider.host.indexOf("infura")!==-1) 
        providerName = "INFURA"      

    else if(window.web3.currentProvider.host.indexOf("localhost")!==-1)  
        providerName ="LOCALHOST"

    return providerName
}
1
  • Interesting that a few years on and there is no real elegant solution? Also nobody mentioned that webpack uglification etc. breaks the constructor.name approach, unless classnames are excluding from webpack config. – robertdavid Nov 26 '20 at 10:13
9

This my current implementation:

getCurrentProvider() {
    if (!window.web3) return 'unknown';

    if (window.web3.currentProvider.isMetaMask)
        return 'metamask';

    if (window.web3.currentProvider.isTrust)
        return 'trust';

    if (window.web3.currentProvider.isGoWallet)
        return 'goWallet';

    if (window.web3.currentProvider.isAlphaWallet)
        return 'alphaWallet';

    if (window.web3.currentProvider.isStatus)
        return 'status';

    if (window.web3.currentProvider.isToshi)
        return 'coinbase';

    if (typeof window.__CIPHER__ !== 'undefined')
        return 'cipher';

    if (window.web3.currentProvider.constructor.name === 'EthereumProvider')
        return 'mist';

    if (window.web3.currentProvider.constructor.name === 'Web3FrameProvider')
        return 'parity';

    if (window.web3.currentProvider.host && window.web3.currentProvider.host.indexOf('infura') !== -1)
        return 'infura';

    if (window.web3.currentProvider.host && window.web3.currentProvider.host.indexOf('localhost') !== -1)
        return 'localhost';

    return 'unknown';
},
2
  • 1
    Coinbase Wallet currently includes an isToshi flag, which may be more appropriate than using the SOFA detection strategy. – Micah Alcorn Nov 23 '18 at 21:33
  • this won't work with 1.0.0-beta, use window.ethereum.isMetaMask instead – Cody Django Mar 2 '19 at 22:32
3

I am looking for a better way myself, at least for metamask I found that you can do that:

window.web3.currentProvider.isMetaMask

1

MetaMask announced a breaking fix to a security issue that relates to the answer of @Arash Kiani and @mager. When you follow it then you need ...

// Modern dapp browsers...
if (window.ethereum) {
    window.web3 = new Web3(ethereum);
    try {
        // Request account access if needed
        await ethereum.enable();
        // Acccounts now exposed
        web3.eth.sendTransaction({/* ... */});
    } catch (error) {
        // User denied account access...
    }
}
// Legacy dapp browsers...
else if (window.web3) {
    window.web3 = new Web3(web3.currentProvider);
    // Acccounts always exposed
    web3.eth.sendTransaction({/* ... */});
}

I only noticed it when investigation the console. The break will be effective from Nov 2 2018!

source: https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8

0

How about this:

import Web3 from 'web3';

let web3;

if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
  // We are in the browser and metamask is running.
  web3 = new Web3(window.web3.currentProvider);
} else {
  // We are on the server *OR* the user is not running metamask
  const provider = new Web3.providers.HttpProvider(
    'https://rinkeby.infura.io/foo',
  );
  web3 = new Web3(provider);
}

export default web3;
0

window.web3 has being depreciated, according to the documentation its recommended to use the following:

import Web3 from 'web3';
const web3 = new Web3(Web3.givenProvider || "ws://localhost:8546");
console.log(web3.currentProvider.isMetaMask)
1
  • This is only for version 1.x of web3 – Laxmana Jul 27 '18 at 14:31

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.