2022-03-09 21:20:48 +01:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2022-02-15 01:02:51 +01:00
|
|
|
import { useHistory, useLocation } from 'react-router-dom';
|
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
2023-03-08 19:29:23 +01:00
|
|
|
import {
|
|
|
|
SnapCaveatType,
|
|
|
|
WALLET_SNAP_PERMISSION_KEY,
|
|
|
|
} from '@metamask/rpc-methods';
|
2023-04-24 12:21:37 +02:00
|
|
|
import { getSnapPrefix } from '@metamask/snaps-utils';
|
2022-02-15 01:02:51 +01:00
|
|
|
import Button from '../../../../components/ui/button';
|
|
|
|
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
|
|
|
import {
|
2023-04-24 12:21:37 +02:00
|
|
|
Size,
|
2023-02-02 21:15:26 +01:00
|
|
|
TextColor,
|
2023-04-24 12:21:37 +02:00
|
|
|
TextVariant,
|
2022-02-15 01:02:51 +01:00
|
|
|
} from '../../../../helpers/constants/design-system';
|
2023-03-24 17:16:46 +01:00
|
|
|
import SnapAuthorship from '../../../../components/app/flask/snap-authorship';
|
2022-02-15 01:02:51 +01:00
|
|
|
import Box from '../../../../components/ui/box';
|
2022-03-09 21:20:48 +01:00
|
|
|
import SnapRemoveWarning from '../../../../components/app/flask/snap-remove-warning';
|
2022-02-15 01:02:51 +01:00
|
|
|
import ToggleButton from '../../../../components/ui/toggle-button';
|
|
|
|
import ConnectedSitesList from '../../../../components/app/connected-sites-list';
|
|
|
|
import Tooltip from '../../../../components/ui/tooltip';
|
|
|
|
import { SNAPS_LIST_ROUTE } from '../../../../helpers/constants/routes';
|
|
|
|
import {
|
|
|
|
disableSnap,
|
|
|
|
enableSnap,
|
|
|
|
removeSnap,
|
|
|
|
removePermissionsFor,
|
2023-03-08 19:29:23 +01:00
|
|
|
updateCaveat,
|
2022-02-15 01:02:51 +01:00
|
|
|
} from '../../../../store/actions';
|
2022-09-12 18:36:40 +02:00
|
|
|
import {
|
|
|
|
getSnaps,
|
2023-03-08 19:29:23 +01:00
|
|
|
getSubjectsWithSnapPermission,
|
2022-09-12 18:36:40 +02:00
|
|
|
getPermissions,
|
2023-03-08 19:29:23 +01:00
|
|
|
getPermissionSubjects,
|
2023-04-05 15:34:33 +02:00
|
|
|
getTargetSubjectMetadata,
|
2022-09-12 18:36:40 +02:00
|
|
|
} from '../../../../selectors';
|
2023-04-24 12:21:37 +02:00
|
|
|
import {
|
|
|
|
formatDate,
|
|
|
|
getSnapName,
|
|
|
|
removeSnapIdPrefix,
|
|
|
|
} from '../../../../helpers/utils/util';
|
|
|
|
import { ButtonLink, Text } from '../../../../components/component-library';
|
2023-04-14 12:04:23 +02:00
|
|
|
import SnapPermissionsList from '../../../../components/app/flask/snap-permissions-list';
|
2022-02-15 01:02:51 +01:00
|
|
|
|
|
|
|
function ViewSnap() {
|
|
|
|
const t = useI18nContext();
|
|
|
|
const history = useHistory();
|
|
|
|
const location = useLocation();
|
|
|
|
const { pathname } = location;
|
2022-05-11 22:14:53 +02:00
|
|
|
// The snap ID is in URI-encoded form in the last path segment of the URL.
|
|
|
|
const decodedSnapId = decodeURIComponent(pathname.match(/[^/]+$/u)[0]);
|
2022-02-15 01:02:51 +01:00
|
|
|
const snaps = useSelector(getSnaps);
|
|
|
|
const snap = Object.entries(snaps)
|
|
|
|
.map(([_, snapState]) => snapState)
|
2022-05-11 22:14:53 +02:00
|
|
|
.find((snapState) => snapState.id === decodedSnapId);
|
2022-02-15 01:02:51 +01:00
|
|
|
|
2022-03-09 21:20:48 +01:00
|
|
|
const [isShowingRemoveWarning, setIsShowingRemoveWarning] = useState(false);
|
|
|
|
|
2022-02-15 01:02:51 +01:00
|
|
|
useEffect(() => {
|
|
|
|
if (!snap) {
|
|
|
|
history.push(SNAPS_LIST_ROUTE);
|
|
|
|
}
|
|
|
|
}, [history, snap]);
|
|
|
|
|
|
|
|
const connectedSubjects = useSelector((state) =>
|
2023-03-08 19:29:23 +01:00
|
|
|
getSubjectsWithSnapPermission(state, snap?.id),
|
2022-02-15 01:02:51 +01:00
|
|
|
);
|
2022-09-13 12:41:29 +02:00
|
|
|
const permissions = useSelector(
|
|
|
|
(state) => snap && getPermissions(state, snap.id),
|
|
|
|
);
|
2023-03-08 19:29:23 +01:00
|
|
|
const subjects = useSelector((state) => getPermissionSubjects(state));
|
2023-04-05 15:34:33 +02:00
|
|
|
const targetSubjectMetadata = useSelector((state) =>
|
|
|
|
getTargetSubjectMetadata(state, snap?.id),
|
|
|
|
);
|
2022-02-15 01:02:51 +01:00
|
|
|
const dispatch = useDispatch();
|
2023-03-08 19:29:23 +01:00
|
|
|
|
2022-02-15 01:02:51 +01:00
|
|
|
const onToggle = () => {
|
|
|
|
if (snap.enabled) {
|
|
|
|
dispatch(disableSnap(snap.id));
|
|
|
|
} else {
|
|
|
|
dispatch(enableSnap(snap.id));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-03-08 19:29:23 +01:00
|
|
|
const onDisconnect = (connectedOrigin, snapId) => {
|
|
|
|
const caveatValue =
|
|
|
|
subjects[connectedOrigin].permissions[WALLET_SNAP_PERMISSION_KEY]
|
|
|
|
.caveats[0].value;
|
|
|
|
const newCaveatValue = { ...caveatValue };
|
|
|
|
delete newCaveatValue[snapId];
|
|
|
|
if (Object.keys(newCaveatValue) > 0) {
|
|
|
|
dispatch(
|
|
|
|
updateCaveat(
|
|
|
|
connectedOrigin,
|
|
|
|
WALLET_SNAP_PERMISSION_KEY,
|
|
|
|
SnapCaveatType.SnapIds,
|
|
|
|
newCaveatValue,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
dispatch(
|
|
|
|
removePermissionsFor({
|
|
|
|
[connectedOrigin]: [WALLET_SNAP_PERMISSION_KEY],
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-02-15 01:02:51 +01:00
|
|
|
if (!snap) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-04-04 19:40:24 +02:00
|
|
|
|
|
|
|
const versionHistory = snap.versionHistory ?? [];
|
2023-04-24 12:21:37 +02:00
|
|
|
const installInfo = versionHistory.length
|
|
|
|
? versionHistory[versionHistory.length - 1]
|
|
|
|
: undefined;
|
|
|
|
const packageName = snap.id && removeSnapIdPrefix(snap.id);
|
|
|
|
const snapPrefix = snap.id && getSnapPrefix(snap.id);
|
|
|
|
const isNPM = snapPrefix === 'npm:';
|
|
|
|
const url = isNPM
|
|
|
|
? `https://www.npmjs.com/package/${packageName}`
|
|
|
|
: packageName;
|
|
|
|
const snapName = getSnapName(snap.id, targetSubjectMetadata);
|
2022-04-04 19:40:24 +02:00
|
|
|
|
2022-02-15 01:02:51 +01:00
|
|
|
return (
|
2023-04-24 12:21:37 +02:00
|
|
|
<Box
|
|
|
|
className="view-snap"
|
|
|
|
paddingBottom={8}
|
|
|
|
paddingLeft={3}
|
|
|
|
paddingRight={3}
|
|
|
|
>
|
|
|
|
<Box
|
|
|
|
className="view-snap__header"
|
|
|
|
paddingTop={8}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<SnapAuthorship snapId={snap.id} />
|
|
|
|
</Box>
|
|
|
|
<Box
|
|
|
|
className="view-snap__description"
|
|
|
|
marginTop={4}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyMd} color={TextColor.textDefault}>
|
|
|
|
{snap.manifest.description}
|
|
|
|
</Text>
|
|
|
|
</Box>
|
|
|
|
<Box
|
|
|
|
className="view-snap__version_info"
|
|
|
|
marginTop={2}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyMd} color={TextColor.textDefault}>
|
|
|
|
{`${t('youInstalled')} `}
|
|
|
|
<span className="view-snap__version_info__version-number">
|
|
|
|
v{snap.version}
|
|
|
|
</span>
|
|
|
|
{` ${t('ofTextNofM')} `}
|
|
|
|
<ButtonLink
|
|
|
|
size={Size.auto}
|
|
|
|
href={url}
|
|
|
|
target="_blank"
|
|
|
|
className="view-snap__version_info__link"
|
2022-02-15 01:02:51 +01:00
|
|
|
>
|
2023-04-24 12:21:37 +02:00
|
|
|
{packageName}
|
|
|
|
</ButtonLink>
|
|
|
|
{installInfo && ` ${t('from').toLowerCase()} `}
|
|
|
|
{installInfo && (
|
|
|
|
<ButtonLink
|
|
|
|
size={Size.auto}
|
|
|
|
href={installInfo.origin}
|
|
|
|
target="_blank"
|
|
|
|
className="view-snap__version_info__link"
|
|
|
|
>
|
|
|
|
{installInfo.origin}
|
|
|
|
</ButtonLink>
|
2022-04-04 19:40:24 +02:00
|
|
|
)}
|
2023-04-24 12:21:37 +02:00
|
|
|
{installInfo &&
|
|
|
|
` ${t('on').toLowerCase()} ${formatDate(
|
|
|
|
installInfo.date,
|
|
|
|
'dd MMM yyyy',
|
|
|
|
)}`}
|
|
|
|
.
|
|
|
|
</Text>
|
|
|
|
</Box>
|
|
|
|
<Box
|
|
|
|
className="view-snap__enable"
|
|
|
|
marginTop={12}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyLgMedium}>{t('enableSnap')}</Text>
|
|
|
|
<Text
|
|
|
|
variant={TextVariant.bodyMd}
|
|
|
|
color={TextColor.textDefault}
|
|
|
|
marginBottom={4}
|
2022-02-15 01:02:51 +01:00
|
|
|
>
|
2023-04-24 12:21:37 +02:00
|
|
|
{t('enableSnapDescription')}
|
|
|
|
</Text>
|
|
|
|
<Box className="view-snap__enable__tooltip_wrapper">
|
|
|
|
<Tooltip interactive position="left" html={t('snapsToggle')}>
|
|
|
|
<ToggleButton
|
|
|
|
value={snap.enabled}
|
|
|
|
onToggle={onToggle}
|
|
|
|
className="view-snap__toggle-button"
|
|
|
|
/>
|
|
|
|
</Tooltip>
|
|
|
|
</Box>
|
|
|
|
</Box>
|
|
|
|
<Box className="view-snap__permissions" marginTop={12}>
|
|
|
|
<Text variant={TextVariant.bodyLgMedium} marginLeft={4} marginRight={4}>
|
|
|
|
{t('permissions')}
|
|
|
|
</Text>
|
|
|
|
<SnapPermissionsList
|
|
|
|
permissions={permissions ?? {}}
|
|
|
|
targetSubjectMetadata={targetSubjectMetadata}
|
|
|
|
/>
|
|
|
|
</Box>
|
|
|
|
<Box
|
|
|
|
className="view-snap__connected-sites"
|
|
|
|
marginTop={12}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyLgMedium} marginBottom={4}>
|
|
|
|
{t('connectedSites')}
|
|
|
|
</Text>
|
|
|
|
<ConnectedSitesList
|
|
|
|
connectedSubjects={connectedSubjects}
|
|
|
|
onDisconnect={(origin) => {
|
|
|
|
onDisconnect(origin, snap.id);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Box>
|
|
|
|
<Box
|
|
|
|
className="view-snap__remove"
|
|
|
|
marginTop={12}
|
|
|
|
marginLeft={4}
|
|
|
|
marginRight={4}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyLgMedium} color={TextColor.textDefault}>
|
|
|
|
{t('removeSnap')}
|
|
|
|
</Text>
|
|
|
|
<Text variant={TextVariant.bodyMd} color={TextColor.textDefault}>
|
|
|
|
{t('removeSnapDescription')}
|
|
|
|
</Text>
|
|
|
|
<Box marginTop={4}>
|
|
|
|
<Button
|
|
|
|
className="view-snap__remove-button"
|
|
|
|
type="danger"
|
|
|
|
onClick={() => setIsShowingRemoveWarning(true)}
|
|
|
|
>
|
|
|
|
<Text variant={TextVariant.bodyMd} color={TextColor.errorDefault}>
|
|
|
|
{`${t('remove')} ${snapName}`}
|
|
|
|
</Text>
|
|
|
|
</Button>
|
|
|
|
{isShowingRemoveWarning && (
|
|
|
|
<SnapRemoveWarning
|
|
|
|
onCancel={() => setIsShowingRemoveWarning(false)}
|
|
|
|
onSubmit={async () => {
|
|
|
|
await dispatch(removeSnap(snap.id));
|
2022-02-15 01:02:51 +01:00
|
|
|
}}
|
2023-04-24 12:21:37 +02:00
|
|
|
snapName={snapName}
|
|
|
|
/>
|
|
|
|
)}
|
2022-02-15 01:02:51 +01:00
|
|
|
</Box>
|
2023-04-24 12:21:37 +02:00
|
|
|
</Box>
|
|
|
|
</Box>
|
2022-02-15 01:02:51 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-04-24 12:21:37 +02:00
|
|
|
export default ViewSnap;
|