import PropTypes from 'prop-types'; import React, { useCallback, useState } from 'react'; import { flatMap } from '@metamask/snap-utils'; import { PageContainerFooter } from '../../../../components/ui/page-container'; import PermissionsConnectPermissionList from '../../../../components/app/permissions-connect-permission-list'; import PermissionsConnectFooter from '../../../../components/app/permissions-connect-footer'; import PermissionConnectHeader from '../../../../components/app/permissions-connect-header'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import SnapInstallWarning from '../../../../components/app/flask/snap-install-warning'; import Box from '../../../../components/ui/box/box'; import { ALIGN_ITEMS, BLOCK_SIZES, BORDER_STYLE, FLEX_DIRECTION, JUSTIFY_CONTENT, TYPOGRAPHY, } from '../../../../helpers/constants/design-system'; import Typography from '../../../../components/ui/typography'; import { coinTypeToProtocolName } from '../../../../helpers/utils/util'; export default function SnapInstall({ request, approveSnapInstall, rejectSnapInstall, targetSubjectMetadata, }) { const t = useI18nContext(); const [isShowingWarning, setIsShowingWarning] = useState(false); const onCancel = useCallback( () => rejectSnapInstall(request.metadata.id), [request, rejectSnapInstall], ); const onSubmit = useCallback( () => approveSnapInstall(request.metadata.id), [request, approveSnapInstall], ); const hasPermissions = request?.permissions && Object.keys(request.permissions).length > 0; const bip44LegacyEntropyPermissions = request.permissions && Object.keys(request.permissions).filter((v) => v.startsWith('snap_getBip44Entropy_'), ); const bip32EntropyPermissions = request.permissions && Object.entries(request.permissions) .filter(([key]) => key === 'snap_getBip32Entropy') .map(([, value]) => value); const bip44EntropyPermissions = request.permissions && Object.entries(request.permissions) .filter(([key]) => key === 'snap_getBip44Entropy') .map(([, value]) => value); const shouldShowWarning = bip32EntropyPermissions?.length > 0 || bip44EntropyPermissions?.length > 0 || bip44LegacyEntropyPermissions?.length > 0; const getCoinType = (bip44EntropyPermission) => bip44EntropyPermission?.split('_').slice(-1); return ( {hasPermissions && ( <> {t('snapRequestsPermission')} )} setIsShowingWarning(true) : onSubmit } submitText={t(hasPermissions ? 'approveAndInstall' : 'install')} /> {isShowingWarning && ( setIsShowingWarning(false)} onSubmit={onSubmit} warnings={[ ...flatMap(bip32EntropyPermissions, (permission, i) => permission.caveats[0].value.map(({ path, curve }) => ({ id: `key-access-bip32-${path.join('/')}-${curve}-${i}`, message: t('snapInstallWarningKeyAccess', [ targetSubjectMetadata.name, `${path.join('/')} (${curve})`, ]), })), ), ...flatMap(bip44EntropyPermissions, (permission, i) => permission.caveats[0].value.map(({ coinType }) => ({ id: `key-access-bip44-${coinType}-${i}`, message: t('snapInstallWarningKeyAccess', [ targetSubjectMetadata.name, coinTypeToProtocolName(coinType) || t('unrecognizedProtocol', [coinType]), ]), })), ), ...bip44LegacyEntropyPermissions.map((permission, i) => { const coinType = getCoinType(permission); return { id: `key-access-bip44-legacy-${i}`, message: t('snapInstallWarningKeyAccess', [ targetSubjectMetadata.name, coinTypeToProtocolName(coinType) || t('unrecognizedProtocol', [coinType]), ]), }; }), ]} /> )} ); } SnapInstall.propTypes = { request: PropTypes.object.isRequired, approveSnapInstall: PropTypes.func.isRequired, rejectSnapInstall: PropTypes.func.isRequired, targetSubjectMetadata: PropTypes.shape({ iconUrl: PropTypes.string, name: PropTypes.string, origin: PropTypes.string.isRequired, sourceCode: PropTypes.string, version: PropTypes.string, }).isRequired, };