From e424debfc0ed834a06dc825fe6470953ccab1b6a Mon Sep 17 00:00:00 2001
From: vthomas13 <10986371+vthomas13@users.noreply.github.com>
Date: Thu, 23 Mar 2023 10:55:43 -0400
Subject: [PATCH 01/12] adding opensea security provider image (#18292)
---
app/images/open-sea-security-provider.svg | 91 +++++++++++++++++++++++
1 file changed, 91 insertions(+)
create mode 100644 app/images/open-sea-security-provider.svg
diff --git a/app/images/open-sea-security-provider.svg b/app/images/open-sea-security-provider.svg
new file mode 100644
index 000000000000..ac79c0026adb
--- /dev/null
+++ b/app/images/open-sea-security-provider.svg
@@ -0,0 +1,91 @@
+
From ed5b78d61ba42ac85a0382072811554795fb7b7b Mon Sep 17 00:00:00 2001
From: Garrett Bear
Date: Thu, 23 Mar 2023 08:24:23 -0700
Subject: [PATCH 02/12] Feat/add header base component (#18043)
* add header base component
* fix resizing issue
* add center
* add demo
* header base using flexbox
* fix button issue
* header base clean up
* update tests
* add readme description
* add docs
* update snapshot
* add more to readme
* convert to TS
* fix file name
* fix types and colors
* fix classname error
* fix boxprops import
* fix boxprops
* prop fix
* fix errors
* Update ui/components/component-library/header-base/header-base.stories.tsx
Co-authored-by: George Marshall
* Update ui/components/component-library/header-base/header-base.types.ts
Co-authored-by: George Marshall
* Update ui/components/component-library/header-base/header-base.types.ts
Co-authored-by: George Marshall
* headerbase fixes
* fix export
* remove Math.max
* change order for index on storybook to prep build
* revert back to order
* remove type from export
* add type to export
* change export of headerbase function
* export update
* revert back to normal
* add type to export
* Removing interface export from index
---------
Co-authored-by: George Marshall
---
.../component-library/header-base/README.mdx | 114 +++++++
.../__snapshots__/header-base.test.tsx.snap | 17 +
.../header-base/header-base.stories.tsx | 293 ++++++++++++++++++
.../header-base/header-base.test.tsx | 61 ++++
.../header-base/header-base.tsx | 117 +++++++
.../header-base/header-base.types.ts | 33 ++
.../component-library/header-base/index.ts | 2 +
ui/components/component-library/index.js | 1 +
8 files changed, 638 insertions(+)
create mode 100644 ui/components/component-library/header-base/README.mdx
create mode 100644 ui/components/component-library/header-base/__snapshots__/header-base.test.tsx.snap
create mode 100644 ui/components/component-library/header-base/header-base.stories.tsx
create mode 100644 ui/components/component-library/header-base/header-base.test.tsx
create mode 100644 ui/components/component-library/header-base/header-base.tsx
create mode 100644 ui/components/component-library/header-base/header-base.types.ts
create mode 100644 ui/components/component-library/header-base/index.ts
diff --git a/ui/components/component-library/header-base/README.mdx b/ui/components/component-library/header-base/README.mdx
new file mode 100644
index 000000000000..ab8c671a5467
--- /dev/null
+++ b/ui/components/component-library/header-base/README.mdx
@@ -0,0 +1,114 @@
+import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
+import { HeaderBase } from './header-base';
+
+### This is a base component. It should not be used in your feature code directly but as a "base" for other UI components
+
+# HeaderBase
+
+The `HeaderBase` component is a reusable UI component for displaying a header with optional startAccessory, children (title) and endAccessory content areas. It is designed to be flexible and customizable for various use cases to keep a visually balanced appearance.
+
+
+
+## Props
+
+The `HeaderBase` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props
+
+
+
+### Children
+
+Wrapping content in the `HeaderBase` component will be rendered in the center of the header.
+
+Use the `childrenWrapperProps` prop to customize the wrapper element around the `children` content.
+
+
+
+```jsx
+import { HeaderBase, Text } from '../../component-library';
+import {
+ TEXT_ALIGN,
+ TextVariant,
+} from '../../../helpers/constants/design-system';
+
+
+
+ Title is sentence case no period
+
+;
+```
+
+### startAccessory
+
+Using the `startAccessory` prop will render the content in the start (left) side of the header.
+
+Use the `startAccessoryWrapperProps` prop to customize the wrapper element around the `startAccessory` content.
+
+
+
+```jsx
+import { HeaderBase, Text } from '../../component-library';
+import {
+ TEXT_ALIGN,
+ TextVariant,
+} from '../../../helpers/constants/design-system';
+
+
+ }
+>
+
+ Title is sentence case no period
+
+;
+```
+
+### endAccessory
+
+Using the `endAccessory` prop will render the content in the end (right) side of the header.
+
+Use the `endAccessoryWrapperProps` prop to customize the wrapper element around the `endAccessory` content.
+
+
+
+```jsx
+import { HeaderBase, Text } from '../../component-library';
+import {
+ TEXT_ALIGN,
+ TextVariant,
+} from '../../../helpers/constants/design-system';
+
+
+ }
+>
+
+ Title is sentence case no period
+
+;
+```
+
+### Use Case Demos
+
+Some examples of how the `HeaderBase` component can be used in various use cases with background colors set for visual aid.
+
+
diff --git a/ui/components/component-library/header-base/__snapshots__/header-base.test.tsx.snap b/ui/components/component-library/header-base/__snapshots__/header-base.test.tsx.snap
new file mode 100644
index 000000000000..6253be824a9f
--- /dev/null
+++ b/ui/components/component-library/header-base/__snapshots__/header-base.test.tsx.snap
@@ -0,0 +1,17 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderBase should render HeaderBase element correctly 1`] = `
+
+
+
+ should render HeaderBase element correctly
+
+
+
+`;
diff --git a/ui/components/component-library/header-base/header-base.stories.tsx b/ui/components/component-library/header-base/header-base.stories.tsx
new file mode 100644
index 000000000000..be26fe8741ca
--- /dev/null
+++ b/ui/components/component-library/header-base/header-base.stories.tsx
@@ -0,0 +1,293 @@
+import React from 'react';
+import { ComponentStory, ComponentMeta } from '@storybook/react';
+import Box from '../../ui/box';
+import {
+ ICON_NAMES,
+ Button,
+ ButtonIcon,
+ BUTTON_ICON_SIZES,
+ BUTTON_SIZES,
+ Text,
+} from '..';
+import {
+ AlignItems,
+ BackgroundColor,
+ TextVariant,
+ TEXT_ALIGN,
+} from '../../../helpers/constants/design-system';
+import { HeaderBase } from './header-base';
+import README from './README.mdx';
+
+export default {
+ title: 'Components/ComponentLibrary/HeaderBase',
+ component: HeaderBase,
+ parameters: {
+ docs: {
+ page: README,
+ },
+ },
+} as ComponentMeta;
+
+const Template: ComponentStory = (args) => (
+
+);
+
+export const DefaultStory = Template.bind({});
+
+DefaultStory.args = {
+ children: (
+
+ Title is sentence case no period
+
+ ),
+ startAccessory: (
+
+ ),
+ endAccessory: (
+
+ ),
+};
+
+DefaultStory.storyName = 'Default';
+
+export const Children = (args) => {
+ return (
+
+
+ Title is sentence case no period
+
+
+ );
+};
+
+export const StartAccessory = (args) => {
+ return (
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+ );
+};
+
+export const EndAccessory = (args) => {
+ return (
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+ );
+};
+
+export const UseCaseDemos = (args) => (
+ <>
+ children only assigned
+
+
+
+ Title is sentence case no period
+
+
+
+ children and endAccessory assigned
+
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+
+ children and startAccessory assigned
+
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+
+ children, startAccessory, and endAccessory assigned
+
+
+ }
+ endAccessory={
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+
+ children, startAccessory, and endAccessory assigned
+
+
+ Unlock Now
+
+ }
+ endAccessory={
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+
+
+ children, startAccessory, and endAccessory assigned with prop alignItems=
+ {AlignItems.center} passed at HeaderBase
+
+
+
+ }
+ endAccessory={
+
+ }
+ {...args}
+ >
+
+ Title is sentence case no period
+
+
+
+ startAccessory and endAccessory assigned
+
+
+ Unlock
+
+ }
+ endAccessory={
+
+ }
+ {...args}
+ >
+
+ >
+);
diff --git a/ui/components/component-library/header-base/header-base.test.tsx b/ui/components/component-library/header-base/header-base.test.tsx
new file mode 100644
index 000000000000..9d4ccec69f26
--- /dev/null
+++ b/ui/components/component-library/header-base/header-base.test.tsx
@@ -0,0 +1,61 @@
+/* eslint-disable jest/require-top-level-describe */
+import { render } from '@testing-library/react';
+import React from 'react';
+import { Icon, ICON_NAMES } from '..';
+import { HeaderBase } from './header-base';
+
+describe('HeaderBase', () => {
+ it('should render HeaderBase element correctly', () => {
+ const { getByTestId, container } = render(
+
+ should render HeaderBase element correctly
+ ,
+ );
+ expect(getByTestId('header-base')).toHaveClass('mm-header-base');
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render with added classname', () => {
+ const { getByTestId } = render(
+
+ should render HeaderBase element correctly
+ ,
+ );
+ expect(getByTestId('header-base')).toHaveClass('mm-header-base--test');
+ });
+
+ it('should render HeaderBase children', () => {
+ const { getByText } = render(
+ HeaderBase children test,
+ );
+ expect(getByText('HeaderBase children test')).toBeDefined();
+ });
+
+ it('should render HeaderBase startAccessory', () => {
+ const { getByTestId } = render(
+
+ }
+ />,
+ );
+
+ expect(getByTestId('start-accessory')).toBeDefined();
+ });
+
+ it('should render HeaderBase endAccessory', () => {
+ const { getByTestId } = render(
+
+ }
+ />,
+ );
+
+ expect(getByTestId('end-accessory')).toBeDefined();
+ });
+});
diff --git a/ui/components/component-library/header-base/header-base.tsx b/ui/components/component-library/header-base/header-base.tsx
new file mode 100644
index 000000000000..220a596d43dd
--- /dev/null
+++ b/ui/components/component-library/header-base/header-base.tsx
@@ -0,0 +1,117 @@
+import React, { useRef, useLayoutEffect, useMemo, useState } from 'react';
+import classnames from 'classnames';
+import {
+ BLOCK_SIZES,
+ DISPLAY,
+ JustifyContent,
+} from '../../../helpers/constants/design-system';
+import Box from '../../ui/box';
+
+import { HeaderBaseProps } from './header-base.types';
+
+export const HeaderBase: React.FC = ({
+ startAccessory,
+ endAccessory,
+ className = '',
+ children,
+ childrenWrapperProps,
+ startAccessoryWrapperProps,
+ endAccessoryWrapperProps,
+ ...props
+}) => {
+ const startAccessoryRef = useRef(null);
+ const endAccessoryRef = useRef(null);
+ const [accessoryMinWidth, setAccessoryMinWidth] = useState();
+
+ useLayoutEffect(() => {
+ function handleResize() {
+ if (startAccessoryRef.current && endAccessoryRef.current) {
+ const accMinWidth = Math.max(
+ startAccessoryRef.current.scrollWidth,
+ endAccessoryRef.current.scrollWidth,
+ );
+ setAccessoryMinWidth(accMinWidth);
+ } else if (startAccessoryRef.current && !endAccessoryRef.current) {
+ setAccessoryMinWidth(startAccessoryRef.current.scrollWidth);
+ } else if (!startAccessoryRef.current && endAccessoryRef.current) {
+ setAccessoryMinWidth(endAccessoryRef.current.scrollWidth);
+ } else {
+ setAccessoryMinWidth(0);
+ }
+ }
+
+ handleResize();
+ window.addEventListener('resize', handleResize);
+
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, [startAccessoryRef, endAccessoryRef, children]);
+
+ const getTitleStyles = useMemo(() => {
+ if (startAccessory && !endAccessory) {
+ return {
+ marginRight: `${accessoryMinWidth}px`,
+ };
+ } else if (!startAccessory && endAccessory) {
+ return {
+ marginLeft: `${accessoryMinWidth}px`,
+ };
+ }
+ return {};
+ }, [accessoryMinWidth, startAccessory, endAccessory]);
+
+ return (
+
+ {startAccessory && (
+
+ {startAccessory}
+
+ )}
+ {children && (
+
+ {children}
+
+ )}
+ {endAccessory && (
+
+ {endAccessory}
+
+ )}
+
+ );
+};
diff --git a/ui/components/component-library/header-base/header-base.types.ts b/ui/components/component-library/header-base/header-base.types.ts
new file mode 100644
index 000000000000..a871ce744a04
--- /dev/null
+++ b/ui/components/component-library/header-base/header-base.types.ts
@@ -0,0 +1,33 @@
+import React from 'react';
+import type { BoxProps } from '../../ui/box/box.d';
+
+export interface HeaderBaseProps extends BoxProps {
+ /**
+ * The children is the title area of the HeaderBase
+ */
+ children?: React.ReactNode;
+ /**
+ * Use the `childrenWrapperProps` prop to define the props to the children wrapper
+ */
+ childrenWrapperProps?: BoxProps;
+ /**
+ * The start(default left) content area of HeaderBase
+ */
+ startAccessory?: React.ReactNode;
+ /**
+ * Use the `startAccessoryWrapperProps` prop to define the props to the start accessory wrapper
+ */
+ startAccessoryWrapperProps?: BoxProps;
+ /**
+ * The end (default right) content area of HeaderBase
+ */
+ endAccessory?: React.ReactNode;
+ /**
+ * Use the `endAccessoryWrapperProps` prop to define the props to the end accessory wrapper
+ */
+ endAccessoryWrapperProps?: BoxProps;
+ /**
+ * An additional className to apply to the HeaderBase
+ */
+ className?: string;
+}
diff --git a/ui/components/component-library/header-base/index.ts b/ui/components/component-library/header-base/index.ts
new file mode 100644
index 000000000000..1b47557f8897
--- /dev/null
+++ b/ui/components/component-library/header-base/index.ts
@@ -0,0 +1,2 @@
+export { HeaderBase } from './header-base';
+export type { HeaderBaseProps } from './header-base.types';
diff --git a/ui/components/component-library/index.js b/ui/components/component-library/index.js
index 33e8ab60480e..f24721433eeb 100644
--- a/ui/components/component-library/index.js
+++ b/ui/components/component-library/index.js
@@ -21,6 +21,7 @@ export { ButtonLink, BUTTON_LINK_SIZES } from './button-link';
export { ButtonPrimary, BUTTON_PRIMARY_SIZES } from './button-primary';
export { ButtonSecondary, BUTTON_SECONDARY_SIZES } from './button-secondary';
export { FormTextField } from './form-text-field';
+export { HeaderBase } from './header-base';
export { HelpText } from './help-text';
export { Icon, ICON_NAMES, ICON_SIZES } from './icon';
export { Label } from './label';
From 048c3e32583c4db3c05a9d6da9de0803e4a148e3 Mon Sep 17 00:00:00 2001
From: Frederik Bolding
Date: Thu, 23 Mar 2023 16:52:01 +0100
Subject: [PATCH 03/12] [FLASK] Update iframe-execution-environment (#18299)
---
app/scripts/metamask-controller.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 6a2c1107d07c..1e9698e7827b 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -748,7 +748,7 @@ export default class MetamaskController extends EventEmitter {
///: BEGIN:ONLY_INCLUDE_IN(flask)
const snapExecutionServiceArgs = {
iframeUrl: new URL(
- 'https://metamask.github.io/iframe-execution-environment/0.13.0',
+ 'https://metamask.github.io/iframe-execution-environment/0.14.0',
),
messenger: this.controllerMessenger.getRestricted({
name: 'ExecutionService',
From 270ff26561677c173c8137be914e618261827aca Mon Sep 17 00:00:00 2001
From: Dan J Miller
Date: Thu, 23 Mar 2023 09:07:28 -0700
Subject: [PATCH 04/12] Fixes to the Linea Goerli implementation (#18290)
* Ensure that NonInfuraDefaultNetworks are only selected in the dropdown if they are the currently selected network
* Ensure Linea Goerli network appears in network settings tab if added manually
---
.../app/dropdowns/network-dropdown.js | 21 ++++++++-----------
.../settings/networks-tab/networks-tab.js | 20 ++++++++++--------
2 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js
index 09e94c4981d7..c40ccc79d887 100644
--- a/ui/components/app/dropdowns/network-dropdown.js
+++ b/ui/components/app/dropdowns/network-dropdown.js
@@ -286,22 +286,20 @@ class NetworkDropdown extends Component {
}
renderNonInfuraDefaultNetwork(networkConfigurations, network) {
- const {
- provider: { type: providerType },
- setActiveNetwork,
- upsertNetworkConfiguration,
- } = this.props;
+ const { provider, setActiveNetwork, upsertNetworkConfiguration } =
+ this.props;
- const isCurrentRpcTarget = providerType === NETWORK_TYPES.RPC;
+ const { chainId, ticker, blockExplorerUrl } = BUILT_IN_NETWORKS[network];
+ const networkName = NETWORK_TO_NAME_MAP[network];
+ const rpcUrl = CHAIN_ID_TO_RPC_URL_MAP[chainId];
+
+ const isCurrentRpcTarget =
+ provider.type === NETWORK_TYPES.RPC && rpcUrl === provider.rpcUrl;
return (
{
- const { chainId, ticker, blockExplorerUrl } =
- BUILT_IN_NETWORKS[network];
- const networkName = NETWORK_TO_NAME_MAP[network];
-
const networkConfiguration = pickBy(
networkConfigurations,
(config) => config.rpcUrl === CHAIN_ID_TO_RPC_URL_MAP[chainId],
@@ -310,7 +308,6 @@ class NetworkDropdown extends Component {
let configurationId = null;
// eslint-disable-next-line no-extra-boolean-cast, no-implicit-coercion
if (!!networkConfiguration) {
- const rpcUrl = CHAIN_ID_TO_RPC_URL_MAP[chainId];
configurationId = await upsertNetworkConfiguration(
{
rpcUrl,
@@ -346,7 +343,7 @@ class NetworkDropdown extends Component {
data-testid={`${network}-network-item`}
style={{
color:
- providerType === network
+ provider.type === network
? 'var(--color-text-default)'
: 'var(--color-text-alternative)',
}}
diff --git a/ui/pages/settings/networks-tab/networks-tab.js b/ui/pages/settings/networks-tab/networks-tab.js
index bbc0443cd105..7ba0e29af917 100644
--- a/ui/pages/settings/networks-tab/networks-tab.js
+++ b/ui/pages/settings/networks-tab/networks-tab.js
@@ -30,11 +30,13 @@ import NetworksTabContent from './networks-tab-content';
import NetworksForm from './networks-form';
import NetworksFormSubheader from './networks-tab-subheader';
-const defaultNetworks = defaultNetworksData.map((network) => ({
- ...network,
- viewOnly: true,
- isATestNetwork: TEST_CHAINS.includes(network.chainId),
-}));
+const defaultNetworks = defaultNetworksData
+ .map((network) => ({
+ ...network,
+ viewOnly: true,
+ isATestNetwork: TEST_CHAINS.includes(network.chainId),
+ }))
+ .filter((network) => network.chainId !== CHAIN_IDS.LINEA_TESTNET);
const NetworksTab = ({ addNewNetwork }) => {
const t = useI18nContext();
@@ -55,8 +57,8 @@ const NetworksTab = ({ addNewNetwork }) => {
getNetworksTabSelectedNetworkConfigurationId,
);
- const networkConfigurationsList = Object.entries(networkConfigurations)
- .map(([networkConfigurationId, networkConfiguration]) => {
+ const networkConfigurationsList = Object.entries(networkConfigurations).map(
+ ([networkConfigurationId, networkConfiguration]) => {
return {
label: networkConfiguration.nickname,
iconColor: 'var(--color-icon-alternative)',
@@ -68,8 +70,8 @@ const NetworksTab = ({ addNewNetwork }) => {
isATestNetwork: TEST_CHAINS.includes(networkConfiguration.chainId),
networkConfigurationId,
};
- })
- .filter((network) => network.chainId !== CHAIN_IDS.LINEA_TESTNET);
+ },
+ );
let networksToRender = [...defaultNetworks, ...networkConfigurationsList];
if (!SHOULD_SHOW_LINEA_TESTNET_NETWORK) {
From c89b93dc1dfe12176c276fd397b8c7f280b4f26e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Oliv=C3=A9?=
Date: Thu, 23 Mar 2023 17:09:09 +0100
Subject: [PATCH 05/12] adding code fence in extension file (#17874)
---
app/scripts/platforms/extension.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js
index faf9af160bf7..3a298e699c41 100644
--- a/app/scripts/platforms/extension.js
+++ b/app/scripts/platforms/extension.js
@@ -176,9 +176,14 @@ export default class ExtensionPlatform {
_showFailedTransaction(txMeta, errorMessage) {
const nonce = parseInt(txMeta.txParams.nonce, 16);
const title = 'Failed transaction';
- const message = `Transaction ${nonce} failed! ${
+ let message = `Transaction ${nonce} failed! ${
errorMessage || txMeta.err.message
}`;
+ ///: BEGIN:ONLY_INCLUDE_IN(mmi)
+ if (isNaN(nonce)) {
+ message = `Transaction failed! ${errorMessage || txMeta.err.message}`;
+ }
+ ///: END:ONLY_INCLUDE_IN
this._showNotification(title, message);
}
From 196b8408d0cdf5e35e241be9f0ca98337b4acf0d Mon Sep 17 00:00:00 2001
From: Ariella Vu <20778143+digiwand@users.noreply.github.com>
Date: Thu, 23 Mar 2023 09:32:54 -0700
Subject: [PATCH 06/12] PermissionsConnectHeader: unlock SiteOrigin title
(#18270)
* PermissionsConnectHeader: unlock SiteOrigin title
* SignatureRequestOriginal: unlock SiteOrigin title
* signature-req: update snapshots
---
.../permissions-connect-header.component.js | 1 +
.../__snapshots__/signature-request-original.test.js.snap | 1 +
.../signature-request-original.component.js | 1 +
.../__snapshots__/signature-request-siwe.test.js.snap | 1 +
4 files changed, 4 insertions(+)
diff --git a/ui/components/app/permissions-connect-header/permissions-connect-header.component.js b/ui/components/app/permissions-connect-header/permissions-connect-header.component.js
index cc8f955135df..43b6d5f7e323 100644
--- a/ui/components/app/permissions-connect-header/permissions-connect-header.component.js
+++ b/ui/components/app/permissions-connect-header/permissions-connect-header.component.js
@@ -64,6 +64,7 @@ export default class PermissionsConnectHeader extends Component {