Skip to content

Commit

Permalink
[Gateway] enable metamask desktop and mobile support (#1697)
Browse files Browse the repository at this point in the history
* fix: metamask on mobile

* test switching to ten network on mobile
  • Loading branch information
Jennievon authored Dec 15, 2023
1 parent 6605017 commit 5c4e75d
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 52 deletions.
12 changes: 4 additions & 8 deletions tools/walletextension/frontend/src/api/ethRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ export const switchToTenNetwork = async () => {
});

return 0;
} catch (error: any) {
return error.code;
} catch (switchError: any) {
showToast(ToastType.DESTRUCTIVE, `switchToTenNetwork: ${switchError.code}`);
return switchError.code;
}
};

Expand Down Expand Up @@ -83,14 +84,9 @@ export const getSignature = async (account: string, data: any) => {
};

export const getToken = async (provider: ethers.providers.Web3Provider) => {
if (!provider) {
showToast(
ToastType.DESTRUCTIVE,
"No provider found. Please try again later."
);
if (!provider.send) {
return null;
}

try {
if (await isTenChain()) {
const token = await provider.send(requestMethods.getStorageAt, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function Footer() {
const { version } = useWalletConnection();

return (
<div className="border-t px-2">
<div className="flex h-16 items-center px-4">
<div className="flex-1 flex items-center space-x-4">
<div className="border-t p-2">
<div className="flex h-16 items-center justify-between px-4 flex-wrap">
<div className="flex items-center space-x-4 pr-2">
<a
href={socialLinks.github}
aria-label="GitHub"
Expand All @@ -36,7 +36,7 @@ export default function Footer() {
<DiscordLogoIcon />
</a>
</div>
<div className="flex-1 flex items-center justify-center">
<div className="flex items-center justify-center space-x-4 pr-2">
<h3 className="text-xs text-muted-foreground">
Version: {version || "Unknown"}
</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const Connected = () => {
</TableRow>
) : (
accounts.map((account: Account, i: number) => (
<TableRow key={i}>
<TableRow key={account.name}>
<TableCell className="font-medium">
<TruncatedAddress address={account.name} />
</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Account,
} from "../../types/interfaces/WalletInterfaces";
import { showToast } from "../ui/use-toast";
import { ethereum } from "../../lib/utils";
import { ethereum, isValidTokenFormat } from "../../lib/utils";
import {
accountIsAuthenticated,
fetchVersion,
Expand Down Expand Up @@ -44,25 +44,23 @@ export const WalletConnectionProvider = ({
const [provider, setProvider] = useState({} as ethers.providers.Web3Provider);

const initialize = async () => {
if (!provider) {
return showToast(
ToastType.INFO,
"Provider is required to initialize wallet connection."
);
}

try {
if (!ethereum) {
showToast(
ToastType.DESTRUCTIVE,
"Please install Metamask to connect your wallet."
);
return;
}
const providerInstance = new ethers.providers.Web3Provider(ethereum);
setProvider(providerInstance);
await ethService.checkIfMetamaskIsLoaded(providerInstance);
await ethService.checkIfMetamaskIsLoaded(provider);

const fetchedToken = await getToken(providerInstance);
const fetchedToken = await getToken(provider);
setToken(fetchedToken);

const status = await ethService.isUserConnectedToTenChain(fetchedToken);
setWalletConnected(status);

const accounts = await ethService.getAccounts(providerInstance);
const accounts = await ethService.getAccounts(provider);
setAccounts(accounts || null);
setVersion(await fetchVersion());
} catch (error) {
Expand Down Expand Up @@ -105,7 +103,7 @@ export const WalletConnectionProvider = ({
} else {
showToast(ToastType.DESTRUCTIVE, "Account authentication failed.");
}
} catch (error) {
} catch (error: any) {
showToast(ToastType.DESTRUCTIVE, "Account authentication failed.");
}
};
Expand Down Expand Up @@ -135,35 +133,72 @@ export const WalletConnectionProvider = ({
);
return;
}
const token = await getToken(provider);

if (!isValidTokenFormat(token)) {
showToast(
ToastType.INFO,
"Invalid token format. Please refresh the page."
);
setAccounts([]);
setWalletConnected(false);
return;
}

setToken(token);

try {
const accounts = await ethService.getAccounts(provider);
const token = await getToken(provider);
setToken(token);
let updatedAccounts: Account[] = [];

updatedAccounts = await Promise.all(
accounts!.map(async (account) => {
await ethService.authenticateWithGateway(token, account.name);
const { status } = await accountIsAuthenticated(token, account.name);
return {
...account,
connected: status,
};
})
if (!accounts || accounts.length === 0) {
setAccounts([]);
} else {
updatedAccounts = await Promise.all(
accounts!.map(async (account) => {
await ethService.authenticateWithGateway(token, account.name);
const { status } = await accountIsAuthenticated(
token,
account.name
);
return {
...account,
connected: status,
};
})
);
showToast(ToastType.INFO, "Accounts authenticated with gateway!");
setAccounts(updatedAccounts);
}
} catch (error: any) {
showToast(
ToastType.DESTRUCTIVE,
`Error fetching user accounts: ${error?.message}`
);
setAccounts(updatedAccounts || null);
} catch (error) {
showToast(ToastType.DESTRUCTIVE, "Error fetching user accounts.");
} finally {
setWalletConnected(true);
setLoading(false);
}
};

useEffect(() => {
initialize();
// eslint-disable-next-line react-hooks/exhaustive-deps
if (ethereum && ethereum.isMetaMask) {
const providerInstance = new ethers.providers.Web3Provider(ethereum);
setProvider(providerInstance);
initialize();

ethereum.on("accountsChanged", () => {
fetchUserAccounts();
});
}

return () => {
if (ethereum && ethereum.removeListener) {
ethereum.removeListener("accountsChanged", () => {
fetchUserAccounts();
});
}
};
}, []);

const walletConnectionContextValue: WalletConnectionContextType = {
Expand Down
3 changes: 2 additions & 1 deletion tools/walletextension/frontend/src/services/ethService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const ethService = {
})
);
updatedAccounts = await Promise.all(authenticationPromise);
showToast(ToastType.SUCCESS, "Account authentication status updated!");
showToast(ToastType.INFO, "Account authentication status updated!");
return updatedAccounts;
},

Expand Down Expand Up @@ -135,6 +135,7 @@ const ethService = {
} catch (error) {
console.error(error);
showToast(ToastType.DESTRUCTIVE, "An error occurred. Please try again.");
throw error;
}
},

Expand Down
27 changes: 19 additions & 8 deletions tools/walletextension/frontend/src/services/useGatewayService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import { ToastType } from "@/types/interfaces";
import { joinTestnet } from "../api/gateway";
import { useWalletConnection } from "../components/providers/wallet-provider";
import { showToast } from "../components/ui/use-toast";
import {SWITCHED_CODE, tenGatewayAddress, tenGatewayVersion} from "../lib/constants";
import {
SWITCHED_CODE,
tenGatewayAddress,
tenGatewayVersion,
} from "../lib/constants";
import { isTenChain, isValidTokenFormat } from "../lib/utils";
import {
addNetworkToMetaMask,
connectAccounts,
getToken,
switchToTenNetwork,
} from "@/api/ethRequests";

Expand All @@ -28,37 +33,43 @@ const useGatewayService = () => {
};

const connectToTenTestnet = async () => {
showToast(ToastType.INFO, "Connecting to Obscuro Testnet...");
setLoading(true);
try {
if (await isTenChain()) {
if (!token || !isValidTokenFormat(token)) {
showToast(
ToastType.DESTRUCTIVE,
"Existing Ten network detected in MetaMask. Please remove before hitting begin"
"Existing Obscuro Testnet detected in MetaMask. Please remove before hitting begin"
);
return;
}
}

showToast(ToastType.INFO, "Switching to Obscuro Testnet...");
const switched = await switchToTenNetwork();

if (switched === SWITCHED_CODE || (token && !isValidTokenFormat(token))) {
showToast(ToastType.SUCCESS, `Switched to Obscuro Testnet: ${switched}`);
// SWITCHED_CODE=4902; error 4902 means that the chain does not exist
if (
switched === SWITCHED_CODE ||
!isValidTokenFormat(await getToken(provider))
) {
showToast(ToastType.INFO, "Adding Obscuro Testnet...");
const user = await joinTestnet();
const rpcUrls = [
`${tenGatewayAddress}/${tenGatewayVersion}/?token=${user}`,
];
await addNetworkToMetaMask(rpcUrls);
showToast(ToastType.SUCCESS, "Added Obscuro Testnet");
}

if (!(await isMetamaskConnected())) {
showToast(ToastType.INFO, "No accounts found, connecting...");
await connectAccounts();
showToast(ToastType.SUCCESS, "Connected to Ten Network");
showToast(ToastType.SUCCESS, "Connected to Obscuro Testnet");
}

await fetchUserAccounts();
} catch (error: any) {
showToast(ToastType.DESTRUCTIVE, `${error}`);
showToast(ToastType.DESTRUCTIVE, `${error?.message}`);
throw error;
} finally {
setLoading(false);
Expand Down

0 comments on commit 5c4e75d

Please sign in to comment.