2

I'm using metamask/detect-provider to make a simple button that connects to the metamask extension following the metamask documentation. However, it returns

Typescript error Cannot find name 'ethereum'. TS3204 when I do npm start. Does anyone know the reason for this error?

import Web3 from 'web3';
import { Message, Button } from "semantic-ui-react";
import 'semantic-ui-css/semantic.min.css';
import detectEthereumProvider from '@metamask/detect-provider';
import './App.css';

function App() {
  const loadMetamask = () => {
    ethereum.request({ method: 'eth_requestAccounts' });
  }
  return (
    <div className="App">
      <div className="App-header">
        <h1>Testing</h1>

        <Message warning>Metamask is not connected</Message>
        <button color="green"
          onClick={() => loadMetamask()}
        >Connect to Metamask</button>
      </div>
    </div>
  );
}
export default App;
TylerH
  • 20,799
  • 66
  • 75
  • 101
mortem
  • 23
  • 3

1 Answers1

4

This is due to typescript compiler couldn't find the ethereum module as ethereum module is in global window.

There are few ways to solve it.

First way, create your own type definition for window.ethereum. You may refer to here Web3.js extending the window interface type definitions

Second way, ask typescript compiler to ignore the error, which is not recommended as it beat the purpose of using typescript.

//@ts-ignore
 ethereum.request({ method: 'eth_requestAccounts' });

Last way, which is the laziest way. @metamask/provides did provide the type definition for window.ethereum. Therefore, we install it by running

npm i @metamask/providers

After that, import the class

import { MetaMaskInpageProvider } from '@metamask/providers';

Then, tell the typescript compiler to treat window.ethereum as MetaMaskInpageProvider

const ethereum = window.ethereum as MetaMaskInpageProvider;

Now, you should be able to

ethereum.request<string[]>({ method: 'eth_requestAccounts' });

Your code should looks similar to below

import Web3 from 'web3';
import { Message, Button } from "semantic-ui-react";
import 'semantic-ui-css/semantic.min.css';
import detectEthereumProvider from '@metamask/detect-provider';
import { MetaMaskInpageProvider } from '@metamask/providers';
import './App.css';

function App() {
  const loadMetamask = async () => {
    // You need to await for user response on the metamask popup dialog
    const accounts = await ethereum.request<string[]>({ method: 'eth_requestAccounts' });
    if(accounts){
       console.log(accounts[0]);
    }
  }
  return (
    <div className="App">
      <div className="App-header">
        <h1>Testing</h1>

        <Message warning>Metamask is not connected</Message>
        <button color="green"
          onClick={() => loadMetamask()}
        >Connect to Metamask</button>
      </div>
    </div>
  );
}
export default App;

Even though it works, but we installed unused @metamask/providers library.

kampung-tech
  • 386
  • 1
  • 6