diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index f015a4b23ab8..02e2e5f2c12d 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -3235,6 +3235,12 @@
"snaps": {
"message": "Snaps"
},
+ "snapsInsightLoading": {
+ "message": "Loading transaction insight..."
+ },
+ "snapsNoInsight": {
+ "message": "The snap didn't return any Insight"
+ },
"snapsSettingsDescription": {
"message": "Manage your Snaps"
},
diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js
index b09b534ed9c5..be48015a56fc 100644
--- a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js
+++ b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js
@@ -23,6 +23,9 @@ export default class ConfirmPageContainerContent extends Component {
dataComponent: PropTypes.node,
dataHexComponent: PropTypes.node,
detailsComponent: PropTypes.node,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent: PropTypes.node,
+ ///: END:ONLY_INCLUDE_IN
errorKey: PropTypes.string,
errorMessage: PropTypes.string,
hideSubtitle: PropTypes.bool,
@@ -59,15 +62,37 @@ export default class ConfirmPageContainerContent extends Component {
renderContent() {
const { detailsComponent, dataComponent } = this.props;
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ const { insightComponent } = this.props;
+
+ if (insightComponent && (detailsComponent || dataComponent)) {
+ return this.renderTabs();
+ }
+ ///: END:ONLY_INCLUDE_IN
+
if (detailsComponent && dataComponent) {
return this.renderTabs();
}
- return detailsComponent || dataComponent;
+
+ return (
+ detailsComponent ||
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent ||
+ ///: END:ONLY_INCLUDE_IN
+ dataComponent
+ );
}
renderTabs() {
const { t } = this.context;
- const { detailsComponent, dataComponent, dataHexComponent } = this.props;
+ const {
+ detailsComponent,
+ dataComponent,
+ dataHexComponent,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent,
+ ///: END:ONLY_INCLUDE_IN
+ } = this.props;
return (
@@ -88,6 +113,12 @@ export default class ConfirmPageContainerContent extends Component {
{dataHexComponent}
)}
+
+ {
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent
+ ///: END:ONLY_INCLUDE_IN
+ }
);
}
diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss b/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss
index 37d104c808fc..f9ebf4be115f 100644
--- a/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss
+++ b/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss
@@ -82,13 +82,20 @@
color: var(--color-text-alternative);
text-transform: uppercase;
- margin: 0 8px;
& button {
font-size: unset;
color: var(--color-text-alternative);
text-transform: uppercase;
}
+
+ & .dropdown__select {
+ color: var(--color-text-alternative);
+ }
+
+ & .dropdown__icon-caret-down {
+ top: 40%;
+ }
}
.page-container__footer {
diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js
index 79ac85996153..ed0962b0750e 100644
--- a/ui/components/app/confirm-page-container/confirm-page-container.component.js
+++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js
@@ -64,6 +64,9 @@ export default class ConfirmPageContainer extends Component {
dataComponent: PropTypes.node,
dataHexComponent: PropTypes.node,
detailsComponent: PropTypes.node,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent: PropTypes.node,
+ ///: END:ONLY_INCLUDE_IN
tokenAddress: PropTypes.string,
nonce: PropTypes.string,
warning: PropTypes.string,
@@ -153,6 +156,9 @@ export default class ConfirmPageContainer extends Component {
showBuyModal,
isBuyableChain,
networkIdentifier,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent,
+ ///: END:ONLY_INCLUDE_IN
} = this.props;
const showAddToAddressDialog =
@@ -240,6 +246,9 @@ export default class ConfirmPageContainer extends Component {
detailsComponent={detailsComponent}
dataComponent={dataComponent}
dataHexComponent={dataHexComponent}
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent={insightComponent}
+ ///: END:ONLY_INCLUDE_IN
errorMessage={errorMessage}
errorKey={errorKey}
tokenAddress={tokenAddress}
diff --git a/ui/components/app/confirm-page-container/flask/index.scss b/ui/components/app/confirm-page-container/flask/index.scss
new file mode 100644
index 000000000000..818e91330767
--- /dev/null
+++ b/ui/components/app/confirm-page-container/flask/index.scss
@@ -0,0 +1,32 @@
+.snap-insight {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ word-wrap: break-word;
+
+
+ &--no-data {
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ height: 170px;
+ }
+
+ &__container {
+ display: flex;
+ height: 100%;
+ flex-direction: column;
+
+
+ &__data {
+ display: flex;
+ flex-direction: column;
+ padding: 0 4px 12px 24px;
+
+ .typography {
+ font-size: 14px;
+ }
+ }
+ }
+}
diff --git a/ui/components/app/confirm-page-container/flask/snap-insight.js b/ui/components/app/confirm-page-container/flask/snap-insight.js
new file mode 100644
index 000000000000..0a2bb94a3b32
--- /dev/null
+++ b/ui/components/app/confirm-page-container/flask/snap-insight.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import classnames from 'classnames';
+
+import Preloader from '../../../ui/icon/preloader/preloader-icon.component';
+import Typography from '../../../ui/typography/typography';
+import { COLORS } from '../../../../helpers/constants/design-system';
+import { useI18nContext } from '../../../../hooks/useI18nContext';
+import { useTransactionInsightSnap } from '../../../../hooks/flask/useTransactionInsightSnap';
+import SnapContentFooter from '../../flask/snap-content-footer/snap-content-footer';
+
+export const SnapInsight = ({ transaction, chainId, selectedSnap }) => {
+ const t = useI18nContext();
+ const response = useTransactionInsightSnap({
+ transaction,
+ chainId,
+ snapId: selectedSnap.id,
+ });
+
+ const data = response?.insights;
+
+ return (
+
+ {data ? (
+
+ {Object.keys(data).length ? (
+ <>
+
+ {Object.keys(data).map((key, i) => (
+
+
+ {key}
+
+ {data[key]}
+
+ ))}
+
+
+ >
+ ) : (
+
+ {t('snapsNoInsight')}
+
+ )}
+
+ ) : (
+ <>
+
+
+ {t('snapsInsightLoading')}
+
+ >
+ )}
+
+ );
+};
+
+SnapInsight.propTypes = {
+ transaction: PropTypes.object,
+ chainId: PropTypes.string,
+ selectedSnap: PropTypes.object,
+};
diff --git a/ui/components/app/confirm-page-container/index.js b/ui/components/app/confirm-page-container/index.js
index 955ef1bb8b49..b216aba0561b 100644
--- a/ui/components/app/confirm-page-container/index.js
+++ b/ui/components/app/confirm-page-container/index.js
@@ -7,3 +7,6 @@ export {
default as ConfirmPageContainerContent,
ConfirmPageContainerSummary,
} from './confirm-page-container-content';
+///: BEGIN:ONLY_INCLUDE_IN(flask)
+export { SnapInsight } from './flask/snap-insight';
+///: END:ONLY_INCLUDE_IN
diff --git a/ui/components/app/confirm-page-container/index.scss b/ui/components/app/confirm-page-container/index.scss
index ca3e12aa7a76..ca1ac9fb150d 100644
--- a/ui/components/app/confirm-page-container/index.scss
+++ b/ui/components/app/confirm-page-container/index.scss
@@ -2,6 +2,9 @@
@import 'confirm-page-container-header/index';
@import 'confirm-detail-row/index';
@import 'confirm-page-container-navigation/index';
+///: BEGIN:ONLY_INCLUDE_IN(flask)
+@import 'flask/index';
+///: END:ONLY_INCLUDE_IN
.confirm-page-container {
&__dialog {
diff --git a/ui/components/app/flask/snap-content-footer/index.scss b/ui/components/app/flask/snap-content-footer/index.scss
index ea253480406c..9d451153a73a 100644
--- a/ui/components/app/flask/snap-content-footer/index.scss
+++ b/ui/components/app/flask/snap-content-footer/index.scss
@@ -1,7 +1,12 @@
.snap-content-footer {
display: flex;
justify-content: center;
- padding: 24px 0 16px;
+ align-items: center;
+ padding: 16px 0;
+
+ .typography {
+ font-size: 12px;
+ }
i {
color: var(--color-icon-muted);
diff --git a/ui/components/app/flask/snap-content-footer/snap-content-footer.js b/ui/components/app/flask/snap-content-footer/snap-content-footer.js
index b6b20f83be63..ec75f9b89737 100644
--- a/ui/components/app/flask/snap-content-footer/snap-content-footer.js
+++ b/ui/components/app/flask/snap-content-footer/snap-content-footer.js
@@ -1,19 +1,35 @@
import React from 'react';
import PropTypes from 'prop-types';
+
+import { useHistory } from 'react-router-dom';
+
import Typography from '../../../ui/typography/typography';
import { useI18nContext } from '../../../../hooks/useI18nContext';
-import { SNAPS_VIEW_ROUTE } from 'ui/helpers/constants/routes';
-import { COLORS, TYPOGRAPHY } from 'ui/helpers/constants/design-system';
+import { SNAPS_VIEW_ROUTE } from '../../../../helpers/constants/routes';
+import {
+ COLORS,
+ TYPOGRAPHY,
+} from '../../../../helpers/constants/design-system';
+import Button from '../../../ui/button';
export default function SnapContentFooter({ snapName, snapId }) {
const t = useI18nContext();
- const route = `${SNAPS_VIEW_ROUTE}/${encodeURIComponent(snapId)}`;
+ const history = useHistory();
+
+ const handleNameClick = (e) => {
+ e.stopPropagation();
+ history.push(`${SNAPS_VIEW_ROUTE}/${encodeURIComponent(snapId)}`);
+ };
// TODO: add truncation to the snap name, need to pick a character length at which to cut off
return (
-
+
- {t('snapContent', {snapName})}
+ {t('snapContent', [
+ ,
+ ])}
);
diff --git a/ui/components/ui/tabs/dropdown-tab/dropdown-tab.js b/ui/components/ui/tabs/dropdown-tab/dropdown-tab.js
new file mode 100644
index 000000000000..4deccf85045d
--- /dev/null
+++ b/ui/components/ui/tabs/dropdown-tab/dropdown-tab.js
@@ -0,0 +1,63 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import Dropdown from '../../dropdown';
+
+export const DropdownTab = (props) => {
+ const {
+ activeClassName,
+ className,
+ 'data-testid': dataTestId,
+ isActive,
+ onClick,
+ onChange,
+ tabIndex,
+ options,
+ selectedOption,
+ } = props;
+
+ return (
+ {
+ event.preventDefault();
+ onClick(tabIndex);
+ }}
+ >
+
+
+ );
+};
+
+DropdownTab.propTypes = {
+ activeClassName: PropTypes.string,
+ className: PropTypes.string,
+ 'data-testid': PropTypes.string,
+ isActive: PropTypes.bool, // required, but added using React.cloneElement
+ options: PropTypes.arrayOf(
+ PropTypes.exact({
+ name: PropTypes.string,
+ value: PropTypes.string.isRequired,
+ }),
+ ).isRequired,
+ selectedOption: PropTypes.string,
+ onChange: PropTypes.func,
+ onClick: PropTypes.func,
+ tabIndex: PropTypes.number, // required, but added using React.cloneElement
+};
+
+DropdownTab.defaultProps = {
+ activeClassName: undefined,
+ className: undefined,
+ onChange: undefined,
+ onClick: undefined,
+ selectedOption: undefined,
+};
diff --git a/ui/components/ui/tabs/dropdown-tab/index.js b/ui/components/ui/tabs/dropdown-tab/index.js
new file mode 100644
index 000000000000..82d1738acee7
--- /dev/null
+++ b/ui/components/ui/tabs/dropdown-tab/index.js
@@ -0,0 +1,3 @@
+import { DropdownTab } from './dropdown-tab';
+
+export default DropdownTab;
diff --git a/ui/components/ui/tabs/dropdown-tab/index.scss b/ui/components/ui/tabs/dropdown-tab/index.scss
new file mode 100644
index 000000000000..11461d56b0d4
--- /dev/null
+++ b/ui/components/ui/tabs/dropdown-tab/index.scss
@@ -0,0 +1,25 @@
+.tab {
+ .dropdown__select {
+ border: none;
+ font-size: unset;
+ width: 100%;
+ background-color: unset;
+ padding-left: 8px;
+ padding-right: 20px;
+ line-height: unset;
+ text-transform: uppercase;
+
+ option {
+ background-color: var(--color-background-default);
+ text-transform: none;
+ }
+
+ &:focus-visible {
+ outline: none;
+ }
+ }
+
+ .dropdown__icon-caret-down {
+ right: 0;
+ }
+}
diff --git a/ui/components/ui/tabs/index.js b/ui/components/ui/tabs/index.js
index 43366ec6f7e8..c20ebbfc1854 100644
--- a/ui/components/ui/tabs/index.js
+++ b/ui/components/ui/tabs/index.js
@@ -1,4 +1,5 @@
import Tabs from './tabs.component';
import Tab from './tab';
+import DropdownTab from './dropdown-tab';
-export { Tabs, Tab };
+export { Tabs, Tab, DropdownTab };
diff --git a/ui/components/ui/tabs/index.scss b/ui/components/ui/tabs/index.scss
index 96ccf695c2af..b3f230d98664 100644
--- a/ui/components/ui/tabs/index.scss
+++ b/ui/components/ui/tabs/index.scss
@@ -1,4 +1,5 @@
@import 'tab/index';
+@import 'dropdown-tab/index';
.tabs {
flex-grow: 1;
diff --git a/ui/components/ui/tabs/tabs.stories.js b/ui/components/ui/tabs/tabs.stories.js
index 0266eec6c5d7..f3047e4915e6 100644
--- a/ui/components/ui/tabs/tabs.stories.js
+++ b/ui/components/ui/tabs/tabs.stories.js
@@ -1,4 +1,5 @@
import React from 'react';
+import DropdownTab from './dropdown-tab';
import Tab from './tab/tab.component';
import Tabs from './tabs.component';
@@ -41,6 +42,14 @@ export const DefaultStory = (args) => {
onTabClick={args.onTabClick}
>
{args.tabs.map((tabProps, i) => renderTab(tabProps, i))}
+
+ This is a dropdown Tab
+
);
};
diff --git a/ui/hooks/flask/useTransactionInsightSnap.js b/ui/hooks/flask/useTransactionInsightSnap.js
index cf1db24df994..6206bc30da90 100644
--- a/ui/hooks/flask/useTransactionInsightSnap.js
+++ b/ui/hooks/flask/useTransactionInsightSnap.js
@@ -3,28 +3,35 @@ import { useSelector } from 'react-redux';
import { handleSnapRequest } from '../../store/actions';
import { getPermissionSubjects } from '../../selectors';
-const INSIGHT_PERMISSION = 'endowment:tx-insight';
+const INSIGHT_PERMISSION = 'endowment:transaction-insight';
-export function useTransactionInsightSnap(transaction, snapId) {
+export function useTransactionInsightSnap({ transaction, chainId, snapId }) {
const subjects = useSelector(getPermissionSubjects);
if (!subjects[snapId]?.permissions[INSIGHT_PERMISSION]) {
throw new Error(
'This snap does not have the transaction insight endowment.',
);
}
- const [data, setData] = useState(null);
+ const [data, setData] = useState(undefined);
useEffect(() => {
async function fetchInsight() {
- const d = await handleSnapRequest(snapId, undefined, 'onTransaction', {
- params: [transaction],
+ const d = await handleSnapRequest({
+ snapId,
+ origin: 'test',
+ handler: 'onTransaction',
+ request: {
+ jsonrpc: '2.0',
+ method: ' ',
+ params: { transaction, chainId },
+ },
});
setData(d);
}
if (transaction) {
fetchInsight();
}
- }, [snapId, transaction]);
+ }, [snapId, transaction, chainId]);
return data;
}
diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js
index acc2c0b549d9..a9023d65b719 100644
--- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js
+++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js
@@ -1,5 +1,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+///: BEGIN:ONLY_INCLUDE_IN(flask)
+import { stripHexPrefix } from 'ethereumjs-util';
+///: END:ONLY_INCLUDE_IN
import ConfirmPageContainer from '../../components/app/confirm-page-container';
import TransactionDecoding from '../../components/app/transaction-decoding';
import { isBalanceSufficient } from '../send/send.utils';
@@ -46,7 +49,7 @@ import GasDetailsItem from '../../components/app/gas-details-item';
import GasTiming from '../../components/app/gas-timing/gas-timing.component';
import LedgerInstructionField from '../../components/app/ledger-instruction-field';
import MultiLayerFeeMessage from '../../components/app/multilayer-fee-message';
-
+import Typography from '../../components/ui/typography/typography';
import {
COLORS,
FONT_STYLE,
@@ -59,10 +62,19 @@ import {
removePollingTokenFromAppState,
} from '../../store/actions';
-import Typography from '../../components/ui/typography/typography';
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants';
-import { NETWORK_TO_NAME_MAP } from '../../../shared/constants/network';
+///: BEGIN:ONLY_INCLUDE_IN(flask)
+import { SnapInsight } from '../../components/app/confirm-page-container/flask/snap-insight';
+import { DropdownTab, Tab } from '../../components/ui/tabs';
+///: END:ONLY_INCLUDE_IN
+
+import {
+ NETWORK_TO_NAME_MAP,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ CHAIN_ID_TO_NETWORK_ID_MAP,
+ ///: END:ONLY_INCLUDE_IN
+} from '../../../shared/constants/network';
import TransactionAlerts from './transaction-alerts';
const renderHeartBeatIfNotInTest = () =>
@@ -151,6 +163,9 @@ export default class ConfirmTransactionBase extends Component {
eip1559V2Enabled: PropTypes.bool,
showBuyModal: PropTypes.func,
isBuyableChain: PropTypes.bool,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightSnaps: PropTypes.arrayOf(PropTypes.object),
+ ///: END:ONLY_INCLUDE_IN
};
state = {
@@ -160,6 +175,9 @@ export default class ConfirmTransactionBase extends Component {
ethGasPriceWarning: '',
editingGas: false,
userAcknowledgedGasMissing: false,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ selectedInsightSnapId: this.props.insightSnaps[0]?.id,
+ ///: END:ONLY_INCLUDE_IN
};
componentDidUpdate(prevProps) {
@@ -303,6 +321,12 @@ export default class ConfirmTransactionBase extends Component {
this.setState({ editingGas: false });
}
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ handleSnapSelected(snapId) {
+ this.setState({ selectedInsightSnapId: snapId });
+ }
+ ///: END:ONLY_INCLUDE_IN
+
setUserAcknowledgedGasMissing() {
this.setState({ userAcknowledgedGasMissing: true });
}
@@ -730,6 +754,62 @@ export default class ConfirmTransactionBase extends Component {
);
}
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ renderInsight() {
+ const { txData, insightSnaps } = this.props;
+ const { selectedInsightSnapId } = this.state;
+ const { txParams, chainId } = txData;
+
+ const selectedSnap = insightSnaps.find(
+ ({ id }) => id === selectedInsightSnapId,
+ );
+
+ const networkId = CHAIN_ID_TO_NETWORK_ID_MAP[chainId];
+ const caip2ChainId = `eip155:${networkId ?? stripHexPrefix(chainId)}`;
+
+ if (
+ txData.type !== TRANSACTION_TYPES.CONTRACT_INTERACTION ||
+ !insightSnaps
+ ) {
+ return null;
+ }
+
+ const dropdownOptions = insightSnaps.reduce(
+ (prev, acc) => [
+ ...prev,
+ { value: acc.id, name: acc.manifest.proposedName },
+ ],
+ [],
+ );
+
+ return insightSnaps.length > 1 ? (
+ this.handleSnapSelected(snapId)}
+ >
+
+
+ ) : (
+
+
+
+ );
+ }
+ ///: END:ONLY_INCLUDE_IN
+
handleEdit() {
const {
txData,
@@ -1111,6 +1191,9 @@ export default class ConfirmTransactionBase extends Component {
detailsComponent={this.renderDetails()}
dataComponent={this.renderData(functionType)}
dataHexComponent={this.renderDataHex(functionType)}
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightComponent={this.renderInsight()}
+ ///: END:ONLY_INCLUDE_IN
contentComponent={contentComponent}
nonce={customNonceValue || nonce}
unapprovedTxCount={unapprovedTxCount}
diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js
index 78770daa2068..555b370774f6 100644
--- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js
+++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js
@@ -35,6 +35,9 @@ import {
getEIP1559V2Enabled,
getIsBuyableChain,
getEnsResolutionByAddress,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ getInsightSnaps,
+ ///: END:ONLY_INCLUDE_IN
} from '../../selectors';
import { getMostRecentOverviewPage } from '../../ducks/history/history';
import {
@@ -197,6 +200,10 @@ const mapStateToProps = (state, ownProps) => {
const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state);
const eip1559V2Enabled = getEIP1559V2Enabled(state);
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ const insightSnaps = getInsightSnaps(state);
+ ///: END:ONLY_INCLUDE_IN
+
return {
balance,
fromAddress,
@@ -249,6 +256,9 @@ const mapStateToProps = (state, ownProps) => {
chainId,
eip1559V2Enabled,
isBuyableChain,
+ ///: BEGIN:ONLY_INCLUDE_IN(flask)
+ insightSnaps,
+ ///: END:ONLY_INCLUDE_IN
};
};
diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js
index 59e4dd70dd75..72dde3ec9448 100644
--- a/ui/selectors/selectors.js
+++ b/ui/selectors/selectors.js
@@ -72,6 +72,7 @@ import {
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
///: BEGIN:ONLY_INCLUDE_IN(flask)
import { SNAPS_VIEW_ROUTE } from '../helpers/constants/routes';
+import { getPermissionSubjects } from './permissions';
///: END:ONLY_INCLUDE_IN
/**
@@ -747,6 +748,17 @@ export function getSnaps(state) {
return state.metamask.snaps;
}
+export function getInsightSnaps(state) {
+ const snaps = Object.values(state.metamask.snaps);
+ const subjects = getPermissionSubjects(state);
+
+ const insightSnaps = snaps.filter(
+ ({ id }) => subjects[id]?.permissions['endowment:transaction-insight'],
+ );
+
+ return insightSnaps;
+}
+
export const getSnapsRouteObjects = createSelector(getSnaps, (snaps) => {
return Object.values(snaps).map((snap) => {
return {
diff --git a/ui/store/actions.js b/ui/store/actions.js
index 84b944615a0f..c977918f6ad7 100644
--- a/ui/store/actions.js
+++ b/ui/store/actions.js
@@ -1050,13 +1050,8 @@ export async function removeSnapError(msgData) {
return submitRequestToBackground('removeSnapError', [msgData]);
}
-export async function handleSnapRequest(snapId, origin, handler, request) {
- return submitRequestToBackground('handleSnapRequest', [
- snapId,
- origin,
- handler,
- request,
- ]);
+export async function handleSnapRequest(args) {
+ return submitRequestToBackground('handleSnapRequest', [args]);
}
export function dismissNotifications(ids) {