Skip to content

Commit

Permalink
feat: display loader on re-designed confirmation page while blockaid …
Browse files Browse the repository at this point in the history
…validation is in progress (#25477)
  • Loading branch information
jpuri authored Jun 27, 2024
1 parent f82a04a commit e0fb582
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BlockaidLoadingIndicator returns spinner when there blockaid validation is in progress for signature 1`] = `
<div>
<div
class="mm-box mm-box--margin-top-4 mm-box--margin-inline-auto"
>
<svg
class="preloader__icon"
fill="none"
height="18"
viewBox="0 0 16 16"
width="18"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M8 13.7143C4.84409 13.7143 2.28571 11.1559 2.28571 8C2.28571 4.84409 4.84409 2.28571 8 2.28571C11.1559 2.28571 13.7143 4.84409 13.7143 8C13.7143 11.1559 11.1559 13.7143 8 13.7143ZM8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16Z"
fill="var(--color-primary-muted)"
fill-rule="evenodd"
/>
<mask
height="16"
id="mask0"
mask-type="alpha"
maskUnits="userSpaceOnUse"
width="16"
x="0"
y="0"
>
<path
clip-rule="evenodd"
d="M8 13.7143C4.84409 13.7143 2.28571 11.1559 2.28571 8C2.28571 4.84409 4.84409 2.28571 8 2.28571C11.1559 2.28571 13.7143 4.84409 13.7143 8C13.7143 11.1559 11.1559 13.7143 8 13.7143ZM8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16Z"
fill="var(--color-primary-default)"
fill-rule="evenodd"
/>
</mask>
<g
mask="url(#mask0)"
>
<path
d="M6.85718 17.9999V11.4285V8.28564H-4.85711V17.9999H6.85718Z"
fill="var(--color-primary-default)"
/>
</g>
</svg>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import {
TransactionStatus,
TransactionType,
} from '@metamask/transaction-controller';

import mockState from '../../../../../../test/data/mock-state.json';
import { BlockaidResultType } from '../../../../../../shared/constants/security-provider';
import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
import { SecurityAlertResponse } from '../../../types/confirm';

import BlockaidLoadingIndicator from './blockaid-loading-indicator';

const mockSecurityAlertResponse: SecurityAlertResponse = {
securityAlertId: 'test-id-mock',
reason: 'test-reason',
result_type: BlockaidResultType.Loading,
};

const render = (
securityAlertResponse: SecurityAlertResponse = mockSecurityAlertResponse,
) => {
const currentConfirmationMock = {
id: '1',
status: TransactionStatus.unapproved,
time: new Date().getTime(),
type: TransactionType.personalSign,
securityAlertResponse,
chainId: '0x1',
};

const mockExpectedState = {
...mockState,
metamask: {
...mockState.metamask,
unapprovedPersonalMsgs: {
'1': { ...currentConfirmationMock, msgParams: {} },
},
pendingApprovals: {
'1': {
...currentConfirmationMock,
origin: 'origin',
requestData: {},
requestState: null,
expectsResult: false,
},
},
preferences: { redesignedConfirmationsEnabled: true },
signatureSecurityAlertResponses: {
'test-id-mock': securityAlertResponse,
},
},
confirm: { currentConfirmation: currentConfirmationMock },
};

const defaultStore = configureStore()(mockExpectedState);
return renderWithProvider(<BlockaidLoadingIndicator />, defaultStore);
};

describe('BlockaidLoadingIndicator', () => {
it('returns spinner when there blockaid validation is in progress for signature', () => {
const { container } = render();
expect(container).toMatchSnapshot();
});

it('returns null if blockaid validation is not in progress', () => {
const { container } = render({
reason: 'test-reason',
result_type: BlockaidResultType.Benign,
});
expect(container).toBeEmptyDOMElement();
});

it('returns null if there is not blockaid validation response', () => {
const { container } = render({} as SecurityAlertResponse);
expect(container).toBeEmptyDOMElement();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { useSelector } from 'react-redux';

import Preloader from '../../../../../components/ui/icon/preloader';
import { BlockaidResultType } from '../../../../../../shared/constants/security-provider';
import { Box } from '../../../../../components/component-library';

import { currentSignatureRequestSecurityResponseSelector } from '../../../selectors';

const BlockaidLoadingIndicator = () => {
const signatureSecurityAlertResponse = useSelector(
currentSignatureRequestSecurityResponseSelector,
);

if (
signatureSecurityAlertResponse?.result_type !== BlockaidResultType.Loading
) {
return null;
}

return (
<Box marginInline={'auto'} marginTop={4}>
<Preloader size={18} />
</Box>
);
};

export default BlockaidLoadingIndicator;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as BlockaidLoadingIndicator } from './blockaid-loading-indicator';
2 changes: 2 additions & 0 deletions ui/pages/confirmations/confirm/confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Page } from '../../../components/multichain/pages/page';
import { MMISignatureMismatchBanner } from '../../../components/app/mmi-signature-mismatch-banner';
///: END:ONLY_INCLUDE_IF

import { BlockaidLoadingIndicator } from '../components/confirm/blockaid-loading-indicator';
import ScrollToBottom from '../components/confirm/scroll-to-bottom';
import setCurrentConfirmation from '../hooks/setCurrentConfirmation';
import syncConfirmPath from '../hooks/syncConfirmPath';
Expand Down Expand Up @@ -46,6 +47,7 @@ const Confirm = () => {
///: END:ONLY_INCLUDE_IF
}
<ScrollToBottom showAdvancedDetails={showAdvancedDetails}>
<BlockaidLoadingIndicator />
<LedgerInfo />
<Title />
<Info showAdvancedDetails={showAdvancedDetails} />
Expand Down
8 changes: 5 additions & 3 deletions ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
REDESIGN_TRANSACTION_TYPES,
SIGNATURE_TRANSACTION_TYPES,
} from '../../utils';
import { currentConfirmationSelector } from '../../selectors';
import {
currentConfirmationSelector,
currentSignatureRequestSecurityResponseSelector,
} from '../../selectors';
import { normalizeProviderAlert } from './utils';

const SUPPORTED_TRANSACTION_TYPES = [
Expand Down Expand Up @@ -47,8 +50,7 @@ const useBlockaidAlerts = (): Alert[] => {
const transactionType = currentConfirmation?.type as TransactionType;

const signatureSecurityAlertResponse = useSelector(
(state: SecurityAlertResponsesState) =>
state.metamask.signatureSecurityAlertResponses?.[securityAlertId],
currentSignatureRequestSecurityResponseSelector,
);

const transactionSecurityAlertResponse = useSelector(
Expand Down
38 changes: 37 additions & 1 deletion ui/pages/confirmations/selectors/confirm.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import { ApprovalType } from '@metamask/controller-utils';
import { TransactionType } from '@metamask/transaction-controller';
import { ConfirmMetamaskState } from '../types/confirm';

import {
BlockaidReason,
BlockaidResultType,
} from '../../../../shared/constants/security-provider';
import { ConfirmMetamaskState, SecurityAlertResponse } from '../types/confirm';
import {
currentConfirmationSelector,
currentSignatureRequestSecurityResponseSelector,
latestPendingConfirmationSelector,
pendingConfirmationsSelector,
} from './confirm';

const SECURITY_ALERT_RESPONSE_MOCK: SecurityAlertResponse = {
securityAlertId: '1',
result_type: BlockaidResultType.Malicious,
reason: BlockaidReason.permitFarming,
};

describe('confirm selectors', () => {
const mockedState: ConfirmMetamaskState = {
confirm: {
Expand Down Expand Up @@ -75,4 +87,28 @@ describe('confirm selectors', () => {
expect(result).toStrictEqual(mockedState.confirm.currentConfirmation);
});
});

describe('currentSignatureRequestSecurityResponseSelector', () => {
it('should return SecurityAlertResponse for current signature', () => {
const sigMockState: ConfirmMetamaskState = {
confirm: {
currentConfirmation: {
id: '1',
type: TransactionType.personalSign,
securityAlertResponse: SECURITY_ALERT_RESPONSE_MOCK,
},
},
metamask: {
pendingApprovals: {},
approvalFlows: [],
signatureSecurityAlertResponses: { 1: SECURITY_ALERT_RESPONSE_MOCK },
},
};

const result =
currentSignatureRequestSecurityResponseSelector(sigMockState);

expect(result).toStrictEqual(SECURITY_ALERT_RESPONSE_MOCK);
});
});
});
27 changes: 26 additions & 1 deletion ui/pages/confirmations/selectors/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import { ApprovalType } from '@metamask/controller-utils';

import { createSelector } from 'reselect';
import { getPendingApprovals } from '../../../selectors/approvals';
import { ConfirmMetamaskState } from '../types/confirm';
import {
ConfirmMetamaskState,
Confirmation,
SecurityAlertResponse,
} from '../types/confirm';
import { createDeepEqualSelector } from '../../../selectors/util';
import { isSignatureTransactionType } from '../utils';

const ConfirmationApprovalTypes = [
ApprovalType.EthSign,
Expand Down Expand Up @@ -43,3 +48,23 @@ export const confirmSelector = (state: ConfirmMetamaskState) => state.confirm;

export const currentConfirmationSelector = (state: ConfirmMetamaskState) =>
state.confirm.currentConfirmation;

export const currentSignatureRequestSecurityResponseSelector = (
state: ConfirmMetamaskState,
) => {
const currentConfirmation: Confirmation | undefined =
currentConfirmationSelector(state);

if (
!currentConfirmation ||
!isSignatureTransactionType(currentConfirmation)
) {
return undefined;
}

const securityAlertId = (
currentConfirmation?.securityAlertResponse as SecurityAlertResponse
)?.securityAlertId as string;

return state.metamask.signatureSecurityAlertResponses?.[securityAlertId];
};
1 change: 1 addition & 0 deletions ui/pages/confirmations/types/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ export type ConfirmMetamaskState = {
metamask: {
pendingApprovals: ApprovalControllerState['pendingApprovals'];
approvalFlows: ApprovalControllerState['approvalFlows'];
signatureSecurityAlertResponses?: Record<string, SecurityAlertResponse>;
};
};

0 comments on commit e0fb582

Please sign in to comment.