Элегантный способ определить текущего провайдера int web3.js

Я хочу знать, какого провайдера использует пользователь (Metamaks, Mist...), чтобы улучшить взаимодействие с пользователем. Например , дайте советы о том, как разблокировать учетную запись.

Я сейчас делаю это, но это далеко не элегантно. Есть ли более правильный/надежный способ добиться того же?

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
}
Интересно, что прошло несколько лет, а настоящего элегантного решения нет? Кроме того, никто не упомянул, что uglification веб-пакета и т. Д. Нарушает constructor.nameподход, если только имена классов не исключаются из конфигурации веб-пакета.

Ответы (6)

Это моя текущая реализация:

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';
},
Coinbase Wallet в настоящее время включает isToshiфлаг, который может быть более подходящим, чем использование SOFAстратегии обнаружения.
это не будет работать с 1.0.0-beta, используйте window.ethereum.isMetaMaskвместо этого

Я сам ищу лучший способ, по крайней мере, для метамаски я обнаружил, что вы можете это сделать:

window.web3.currentProvider.isMetaMask

MetaMask объявила о серьезном исправлении проблемы безопасности, связанной с ответом @Arash Kiani и @mager. Когда вы следуете ему, вам нужно ...

// 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({/* ... */});
}

Я заметил это только при исследовании консоли. Перерыв вступит в силу со 2 ноября 2018 года!

источник: https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8

Как насчет этого:

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;

window.web3 устарел, согласно документации рекомендуется использовать следующее:

import Web3 from 'web3';
const web3 = new Web3(Web3.givenProvider || "ws://localhost:8546");
console.log(web3.currentProvider.isMetaMask)
Это только для версии 1.x web3

Если вы используете web3 Modal, вы можете использоватьif(localStorage.getItem('WEB3_CONNECT_CACHED_PROVIDER')!==''){ return localStorage.getItem('WEB3_CONNECT_CACHED_PROVIDER'); }