Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@metamask/detect-provider: Unable to detect window.ethereum. #38

Open
caio1985 opened this issue Jan 22, 2022 · 7 comments
Open

@metamask/detect-provider: Unable to detect window.ethereum. #38

caio1985 opened this issue Jan 22, 2022 · 7 comments

Comments

@caio1985
Copy link

caio1985 commented Jan 22, 2022

I'm building a hybrid app using Ionic.

When I serve the app in the browser (Chrome), it works fine asking for the Metamask authentication (opens Metamask as expected).

However when I build that for native Android (I'm using Capacitor), even though the app opens on my Android phone normally after I launch it from Android Studio, it does not ask me to authenticate with Metamask.

After doing some troubleshoot I attached to the app (via Chrome Device Inspect) running on my real phone which is plugged via USB in my computer, and this is what I get on the native app:

common.js:166 @metamask/detect-provider: Unable to detect window.ethereum.
handleEthereum @ common.js:166
23:50:21.508 vendor.js:86490 ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of null (reading 'request')
TypeError: Cannot read properties of null (reading 'request')
    at src_app_home_home_module_ts.js:272:22
    at ZoneDelegate.invoke (polyfills.js:413:30)
    at Object.onInvoke (vendor.js:108502:25)
    at ZoneDelegate.invoke (polyfills.js:412:56)
    at Zone.run (polyfills.js:173:47)
    at polyfills.js:1331:38
    at ZoneDelegate.invokeTask (polyfills.js:447:35)
    at Object.onInvokeTask (vendor.js:108490:25)
    at ZoneDelegate.invokeTask (polyfills.js:446:64)
    at Zone.runTask (polyfills.js:218:51)
    at resolvePromise (polyfills.js:1268:35)
    at polyfills.js:1338:21
    at ZoneDelegate.invokeTask (polyfills.js:447:35)
    at Object.onInvokeTask (vendor.js:108490:25)
    at ZoneDelegate.invokeTask (polyfills.js:446:64)
    at Zone.runTask (polyfills.js:218:51)
    at drainMicroTaskQueue (polyfills.js:633:39)
    at ZoneTask.invokeTask (polyfills.js:533:25)
    at ZoneTask.invoke (polyfills.js:518:52)
    at data.args.<computed> (polyfills.js:3076:36)

What should I do in order to have the native app being able to authenticate with the Metamask installed app?

Thanks!

@DeoThemes
Copy link

I'm getting this in the web app in Chrome, Even a basic example from docs throws this error. I tried to run it on http or https, no difference.

@stramec
Copy link

stramec commented Aug 12, 2022

DeoThemes

Did you figure this out at all? I am getting the same thing. Production web app served over https. Works fine in the browser on desktop, but doesn't find the metaMask app on iOS or Android.

@caio1985
Copy link
Author

Unfortunately I didn't manage to solve the problem.

@mcmire
Copy link
Contributor

mcmire commented Aug 12, 2022

@caio1985 @stramec Are you accessing your app within the MetaMask browser on mobile or outside the app?

@stramec
Copy link

stramec commented Aug 12, 2022

@caio1985 @stramec Are you accessing your app within the MetaMask browser on mobile or outside the app?

Perhaps I have misunderstood how this works, but one testing scenario is we have our web app open in say iOS chrome. The test mobile has the metamask app installed. From the docs it states "We recommend using @metamask/detect-provider (opens new window)to detect our provider, on any platform or browser." so I assumed it would therefore realise the metamask Apple app is installed and continue from there.

It works fine with the browser extension installed on the desktop. Have I assumed incorrectly on the mobile app side?

@mcmire
Copy link
Contributor

mcmire commented Aug 15, 2022

@stramec

I think the docs could be more helpful here, but mobile doesn't work like you may think.

On the desktop side, you will install the MetaMask extension in your browser. The extension provides a UI for you to use MetaMask, which you know, but it also injects a script into every single page that you visit (with some exceptions). It's this injected script that makes it possible for a dapp to interact with the extension via window.ethereum. All the detect-provider library does is look for the presence of this property on window (as well as window.ethereum.isMetaMask, which we set to distinguish ourselves, in case other browser extensions also set window.ethereum).

Mobile is different because we don't provide MetaMask through a browser extension, we offer a separate app. Apps can't talk directly to each other, so if you have a dapp open in iOS Chrome, iOS Safari, Android Chrome, Android Firefox, etc., the site can't know that you have MetaMask installed, because no such script is injected on the page like it is in the browser on desktop. So does this mean that it's impossible for a dapp running on mobile to detect MetaMask? No, because MetaMask-the-app has a browser built into it, and this browser injects a script onto every page that's visited. That means that in order to provide the experience you want, you need users to visit the dapp from within MetaMask, not outside of it. To help with user experience, you may want to update the code in your dapp such that if detect-provider can't detect the presence of window.ethereum, you can assume that the user isn't within MetaMask and show a deeplink that (re)opens your dapp within MetaMask instead. We have a deeplink generator you can use here: https://metamask.github.io/metamask-deeplinks.

I hope that helps!

@stramec
Copy link

stramec commented Aug 15, 2022

Perfect answer, cheers @mcmire - all makes sense now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants