Web3.js – Metamask Stopped Injecting Web3. How to Inject Web3.js Properly?

dapp-developmentdjangometamaskweb3-providersweb3js

I've been running a Django application which allows users to sign up/log in using Metamask. Everything worked great until recent breaking changes:

In early 2021, MetaMask will no longer inject the web3.js API. You can still bring your own web3.js or similar library and use it with MetaMask. We will simply stop injecting a particular version of web3.js for you.

This is what I did before.

I DETECT METAMASK AS FOLLOWED –> This still works

if (typeof web3 !== 'undefined') {
    data['web3_status'] = true;
    if (web3.currentProvider.isMetaMask === true) {
      console.log('success');
    } else {
      console.log('detection failed)';
    }
  } else {
    console.log('detection failed');
};

I ASKED THE USER TO ENABLE –> This still works

var accounts = await ethereum.request({ method: 'eth_requestAccounts' });

I ASK THE USER TO SIGN A MESSAGE FOR VERIFICATION –> This doesn't work

web3.personal.sign(nonce, account, function(error, signature)

Metamask no longer injects web3.js. So I try'd injecting my own as followed.

In my html header

<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.2.9/web3.min.js"></script>` 

In metamask.js script

const provider = new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/<MY-API_KEY>');
const web3 = new Web3(provider);

I receive the following error when trying to sign;

metamask.js:51 Uncaught TypeError: Cannot read property 'personal' of undefined

Thank you for your time.

Best Answer

The metamask.js script seems incorrect.

There isn't enough code to test but you have to do something like this

const oldProvider = web3.currentProvider; // keep a reference to metamask provider

myWeb3 = new Web3(oldProvider);  // now you can use myWeb3 instead of web3

If the project is large you may want to replace web3 with myWeb3.

global.web3 = myWeb3
Related Topic