diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index b36f3ffcdb4e..e79059a7148f 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -413,6 +413,9 @@
"alertMessageAddressMismatchWarning": {
"message": "Attackers sometimes mimic sites by making small changes to the site address. Make sure you're interacting with the intended site before you continue."
},
+ "alertMessageChangeInSimulationResults": {
+ "message": "Estimated changes for this transaction have been updated. Review them closely before proceeding."
+ },
"alertMessageGasEstimateFailed": {
"message": "We’re unable to provide an accurate fee and this estimate might be high. We suggest you to input a custom gas limit, but there’s a risk the transaction will still fail."
},
@@ -452,6 +455,9 @@
"alertModalReviewAllAlerts": {
"message": "Review all alerts"
},
+ "alertReasonChangeInSimulationResults": {
+ "message": "Results have changed"
+ },
"alertReasonGasEstimateFailed": {
"message": "Inaccurate fee"
},
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index 9ccb9b8f435c..0e7ea6a201fe 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -750,15 +750,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -2255,8 +2270,23 @@
},
"@metamask/rpc-errors": {
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/rpc-errors>@metamask/utils": true,
+ "@metamask/rpc-errors>fast-safe-stringify": true
+ }
+ },
+ "@metamask/rpc-errors>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/rpc-methods-flask>nanoid": {
@@ -2833,9 +2863,9 @@
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/network-controller": true,
+ "@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/transaction-controller>@metamask/rpc-errors": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -2861,10 +2891,19 @@
"@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/rpc-errors": {
+ "@metamask/transaction-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/user-operation-controller": {
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index 9ccb9b8f435c..0e7ea6a201fe 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -750,15 +750,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -2255,8 +2270,23 @@
},
"@metamask/rpc-errors": {
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/rpc-errors>@metamask/utils": true,
+ "@metamask/rpc-errors>fast-safe-stringify": true
+ }
+ },
+ "@metamask/rpc-errors>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/rpc-methods-flask>nanoid": {
@@ -2833,9 +2863,9 @@
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/network-controller": true,
+ "@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/transaction-controller>@metamask/rpc-errors": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -2861,10 +2891,19 @@
"@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/rpc-errors": {
+ "@metamask/transaction-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/user-operation-controller": {
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index 9ccb9b8f435c..0e7ea6a201fe 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -750,15 +750,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -2255,8 +2270,23 @@
},
"@metamask/rpc-errors": {
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/rpc-errors>@metamask/utils": true,
+ "@metamask/rpc-errors>fast-safe-stringify": true
+ }
+ },
+ "@metamask/rpc-errors>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/rpc-methods-flask>nanoid": {
@@ -2833,9 +2863,9 @@
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/network-controller": true,
+ "@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/transaction-controller>@metamask/rpc-errors": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -2861,10 +2891,19 @@
"@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/rpc-errors": {
+ "@metamask/transaction-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/user-operation-controller": {
diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json
index 502533c22dfe..bb0e150744bf 100644
--- a/lavamoat/browserify/mmi/policy.json
+++ b/lavamoat/browserify/mmi/policy.json
@@ -842,15 +842,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -2347,8 +2362,23 @@
},
"@metamask/rpc-errors": {
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/rpc-errors>@metamask/utils": true,
+ "@metamask/rpc-errors>fast-safe-stringify": true
+ }
+ },
+ "@metamask/rpc-errors>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/rpc-methods-flask>nanoid": {
@@ -2925,9 +2955,9 @@
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/network-controller": true,
+ "@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/transaction-controller>@metamask/rpc-errors": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -2953,10 +2983,19 @@
"@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/rpc-errors": {
+ "@metamask/transaction-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
"packages": {
- "@metamask/rpc-errors>fast-safe-stringify": true,
- "@metamask/utils": true
+ "@metamask/utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
}
},
"@metamask/user-operation-controller": {
diff --git a/package.json b/package.json
index b97a1bdf5a9a..3d5ee3b946a9 100644
--- a/package.json
+++ b/package.json
@@ -345,7 +345,7 @@
"@metamask/snaps-rpc-methods": "^11.5.0",
"@metamask/snaps-sdk": "^6.9.0",
"@metamask/snaps-utils": "^8.4.1",
- "@metamask/transaction-controller": "^37.3.0",
+ "@metamask/transaction-controller": "^38.1.0",
"@metamask/user-operation-controller": "^13.0.0",
"@metamask/utils": "^9.3.0",
"@ngraveio/bc-ur": "^1.1.12",
diff --git a/test/e2e/tests/simulation-details/mock-request-no-changes.ts b/test/e2e/tests/simulation-details/mock-request-no-changes.ts
index 59b7fc9b8b3d..03aa562fd354 100644
--- a/test/e2e/tests/simulation-details/mock-request-no-changes.ts
+++ b/test/e2e/tests/simulation-details/mock-request-no-changes.ts
@@ -5,7 +5,7 @@ export const NO_CHANGES_TRANSACTION_MOCK = {
maxFeePerGas: '0x0',
maxPriorityFeePerGas: '0x0',
to: SENDER_ADDRESS_MOCK,
- value: '0x38d7ea4c68000',
+ value: '0x0',
};
export const NO_CHANGES_REQUEST_MOCK: MockRequestResponse = {
@@ -42,6 +42,7 @@ export const NO_CHANGES_REQUEST_MOCK: MockRequestResponse = {
stateDiff: {
post: {
[SENDER_ADDRESS_MOCK]: {
+ balance: '0x3185e67a46d9066',
nonce: '0x3c0',
},
},
diff --git a/ui/components/app/confirm/info/row/constants.ts b/ui/components/app/confirm/info/row/constants.ts
index f260f9bce282..415358aa5252 100644
--- a/ui/components/app/confirm/info/row/constants.ts
+++ b/ui/components/app/confirm/info/row/constants.ts
@@ -3,8 +3,9 @@ export const TEST_ADDRESS = '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1';
export enum RowAlertKey {
EstimatedFee = 'estimatedFee',
SigningInWith = 'signingInWith',
- Speed = 'speed',
RequestFrom = 'requestFrom',
+ Resimulation = 'resimulation',
+ Speed = 'speed',
}
export enum AlertActionKey {
diff --git a/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap
index e466d6b5e11e..38219749e987 100644
--- a/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap
+++ b/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap
@@ -178,26 +178,35 @@ exports[`Info renders info section for contract interaction request 1`] = `
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center"
>
-
- Estimated changes
-
-
diff --git a/ui/pages/confirmations/components/confirm/info/base-transaction-info/__snapshots__/base-transaction-info.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/base-transaction-info/__snapshots__/base-transaction-info.test.tsx.snap
index f88485e985b3..47d28a0ba29d 100644
--- a/ui/pages/confirmations/components/confirm/info/base-transaction-info/__snapshots__/base-transaction-info.test.tsx.snap
+++ b/ui/pages/confirmations/components/confirm/info/base-transaction-info/__snapshots__/base-transaction-info.test.tsx.snap
@@ -15,26 +15,35 @@ exports[` renders component for contract interaction requ
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center"
>
-
- Estimated changes
-
-
diff --git a/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap
index 8313befacc21..8bd4a73fe440 100644
--- a/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap
+++ b/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap
@@ -60,26 +60,35 @@ exports[`NFTTokenTransferInfo renders correctly 1`] = `
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center"
>
-
- Estimated changes
-
-
diff --git a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap
index f7a672912907..05a1db6732f5 100644
--- a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap
+++ b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap
@@ -57,26 +57,35 @@ exports[`TokenTransferInfo renders correctly 1`] = `
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center"
>
-
- Estimated changes
-
-
diff --git a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
index 5bb182ac7e66..339ffbdd6a1a 100644
--- a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
+++ b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
@@ -26,6 +26,21 @@ jest.mock('./balance-change-list', () => ({
jest.mock('./useSimulationMetrics');
+jest.mock(
+ '../../../../components/app/confirm/info/row/alert-row/alert-row',
+ () => ({
+ ConfirmInfoAlertRow: jest.fn(({ label }) => <>{label}>),
+ }),
+);
+
+jest.mock('../../context/confirm', () => ({
+ useConfirmContext: jest.fn(() => ({
+ currentConfirmation: {
+ id: 'testTransactionId',
+ },
+ })),
+}));
+
const renderSimulationDetails = (simulationData?: Partial) =>
renderWithProvider(
{
);
};
+const HeaderWithAlert = ({ transactionId }: { transactionId: string }) => {
+ const t = useI18nContext();
+
+ return (
+
+ {/* Intentional fragment */}
+ <>>
+
+ );
+};
+
+const LegacyHeader = () => {
+ const t = useI18nContext();
+ return (
+
+
+ {t('simulationDetailsTitle')}
+
+
+
+
+
+ );
+};
+
/**
* Header at the top of the simulation preview.
*
* @param props
* @param props.children
+ * @param props.isTransactionsRedesign
+ * @param props.transactionId
*/
-const HeaderLayout: React.FC = ({ children }) => {
- const t = useI18nContext();
+const HeaderLayout: React.FC<{
+ isTransactionsRedesign: boolean;
+ transactionId: string;
+}> = ({ children, isTransactionsRedesign, transactionId }) => {
return (
{
alignItems={AlignItems.center}
justifyContent={JustifyContent.spaceBetween}
>
-
-
- {t('simulationDetailsTitle')}
-
-
-
-
-
+ {isTransactionsRedesign ? (
+
+ ) : (
+
+ )}
{children}
);
@@ -142,11 +179,13 @@ const HeaderLayout: React.FC = ({ children }) => {
* @param props.inHeader
* @param props.isTransactionsRedesign
* @param props.children
+ * @param props.transactionId
*/
const SimulationDetailsLayout: React.FC<{
inHeader?: React.ReactNode;
isTransactionsRedesign: boolean;
-}> = ({ inHeader, isTransactionsRedesign, children }) => (
+ transactionId: string;
+}> = ({ inHeader, isTransactionsRedesign, transactionId, children }) => (
- {inHeader}
+
+ {inHeader}
+
{children}
);
@@ -199,6 +243,7 @@ export const SimulationDetails: React.FC = ({
}
isTransactionsRedesign={isTransactionsRedesign}
+ transactionId={transactionId}
>
);
}
@@ -216,7 +261,10 @@ export const SimulationDetails: React.FC = ({
if (error) {
return (
-
+
);
@@ -226,7 +274,10 @@ export const SimulationDetails: React.FC = ({
const empty = balanceChanges.length === 0;
if (empty) {
return (
-
+
);
@@ -235,7 +286,10 @@ export const SimulationDetails: React.FC = ({
const outgoing = balanceChanges.filter((bc) => bc.amount.isNegative());
const incoming = balanceChanges.filter((bc) => !bc.amount.isNegative());
return (
-
+
{
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it('returns no alerts if no confirmation', () => {
+ expect(runHook()).toEqual([]);
+ });
+
+ it('returns no alerts if no transactions', () => {
+ expect(
+ runHook({
+ currentConfirmation: CONFIRMATION_MOCK,
+ transactions: [],
+ }),
+ ).toEqual([]);
+ });
+
+ it('returns no alerts if isUpdatedAfterSecurityCheck is false', () => {
+ const notResimulatedConfirmation = {
+ ...TRANSACTION_META_MOCK,
+ simulationData: {
+ isUpdatedAfterSecurityCheck: false,
+ tokenBalanceChanges: [],
+ },
+ };
+ expect(
+ runHook({
+ currentConfirmation: notResimulatedConfirmation,
+ }),
+ ).toEqual([]);
+ });
+
+ it('returns alert if isUpdatedAfterSecurityCheck is true', () => {
+ const resimulatedConfirmation = {
+ ...CONFIRMATION_MOCK,
+ simulationData: {
+ isUpdatedAfterSecurityCheck: true,
+ tokenBalanceChanges: [],
+ },
+ };
+ const alerts = runHook({
+ currentConfirmation: resimulatedConfirmation,
+ });
+
+ expect(alerts).toEqual([
+ {
+ actions: [],
+ field: RowAlertKey.Resimulation,
+ isBlocking: false,
+ key: 'simulationDetailsTitle',
+ message:
+ 'Estimated changes for this transaction have been updated. Review them closely before proceeding.',
+ reason: 'Results have changed',
+ severity: Severity.Danger,
+ },
+ ]);
+ });
+});
diff --git a/ui/pages/confirmations/hooks/alerts/transactions/useResimulationAlert.ts b/ui/pages/confirmations/hooks/alerts/transactions/useResimulationAlert.ts
new file mode 100644
index 000000000000..c838e07e62c4
--- /dev/null
+++ b/ui/pages/confirmations/hooks/alerts/transactions/useResimulationAlert.ts
@@ -0,0 +1,34 @@
+import { useMemo } from 'react';
+import { TransactionMeta } from '@metamask/transaction-controller';
+
+import { Alert } from '../../../../../ducks/confirm-alerts/confirm-alerts';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+import { Severity } from '../../../../../helpers/constants/design-system';
+import { RowAlertKey } from '../../../../../components/app/confirm/info/row/constants';
+import { useConfirmContext } from '../../../context/confirm';
+
+export function useResimulationAlert(): Alert[] {
+ const t = useI18nContext();
+ const { currentConfirmation } = useConfirmContext();
+
+ const isUpdatedAfterSecurityCheck = (currentConfirmation as TransactionMeta)
+ ?.simulationData?.isUpdatedAfterSecurityCheck;
+
+ return useMemo(() => {
+ if (!isUpdatedAfterSecurityCheck) {
+ return [];
+ }
+
+ return [
+ {
+ actions: [],
+ field: RowAlertKey.Resimulation,
+ isBlocking: false,
+ key: 'simulationDetailsTitle',
+ message: t('alertMessageChangeInSimulationResults'),
+ reason: t('alertReasonChangeInSimulationResults'),
+ severity: Severity.Danger,
+ },
+ ];
+ }, [isUpdatedAfterSecurityCheck, t]);
+}
diff --git a/ui/pages/confirmations/hooks/useConfirmationAlerts.ts b/ui/pages/confirmations/hooks/useConfirmationAlerts.ts
index 3ea9a5e2d254..c5f77f143cb6 100644
--- a/ui/pages/confirmations/hooks/useConfirmationAlerts.ts
+++ b/ui/pages/confirmations/hooks/useConfirmationAlerts.ts
@@ -10,6 +10,7 @@ import { useNetworkBusyAlerts } from './alerts/transactions/useNetworkBusyAlerts
import { useNoGasPriceAlerts } from './alerts/transactions/useNoGasPriceAlerts';
import { usePendingTransactionAlerts } from './alerts/transactions/usePendingTransactionAlerts';
import { useQueuedConfirmationsAlerts } from './alerts/transactions/useQueuedConfirmationsAlerts';
+import { useResimulationAlert } from './alerts/transactions/useResimulationAlert';
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
import { useSigningOrSubmittingAlerts } from './alerts/transactions/useSigningOrSubmittingAlerts';
///: END:ONLY_INCLUDE_IF
@@ -34,11 +35,11 @@ function useTransactionAlerts(): Alert[] {
const networkBusyAlerts = useNetworkBusyAlerts();
const noGasPriceAlerts = useNoGasPriceAlerts();
const pendingTransactionAlerts = usePendingTransactionAlerts();
+ const resimulationAlert = useResimulationAlert();
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
const signingOrSubmittingAlerts = useSigningOrSubmittingAlerts();
///: END:ONLY_INCLUDE_IF
const queuedConfirmationsAlerts = useQueuedConfirmationsAlerts();
-
return useMemo(
() => [
...gasEstimateFailedAlerts,
@@ -48,6 +49,7 @@ function useTransactionAlerts(): Alert[] {
...networkBusyAlerts,
...noGasPriceAlerts,
...pendingTransactionAlerts,
+ ...resimulationAlert,
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
...signingOrSubmittingAlerts,
///: END:ONLY_INCLUDE_IF
@@ -61,6 +63,7 @@ function useTransactionAlerts(): Alert[] {
networkBusyAlerts,
noGasPriceAlerts,
pendingTransactionAlerts,
+ resimulationAlert,
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
signingOrSubmittingAlerts,
///: END:ONLY_INCLUDE_IF
diff --git a/yarn.lock b/yarn.lock
index a8024a521207..1eb362ce3a2c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4882,13 +4882,13 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1":
- version: 7.0.1
- resolution: "@metamask/base-controller@npm:7.0.1"
+"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1, @metamask/base-controller@npm:^7.0.2":
+ version: 7.0.2
+ resolution: "@metamask/base-controller@npm:7.0.2"
dependencies:
- "@metamask/utils": "npm:^9.1.0"
+ "@metamask/utils": "npm:^10.0.0"
immer: "npm:^9.0.6"
- checksum: 10/774b6d68ac95a5ec187e890d321bede50065f8a6f1ba7b49a19f5971366274054ac0e401548b51d3b014d0bca5d650409fb554dd13ce120e7fb3495b4e8e67b1
+ checksum: 10/6f78ec5af840c9947aa8eac6e402df6469600260d613a92196daefd5b072097a176fe5da1c386f2d36853513254b74140d667d817a12880c46f088e18ff3606a
languageName: node
linkType: hard
@@ -4925,20 +4925,20 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0":
- version: 11.4.0
- resolution: "@metamask/controller-utils@npm:11.4.0"
+"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0, @metamask/controller-utils@npm:^11.4.1":
+ version: 11.4.1
+ resolution: "@metamask/controller-utils@npm:11.4.1"
dependencies:
"@ethereumjs/util": "npm:^8.1.0"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/ethjs-unit": "npm:^0.3.0"
- "@metamask/utils": "npm:^9.1.0"
+ "@metamask/utils": "npm:^10.0.0"
"@spruceid/siwe-parser": "npm:2.1.0"
"@types/bn.js": "npm:^5.1.5"
bn.js: "npm:^5.2.1"
eth-ens-namehash: "npm:^2.0.8"
fast-deep-equal: "npm:^3.1.3"
- checksum: 10/f34d24880eab264bddaa5bef21afaecb206db6978364565d0f7b7a54b1d411f129eb84175041df3be8a66394c2d49e83b6648b5cbde6f34662a60fc553c31458
+ checksum: 10/fff4864858ce2072456537c9b51cb4c10d178a27b39ab5af8d6e9595efb59dd043bb49be336d8ac725d1281279db4365855f024329398508658b2b2d3b5bc2a5
languageName: node
linkType: hard
@@ -6059,13 +6059,13 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/rpc-errors@npm:^7.0.0":
- version: 7.0.0
- resolution: "@metamask/rpc-errors@npm:7.0.0"
+"@metamask/rpc-errors@npm:^7.0.0, @metamask/rpc-errors@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "@metamask/rpc-errors@npm:7.0.1"
dependencies:
- "@metamask/utils": "npm:^9.0.0"
+ "@metamask/utils": "npm:^10.0.0"
fast-safe-stringify: "npm:^2.0.6"
- checksum: 10/f25e2a5506d4d0d6193c88aef8f035ec189a1177f8aee8fa01c9a33d73b1536ca7b5eea2fb33a477768bbd2abaf16529e68f0b3cf714387e5d6c9178225354fd
+ checksum: 10/819708b4a7d9695ee67fd867d8f94bb5a273b479a242b17bd53c83d1fceec421fc42928f0bb340f4f138ec803dd82ec9659ce7b09a86aedad6a81d5a39ec5c35
languageName: node
linkType: hard
@@ -6397,9 +6397,9 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/transaction-controller@npm:^37.3.0":
- version: 37.3.0
- resolution: "@metamask/transaction-controller@npm:37.3.0"
+"@metamask/transaction-controller@npm:^38.1.0":
+ version: 38.1.0
+ resolution: "@metamask/transaction-controller@npm:38.1.0"
dependencies:
"@ethereumjs/common": "npm:^3.2.0"
"@ethereumjs/tx": "npm:^4.2.0"
@@ -6407,13 +6407,13 @@ __metadata:
"@ethersproject/abi": "npm:^5.7.0"
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
- "@metamask/base-controller": "npm:^7.0.1"
- "@metamask/controller-utils": "npm:^11.3.0"
+ "@metamask/base-controller": "npm:^7.0.2"
+ "@metamask/controller-utils": "npm:^11.4.1"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/nonce-tracker": "npm:^6.0.0"
- "@metamask/rpc-errors": "npm:^6.3.1"
- "@metamask/utils": "npm:^9.1.0"
+ "@metamask/rpc-errors": "npm:^7.0.1"
+ "@metamask/utils": "npm:^10.0.0"
async-mutex: "npm:^0.5.0"
bn.js: "npm:^5.2.1"
eth-method-registry: "npm:^4.0.0"
@@ -6424,9 +6424,9 @@ __metadata:
"@babel/runtime": ^7.23.9
"@metamask/accounts-controller": ^18.0.0
"@metamask/approval-controller": ^7.0.0
- "@metamask/gas-fee-controller": ^20.0.0
- "@metamask/network-controller": ^21.0.0
- checksum: 10/314a46bdaf1a4c68fe232591d28f3f978d7ed17f19dbaa2e3cbcbc4d28d4f7fc4581d7f88446d31ced2176f4f2abf1022ae39a296cb884fd5a083181c562ee2c
+ "@metamask/gas-fee-controller": ^22.0.0
+ "@metamask/network-controller": ^22.0.0
+ checksum: 10/c1bdca52bbbce42a76ec9c640197534ec6c223b0f5d5815acfa53490dc1175850ea9aeeb6ae3c5ec34218f0bdbbbeb3e8731e2552aa9411e3ed7798a5dea8ab5
languageName: node
linkType: hard
@@ -6460,6 +6460,23 @@ __metadata:
languageName: node
linkType: hard
+"@metamask/utils@npm:^10.0.0":
+ version: 10.0.0
+ resolution: "@metamask/utils@npm:10.0.0"
+ dependencies:
+ "@ethereumjs/tx": "npm:^4.2.0"
+ "@metamask/superstruct": "npm:^3.1.0"
+ "@noble/hashes": "npm:^1.3.1"
+ "@scure/base": "npm:^1.1.3"
+ "@types/debug": "npm:^4.1.7"
+ debug: "npm:^4.3.4"
+ pony-cause: "npm:^2.1.10"
+ semver: "npm:^7.5.4"
+ uuid: "npm:^9.0.1"
+ checksum: 10/9c2e6421f685d8a45145b6026a6f9fd0701eb5a2e8490fc6d18e64c103d5a62097f301cbc797790da52ceb5853bd9f65845c934b00299e69e5e6736c52b32f0f
+ languageName: node
+ linkType: hard
+
"@metamask/utils@npm:^8.1.0, @metamask/utils@npm:^8.2.0, @metamask/utils@npm:^8.3.0":
version: 8.5.0
resolution: "@metamask/utils@npm:8.5.0"
@@ -25958,7 +25975,7 @@ __metadata:
"@metamask/snaps-utils": "npm:^8.4.1"
"@metamask/test-bundler": "npm:^1.0.0"
"@metamask/test-dapp": "npm:8.7.0"
- "@metamask/transaction-controller": "npm:^37.3.0"
+ "@metamask/transaction-controller": "npm:^38.1.0"
"@metamask/user-operation-controller": "npm:^13.0.0"
"@metamask/utils": "npm:^9.3.0"
"@ngraveio/bc-ur": "npm:^1.1.12"