Skip to content

Commit

Permalink
feat: added detect wallet environment hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Jadapema committed Jan 10, 2025
1 parent 247f005 commit aca7dc6
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
12 changes: 6 additions & 6 deletions src/hooks/use-deposit-metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import MMCAbi from '@src/config/abi/MMC.json';
import { GLOBAL_CONSTANTS } from '@src/config-global';
import { publicClient } from '@src/clients/viem/publicClient';
import { ERRORS } from '@notifications/errors.ts';
// import { notifyInfo } from '@notifications/internal-notifications.ts';
// import { INFO } from '@notifications/info.ts';
import { notifyInfo } from '@notifications/internal-notifications.ts';
import { INFO } from '@notifications/info.ts';
import { useMetaMask } from '@src/hooks/use-metamask.ts';
import { enqueueSnackbar } from 'notistack';

Expand Down Expand Up @@ -47,7 +47,7 @@ export const useDepositMetamask = (): UseDepositHook => {
const weiAmount = parseUnits(amount.toString(), 18);

// Notify the user that we are sending approve transaction to the network
// notifyInfo(INFO.APPROVE_SENDING_CONFIRMATION, { options: { autoHideDuration: 3000 } });
notifyInfo(INFO.APPROVE_SENDING_CONFIRMATION, { options: { autoHideDuration: 3000 } });

// 2) First transaction: approve
const approveTxHash = await walletClient?.writeContract({
Expand All @@ -60,15 +60,15 @@ export const useDepositMetamask = (): UseDepositHook => {
});

// Notify the user that we are now waiting for the approve transaction to be confirmed
// notifyInfo(INFO.APPROVE_WAITING_CONFIRMATION, { options: { autoHideDuration: 7000 } });
notifyInfo(INFO.APPROVE_WAITING_CONFIRMATION, { options: { autoHideDuration: 7000 } });

// Wait for the approve transaction to be mined
const approveReceipt = await publicClient.waitForTransactionReceipt({
hash: approveTxHash as Address,
});

// Notify the user that we are now sending the deposit transaction
// notifyInfo(INFO.DEPOSIT_SENDING_CONFIRMATION, { options: { autoHideDuration: 3000 } });
notifyInfo(INFO.DEPOSIT_SENDING_CONFIRMATION, { options: { autoHideDuration: 3000 } });

// 3) Second transaction: deposit
const depositTxHash = await walletClient?.writeContract({
Expand All @@ -81,7 +81,7 @@ export const useDepositMetamask = (): UseDepositHook => {
});

// Notify the user that we are now waiting for the deposit transaction to be confirmed
// notifyInfo(INFO.DEPOSIT_WAITING_CONFIRMATION, { options: { autoHideDuration: 7000 } });
notifyInfo(INFO.DEPOSIT_WAITING_CONFIRMATION, { options: { autoHideDuration: 7000 } });

// Wait for the deposit transaction to be mined
const depositReceipt = await publicClient.waitForTransactionReceipt({
Expand Down
54 changes: 45 additions & 9 deletions src/hooks/use-detect-wallet-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,57 @@ export function useDetectWalletEnvironment(): WalletEnvironment {
});

useEffect(() => {
// Make sure we're on a client (browser) environment
// Early return for SSR (no window object)
if (typeof window === 'undefined') return;

// 1) Check user agent for mobile
// 1) Detect mobile device
const userAgent = navigator.userAgent || navigator.vendor || '';
const isMobile = /android|mobile|iphone|ipad|ipod|blackberry|opera mini|iemobile/i.test(userAgent);
const lowerUA = userAgent.toLowerCase();
const isMobile = /android|mobile|iphone|ipad|ipod|blackberry|opera mini|iemobile/i.test(lowerUA);

// 2) Check if MetaMask is installed
const ethereum = (window as any).ethereum;
const isMetaMaskInstalled = Boolean(ethereum && ethereum.isMetaMask);
// 2) Access "ethereum" and analyze it
const { ethereum } = window as any;
let isMetaMaskInstalled = false;

// 3) Determine if we’re in MetaMask in-app browser on mobile
// (some folks also do userAgent.includes('MetaMaskMobile') as an extra check).
const isMetaMaskInAppBrowser = isMobile && isMetaMaskInstalled;
// - Case A: a single provider (not an array of providers)
if (ethereum && !ethereum.providers) {
// Check the classic "isMetaMask" flag
if (ethereum.isMetaMask) {
isMetaMaskInstalled = true;
} else {
// Check for internal "marks" (heuristics)
// Some older versions might expose ethereum._metamask
// or ethereum.providerMap?.MetaMask
if (ethereum._metamask?.isUnlocked !== undefined) {
// Not 100% official, but sometimes indicates MetaMask
isMetaMaskInstalled = true;
}
if (ethereum.providerMap?.MetaMask) {
isMetaMaskInstalled = true;
}
}
}

// - Case B: multiple providers
if (ethereum && Array.isArray(ethereum.providers)) {
const metaMaskProvider = ethereum.providers.find((prov: any) => prov.isMetaMask);
if (metaMaskProvider) {
isMetaMaskInstalled = true;
}
}

// 3) Determine if it is MetaMask in-app browser (only applies if isMobile + isMetaMaskInstalled)
// We can heuristically check if the userAgent includes specific strings
// from the mobile MetaMask app, such as "MetaMaskMobile" or "metamask".
let isMetaMaskInAppBrowser = false;
if (isMobile && isMetaMaskInstalled) {
// Simple heuristic
if (lowerUA.includes('metamask') || lowerUA.includes('metamaskmobile')) {
isMetaMaskInAppBrowser = true;
}
}

// 4) Update final state
setEnvironment({
isMobile,
isMetaMaskInstalled,
Expand Down
7 changes: 3 additions & 4 deletions src/sections/finance/components/finance-deposit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ import { UseDepositHook } from '@src/hooks/use-deposit';
import { truncateAddress } from '@src/utils/wallet';

// NOTIFICATIONS IMPORTS
// import { notifyError, notifySuccess, notifyWarning } from '@notifications/internal-notifications';
import { notifySuccess, notifyWarning } from '@notifications/internal-notifications';
import { notifyError, notifySuccess, notifyWarning } from '@notifications/internal-notifications';
import { WARNING } from '@notifications/warnings';
import { SUCCESS } from '@notifications/success';
// import { ERRORS } from '@notifications/errors.ts';
import { ERRORS } from '@notifications/errors.ts';
import TextField from '@mui/material/TextField';

interface FinanceDepositProps {
Expand Down Expand Up @@ -75,7 +74,7 @@ const FinanceDeposit: FC<FinanceDepositProps> = ({ address, recipient, depositHo

useEffect(() => {
if (error) {
// notifyError(error as ERRORS);
notifyError(error as ERRORS);
}
}, [error]);

Expand Down

0 comments on commit aca7dc6

Please sign in to comment.