MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites
https://metamask.io
Other
11.84k stars 4.83k forks source link

MetaMask injects it's own version of web3.js which replaces the one used in custom code #7211

Closed olegabr closed 3 years ago

olegabr commented 4 years ago

Describe the bug

MetaMask injects it's own version of web3.js which replaces the one used in custom code. It makes web3.js patching impossible. More details here: https://github.com/INFURA/infura/issues/189

To Reproduce Steps to reproduce the behavior:

  1. make any project using web3.js lib (or install the https://wordpress.org/plugins/ether-and-erc20-tokens-woocommerce-payment-gateway/ wordpress plugin). I'm using the 0.20.7 web3.js version.
  2. customize your copy of the web3.js lib in a visible way (add logs for example)
  3. run your project and look for side effects made by your changes
  4. See no side effects

Expected behavior The web3.js version loaded on the page should be used by user code. The MetaMask loaded code should not be used instead.

Screenshots Screenshot from 2019-09-24 17-49-38

Browser details (please complete the following information):

Additional context

my web3.js 0.20.7 branch patch (trying to fix the https://github.com/INFURA/infura/issues/189):

s$ git diff dist/web3.js
diff --git a/dist/web3.js b/dist/web3.js
index 841d09bf..c20fd669 100644
--- a/dist/web3.js
+++ b/dist/web3.js
@@ -3735,6 +3735,9 @@ var inputCallFormatter = function (options){
     if (options.from) {
         options.from = inputAddressFormatter(options.from);
     }
+    if (null === options.from) {
+        delete options.from;
+    }

     if (options.to) { // it might be contract creation
         options.to = inputAddressFormatter(options.to);
kumavis commented 4 years ago

@olegabr hello/ I'm not aware of anything changing about the injection logic recently. When did you start to see the new behavior? Can you show where you're adding and calling your custom web3?

olegabr commented 4 years ago

Thank you for your answer @kumavis, This behaviour is not new. MM always injected it's web3.js version in a page. It was just not a problem for me until recently.

my custom web3 code:

    if ("undefined" !== typeof window.epg.web3Endpoint) {
        window.epg.web3 = new Web3(new Web3.providers.HttpProvider(window.epg.web3Endpoint));
    }

window.epg.web3Endpoint - is an infura.io URL

In PHP code my web3.js copy is loaded by

            wp_register_script(
                'web3', $base_url . "/js/web3{$min}.js", array('jquery'), '0.20.6'
            );

and later

            wp_enqueue_script(
                'wooetherc20paymentgateway', 
                $base_url . "/js/ether-and-erc20-tokens-woocommerce-payment-gateway{$min}.js", 
                array('jquery', 'bootstrap.wizard', 'web3', 'jquery.qrcode'), 
                '2.6.5'
            );

The MM web3 object is obtained this way:

        window.ethereum.enable().then(function(accounts) {
            var injectedProvider = window.ethereum;
            window.epg.web3metamask = new Web3(injectedProvider);
        }

And tx is sent by

        window.epg.web3metamask.eth.sendTransaction(/* ... */)

After writing all this I understood that my web3.js version is used for my window.epg.web3 object and MM web3.js version is used for the window.epg.web3metamask object, and this is a right behavior.

If you have no ideas how it can be made better, just close this issue please.

olegabr commented 4 years ago

I've checked in a debugger and I was wrong. Even when contract method on my own created web3 object is called, the MM version of web3.js is actually used, not the one I've loaded on my page.

olegabr commented 4 years ago

I've found a very ugly but workable workaround for my problem: https://github.com/INFURA/infura/issues/189#issuecomment-535937835 So, this isue is not urgent for me anymore. Feel free to close it if you see no way to fix it in a reasonable time.

Gudahtt commented 3 years ago

Thanks for the report!

I'll close this now, as we will no longer be injecting web3 at all as of v9.0.0 (See here: #7163), which will be released quite soon.