Skip to content

Commit

Permalink
fix: mm mobile browser pairing (#5887)
Browse files Browse the repository at this point in the history
  • Loading branch information
gomesalexandre authored Dec 19, 2023
1 parent c22736b commit 6370111
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
23 changes: 14 additions & 9 deletions src/context/WalletProvider/MetaMask/components/Connect.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react'
import React, { useCallback, useMemo, useState } from 'react'
import { isMobile } from 'react-device-detect'
import { useSelector } from 'react-redux'
import type { RouteComponentProps } from 'react-router-dom'
Expand All @@ -7,7 +7,11 @@ import { WalletActions } from 'context/WalletProvider/actions'
import { KeyManager } from 'context/WalletProvider/KeyManager'
import { useLocalWallet } from 'context/WalletProvider/local-wallet'
import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
import { checkIsMetaMask, checkIsSnapInstalled } from 'hooks/useIsSnapInstalled/useIsSnapInstalled'
import {
checkIsMetaMask,
checkisMetaMaskMobileWebView,
checkIsSnapInstalled,
} from 'hooks/useIsSnapInstalled/useIsSnapInstalled'
import { useWallet } from 'hooks/useWallet/useWallet'
import { getEthersProvider } from 'lib/ethersProviderSingleton'
import { selectShowSnapsModal } from 'state/slices/selectors'
Expand All @@ -27,7 +31,7 @@ export interface MetaMaskSetupProps
}

export const MetaMaskConnect = ({ history }: MetaMaskSetupProps) => {
const { dispatch, state, getAdapter, onProviderChange } = useWallet()
const { dispatch, getAdapter, onProviderChange } = useWallet()
const localWallet = useLocalWallet()
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
Expand All @@ -39,6 +43,7 @@ export const MetaMaskConnect = ({ history }: MetaMaskSetupProps) => {
}, [])

const isSnapsEnabled = useFeatureFlag('Snaps')
const isMetaMaskMobileWebView = useMemo(() => checkisMetaMaskMobileWebView(), [])

const pairDevice = useCallback(async () => {
setError(null)
Expand Down Expand Up @@ -83,7 +88,8 @@ export const MetaMaskConnect = ({ history }: MetaMaskSetupProps) => {
if (!isMetaMask) return dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: false })
const isSnapInstalled = await checkIsSnapInstalled()

if (isSnapsEnabled && !isSnapInstalled && showSnapModal) {
// We don't want to show the snaps modal on MM mobile browser, as snaps aren't supported on mobile
if (isSnapsEnabled && !isMetaMaskMobileWebView && !isSnapInstalled && showSnapModal) {
return history.push('/metamask/snap/install')
}

Expand All @@ -101,11 +107,12 @@ export const MetaMaskConnect = ({ history }: MetaMaskSetupProps) => {
}
setLoading(false)
}, [
onProviderChange,
getAdapter,
setErrorLoading,
dispatch,
localWallet,
onProviderChange,
isMetaMaskMobileWebView,
isSnapsEnabled,
showSnapModal,
history,
Expand All @@ -119,12 +126,10 @@ export const MetaMaskConnect = ({ history }: MetaMaskSetupProps) => {
.filter(x => !!x)
.join(':')

return window.location.assign(`https://metamask.app.link/dapp/${mmDeeplinkTarget}`)
return window.location.assign(`metamask://dapp//${mmDeeplinkTarget}`)
}, [])

// The MM mobile app itself injects a provider, so we'll use pairDevice once
// we've reopened ourselves in that environment.
return !state.provider && isMobile ? (
return isMobile && !isMetaMaskMobileWebView ? (
<RedirectModal
headerText={'walletProvider.metaMask.redirect.header'}
bodyText={'walletProvider.metaMask.redirect.body'}
Expand Down
11 changes: 11 additions & 0 deletions src/hooks/useIsSnapInstalled/useIsSnapInstalled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ export const checkIsMetaMask = pMemoize(
},
)

// https://github.com/MetaMask/metamask-sdk/blob/6230d8394157f53f1b020ae44601a0a69edc6155/packages/sdk/src/Platform/PlatfformManager.ts#L102C30-L111
export const checkisMetaMaskMobileWebView = () => {
if (typeof window === 'undefined') {
return false
}

return (
Boolean(window.ReactNativeWebView) && Boolean(navigator.userAgent.endsWith('MetaMaskMobile'))
)
}

export const useIsSnapInstalled = (): null | boolean => {
const [isSnapInstalled, setIsSnapInstalled] = useState<null | boolean>(null)

Expand Down

0 comments on commit 6370111

Please sign in to comment.