fix(wallet): check if snaps are supported (#4671)

This commit is contained in:
Art 2023-09-01 13:22:13 +02:00 committed by GitHub
parent 85a4981700
commit 39e5836edb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 57 deletions

View File

@ -1,6 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { import {
Dialog, Dialog,
ExternalLink,
Intent, Intent,
Pill, Pill,
TradingButton, TradingButton,
@ -39,7 +40,7 @@ import { useVegaWallet } from '../use-vega-wallet';
import { InjectedConnectorForm } from './injected-connector-form'; import { InjectedConnectorForm } from './injected-connector-form';
import { isBrowserWalletInstalled } from '../utils'; import { isBrowserWalletInstalled } from '../utils';
import { useIsWalletServiceRunning } from '../use-is-wallet-service-running'; import { useIsWalletServiceRunning } from '../use-is-wallet-service-running';
import { useIsSnapRunning } from '../use-is-snap-running'; import { SnapStatus, useSnapStatus } from '../use-snap-status';
import { useVegaWalletDialogStore } from './vega-wallet-dialog-store'; import { useVegaWalletDialogStore } from './vega-wallet-dialog-store';
export const CLOSE_DELAY = 1700; export const CLOSE_DELAY = 1700;
@ -158,7 +159,7 @@ const ConnectDialogContainer = ({
appChainId appChainId
); );
const isSnapRunning = useIsSnapRunning( const snapStatus = useSnapStatus(
DEFAULT_SNAP_ID, DEFAULT_SNAP_ID,
Boolean(connectors['snap']) Boolean(connectors['snap'])
); );
@ -183,7 +184,7 @@ const ConnectDialogContainer = ({
setWalletUrl={setWalletUrl} setWalletUrl={setWalletUrl}
onSelect={handleSelect} onSelect={handleSelect}
isDesktopWalletRunning={isDesktopWalletRunning} isDesktopWalletRunning={isDesktopWalletRunning}
isSnapRunning={isSnapRunning} snapStatus={snapStatus}
/> />
)} )}
</ConnectDialogContent> </ConnectDialogContent>
@ -198,14 +199,14 @@ const ConnectorList = ({
walletUrl, walletUrl,
setWalletUrl, setWalletUrl,
isDesktopWalletRunning, isDesktopWalletRunning,
isSnapRunning, snapStatus,
}: { }: {
connectors: Connectors; connectors: Connectors;
onSelect: (type: WalletType) => void; onSelect: (type: WalletType) => void;
walletUrl: string; walletUrl: string;
setWalletUrl: (value: string) => void; setWalletUrl: (value: string) => void;
isDesktopWalletRunning: boolean | null; isDesktopWalletRunning: boolean | null;
isSnapRunning: boolean | null; snapStatus: SnapStatus;
}) => { }) => {
const { pubKey, links } = useVegaWallet(); const { pubKey, links } = useVegaWallet();
const title = isBrowserWalletInstalled() const title = isBrowserWalletInstalled()
@ -249,7 +250,7 @@ const ConnectorList = ({
</div> </div>
{connectors['snap'] !== undefined ? ( {connectors['snap'] !== undefined ? (
<div> <div>
{isSnapRunning ? ( {snapStatus === SnapStatus.INSTALLED ? (
<ConnectionOption <ConnectionOption
type="snap" type="snap"
text={ text={
@ -267,8 +268,10 @@ const ConnectorList = ({
}} }}
/> />
) : ( ) : (
<>
<ConnectionOption <ConnectionOption
type="snap" type="snap"
disabled={snapStatus === SnapStatus.NOT_SUPPORTED}
text={ text={
<> <>
<div className="flex items-center justify-center w-full h-full text-base gap-1"> <div className="flex items-center justify-center w-full h-full text-base gap-1">
@ -283,6 +286,16 @@ const ConnectorList = ({
requestSnap(DEFAULT_SNAP_ID); requestSnap(DEFAULT_SNAP_ID);
}} }}
/> />
{snapStatus === SnapStatus.NOT_SUPPORTED ? (
<p className="pt-2 text-sm text-default">
{t('No MetaMask version that supports snaps detected.')}{' '}
{t('Learn more about')}{' '}
<ExternalLink href="https://metamask.io/snaps/">
MetaMask Snaps
</ExternalLink>
</p>
) : null}
</>
)} )}
</div> </div>
) : null} ) : null}

View File

@ -118,14 +118,10 @@ export const getSnap = async (
snapId: string, snapId: string,
version?: string version?: string
): Promise<Snap | undefined> => { ): Promise<Snap | undefined> => {
try {
const snaps = await getSnaps(); const snaps = await getSnaps();
return Object.values(snaps).find( return Object.values(snaps).find(
(snap) => snap.id === snapId && (!version || snap.version === version) (snap) => snap.id === snapId && (!version || snap.version === version)
); );
} catch (e) {
return undefined;
}
}; };
export const invokeSnap = async <T>( export const invokeSnap = async <T>(

View File

@ -1,27 +0,0 @@
import { useEffect, useState } from 'react';
import { getSnap } from './connectors';
const INTERVAL = 2_000;
export const useIsSnapRunning = (snapId: string, shouldCheck: boolean) => {
const [running, setRunning] = useState(false);
useEffect(() => {
if (!shouldCheck) return;
const checkState = async () => {
const snap = await getSnap(snapId);
setRunning(!!snap);
};
const i = setInterval(() => {
checkState();
}, INTERVAL);
checkState();
return () => {
clearInterval(i);
};
}, [snapId, shouldCheck]);
return running;
};

View File

@ -0,0 +1,37 @@
import { useEffect, useState } from 'react';
import { getSnap } from './connectors';
const INTERVAL = 2_000;
export enum SnapStatus {
NOT_SUPPORTED,
INSTALLED,
NOT_INSTALLED,
}
export const useSnapStatus = (snapId: string, shouldCheck: boolean) => {
const [status, setStatus] = useState<SnapStatus>(SnapStatus.NOT_INSTALLED);
useEffect(() => {
if (!shouldCheck) return;
const checkState = async () => {
try {
const snap = await getSnap(snapId);
setStatus(snap ? SnapStatus.INSTALLED : SnapStatus.NOT_INSTALLED);
} catch (err) {
setStatus(SnapStatus.NOT_SUPPORTED);
}
};
const i = setInterval(() => {
checkState();
}, INTERVAL);
checkState();
return () => {
clearInterval(i);
};
}, [snapId, shouldCheck]);
return status;
};