Server Bug Fix: How do you normalize client-side web3 libraries?

Original Source Link

In my web front-end, I need the ability to interact with the Ethereum blockchain.

  1. It’s possible a user has MetaMask installed.
  2. It’s possible a user is using the web without MetaMask installed.
  3. It’s possible a user is using an old dApp browser.
  4. It’s possible a user is using a modern dApp browser.

The following code takes care of all possibilities, and injects ethers.js as a last resort:

if (window.ethereum) { // Modern dapp browsers...
    window.web3 = new Web3(ethereum);
} else if (window.web3) { // Legacy dapp browsers...
    window.web3 = new Web3(web3.currentProvider);
} else { // Non-dapp browsers...
    window.web3 = ethers; // ethersjs provided library

It works! Great! I can make web3.eth.getBalance() calls and such.

Here’s where it gets hairy:

It appears that the exposed interface for dealing with Contracts is not uniform across libraries, both in terms of the constructor and order of parameters.

Have I approached this entirely wrong?

In your code:

window.web3 = new Web3(ethereum);
window.web3 = new Web3(web3.currentProvider);
window.web3 = ethers; // ethersjs provided library

Since web3.js and ethers.js are obviously two different modules (most likely implemented by two different groups), they have no reason to share the exact same API.

The fact that you can set your window.web3 to both is only because Javascript is a weakly-typed language, which allows you to do that at your own risk (of getting a runtime exception).

If you want to use both in a transparent manner, then you’ll need to implement a wrapper with a unified API.

Some details on the difference between strongly-typed languages and weakly-typed languages:

  • A strongly-typed language has stricter typing rules at compile time, which implies that errors and exceptions are more likely to happen during compilation.
  • A weakly-typed language has looser typing rules and may produce unpredictable results or may perform implicit type conversion at runtime.

I used to use the code you are using. When you assign your provider to window.web3 things will go wrong ( I don’t remember why ). But i changed my code and assigned my provider to a variable, also changed the way i check for the web3 existance and it worked without any problems:

Here is the Code:

let web3
if(typeof window !== 'undefined' && typeof window.ethereum !== 'undefined'){
  //getting Permission to access MetaMask
  web3 = new Web3(window.ethereum);

}else if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
  web3 = new Web3(window.web3.currentProvider);
  // In legacy MetaMasks, acccounts are always exposed

} else {
  // No Web3 detected
  const provider = new Web3.providers.HttpProvider(
  web3 = new Web3(provider);


Make sure to change the last part and replace it with your own provider.

Tagged : / / /