From 8c06c97d518095e53882780d9a488f43ba4df9e9 Mon Sep 17 00:00:00 2001 From: Hassan Malik <41640681+hmalik88@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:23:25 -0400 Subject: [PATCH] feat: use new `SnapAuthorshipPill` component to show snap origin in confirmation flow (#26881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? Previously, the confirmation page would just show the snap id for "request from" as part of the confirmation screen. 2. What is the improvement/solution? A pill is now used to show the snap icon and name, the pill opens up to a metadata modal. Fixes: https://github.com/MetaMask/MetaMask-planning/issues/3085 ## **Manual testing steps** 1. Build the extension 2. Install a snap that uses `personal_sign` 3. Call `personal_sign` from the snap ## **Screenshots/Recordings** https://github.com/user-attachments/assets/894ebaf8-9b58-4073-913e-bce64db2ad2a ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- ui/components/app/app-components.scss | 1 + .../app/confirm/info/info.stories.tsx | 2 +- ui/components/app/confirm/info/row/url.tsx | 27 ++++++++- .../app/snaps/snap-authorship-pill/index.scss | 7 +++ .../app/snaps/snap-authorship-pill/index.ts | 1 + .../snap-authorship-pill.stories.tsx | 20 +++++++ .../snap-authorship-pill.tsx | 55 +++++++++++++++++++ 7 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 ui/components/app/snaps/snap-authorship-pill/index.scss create mode 100644 ui/components/app/snaps/snap-authorship-pill/index.ts create mode 100644 ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.stories.tsx create mode 100644 ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index cdbe492029b8..cc9a08a53f1d 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -34,6 +34,7 @@ @import 'snaps/show-more/index'; @import 'snaps/insight-warnings/index'; @import 'snaps/snap-authorship-header/index'; +@import 'snaps/snap-authorship-pill/index'; @import 'snaps/snap-footer-button/index'; @import 'hold-to-reveal-button/index'; @import 'home-notification/index'; diff --git a/ui/components/app/confirm/info/info.stories.tsx b/ui/components/app/confirm/info/info.stories.tsx index d801555aaed0..d23726f39104 100644 --- a/ui/components/app/confirm/info/info.stories.tsx +++ b/ui/components/app/confirm/info/info.stories.tsx @@ -17,7 +17,7 @@ const mockRowConfigs: ConfirmInfoRowConfig[] = [ label: 'Origin', type: ConfirmInfoRowType.UrlType, rowProps: { - address: 'https://metamask.github.io', + url: 'https://metamask.github.io', }, }, { diff --git a/ui/components/app/confirm/info/row/url.tsx b/ui/components/app/confirm/info/row/url.tsx index c7b9b8d9730a..807fc7298042 100644 --- a/ui/components/app/confirm/info/row/url.tsx +++ b/ui/components/app/confirm/info/row/url.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useCallback, useState } from 'react'; import { Box, Icon, @@ -16,6 +16,9 @@ import { TextVariant, BackgroundColor, } from '../../../../../helpers/constants/design-system'; +import SnapAuthorshipPill from '../../../snaps/snap-authorship-pill'; +import { SnapMetadataModal } from '../../../snaps/snap-metadata-modal'; +import { isSnapId } from '../../../../../helpers/utils/snaps'; export type ConfirmInfoRowUrlProps = { url: string; @@ -23,6 +26,28 @@ export type ConfirmInfoRowUrlProps = { export const ConfirmInfoRowUrl = ({ url }: ConfirmInfoRowUrlProps) => { let urlObject; + const [isModalOpen, setIsModalOpen] = useState(false); + const handlePillClick = useCallback( + () => setIsModalOpen(true), + [setIsModalOpen], + ); + const handleModalClose = useCallback( + () => setIsModalOpen(false), + [setIsModalOpen], + ); + + if (isSnapId(url)) { + return ( + <> + + + + ); + } try { urlObject = new URL(url); diff --git a/ui/components/app/snaps/snap-authorship-pill/index.scss b/ui/components/app/snaps/snap-authorship-pill/index.scss new file mode 100644 index 000000000000..6cc4f186046d --- /dev/null +++ b/ui/components/app/snaps/snap-authorship-pill/index.scss @@ -0,0 +1,7 @@ +.snap-authorship-pill { + cursor: pointer; + + &:hover { + background-color: var(--color-background-alternative); + } +} diff --git a/ui/components/app/snaps/snap-authorship-pill/index.ts b/ui/components/app/snaps/snap-authorship-pill/index.ts new file mode 100644 index 000000000000..14a023241bd0 --- /dev/null +++ b/ui/components/app/snaps/snap-authorship-pill/index.ts @@ -0,0 +1 @@ +export { default } from './snap-authorship-pill'; diff --git a/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.stories.tsx b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.stories.tsx new file mode 100644 index 000000000000..0ec787c42887 --- /dev/null +++ b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.stories.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import SnapAuthorshipPill from './snap-authorship-pill' + +export default { + title: 'Components/App/Snaps/SnapAuthorshipPill', + component: SnapAuthorshipPill, + argTypes: { + snapId: { + control: 'text', + }, + }, +}; + +export const DefaultStory = (args) => ; + +DefaultStory.storyName = 'Default'; + +DefaultStory.args = { + snapId: 'npm:@metamask/test-snap-bip44', +}; diff --git a/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx new file mode 100644 index 000000000000..fd8831f36e0f --- /dev/null +++ b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { Box, IconSize, Text } from '../../../component-library'; +import { SnapIcon } from '../snap-icon'; +import { getSnapMetadata } from '../../../../selectors'; +import { + AlignItems, + BorderRadius, + Display, + FlexDirection, + TextColor, + TextVariant, +} from '../../../../helpers/constants/design-system'; + +type SnapAuthorshipPillProps = { + snapId: string; + onClick: () => void; +}; + +const SnapAuthorshipPill: React.FC = ({ + snapId, + onClick, +}) => { + const { name: snapName } = useSelector((state) => + // @ts-expect-error ts is picking up the wrong type for the selector + getSnapMetadata(state, snapId), + ); + + return ( + + + + {snapName} + + + ); +}; + +export default SnapAuthorshipPill;