Skip to content

Commit ef784b0

Browse files
chloeYuecursoragent
andcommitted
Merge branch 'stable' into release/7.76.0
Co-authored-by: Cursor <cursoragent@cursor.com>
2 parents 6bd172e + 37ee996 commit ef784b0

20 files changed

Lines changed: 547 additions & 70 deletions

File tree

.github/workflows/build-android-e2e.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ jobs:
5151
path: .metamask
5252
key: .metamask-${{ hashFiles('package.json', 'yarn.lock') }}
5353

54+
- name: Restore .metamask folder (Foundry download cache for install:foundryup)
55+
uses: actions/cache@v4
56+
with:
57+
path: .metamask
58+
key: .metamask-${{ hashFiles('package.json', 'yarn.lock') }}
59+
5460
- name: Setup Android Build Environment
5561
timeout-minutes: 15
5662
uses: ./.github/actions/setup-e2e-env
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
diff --git a/dist/MultichainAssetsController/MultichainAssetsController.cjs b/dist/MultichainAssetsController/MultichainAssetsController.cjs
2+
index 0f74ce9c3200043c7c8fd121218e41790c55cc0e..ee449c44281ae3dd37e73ea0e9cc0b8ee18dea0e 100644
3+
--- a/dist/MultichainAssetsController/MultichainAssetsController.cjs
4+
+++ b/dist/MultichainAssetsController/MultichainAssetsController.cjs
5+
@@ -493,7 +493,7 @@ async function _MultichainAssetsController_getAssetsMetadataFrom(assets, snapId)
6+
});
7+
}, _MultichainAssetsController_filterBlockaidSpamTokensOnAdd =
8+
/**
9+
- * Fail-closed Blockaid filter for newly detected `token:` assets (native/other namespaces unchanged).
10+
+ * Fail-open Blockaid filter for newly detected `token:` assets (native/other namespaces unchanged).
11+
*
12+
* @param assets - CAIP assets to filter.
13+
* @returns Filtered list, original order preserved.
14+
@@ -503,33 +503,25 @@ async function _MultichainAssetsController_filterBlockaidSpamTokensOnAdd(assets)
15+
if (Object.keys(tokensByChain).length === 0) {
16+
return [...assets];
17+
}
18+
- const keptTokenAssets = new Set();
19+
+ const rejectedAssets = new Set();
20+
for (const [chainName, tokenEntries] of Object.entries(tokensByChain)) {
21+
const batchOutcomes = await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_runBatchedBulkTokenScans).call(this, chainName, tokenEntries);
22+
for (const outcome of batchOutcomes) {
23+
if (outcome.status === 'rejected') {
24+
+ // Fail-open: if API fails, allow all tokens in this batch through
25+
continue;
26+
}
27+
for (const entry of outcome.entries) {
28+
const scanned = outcome.response[entry.address];
29+
+ // Reject only if we have a definitive malicious result
30+
if (scanned?.result_type &&
31+
scanned.result_type !== phishing_controller_1.TokenScanResultType.Malicious) {
32+
- keptTokenAssets.add(entry.asset);
33+
+ rejectedAssets.add(entry.asset);
34+
}
35+
}
36+
}
37+
}
38+
- return assets.filter((asset) => {
39+
- try {
40+
- if ((0, utils_1.parseCaipAssetType)(asset).assetNamespace === 'token') {
41+
- return keptTokenAssets.has(asset);
42+
- }
43+
- }
44+
- catch {
45+
- return false;
46+
- }
47+
- return true;
48+
- });
49+
+ return assets.filter((asset) => !rejectedAssets.has(asset));
50+
}, _MultichainAssetsController_findMaliciousTokensAmong =
51+
/**
52+
* SPL `token:` assets in state that Blockaid marks malicious (failed batches skipped).

CHANGELOG.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,89 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [7.75.1]
11+
12+
### Fixed
13+
14+
- Fixed Hyperliquid withdraw showing $0 and being blocked for users on Unified Account mode. (#29492)
15+
16+
## [7.75.0]
17+
18+
### Added
19+
20+
- Added support for ENS v2 (#29258)
21+
- Added a Rive-based animated fox splash screen in place of the static loading spinner for a smoother app launch experience (#29003)
22+
- Hid multichain Activity entries involving tokens flagged as malicious by security scanning, consistent with how malicious tokens are handled on the assets overview (#29239)
23+
- Added Suspicious and Malicious security badges to tokens in the Swaps and Bridge asset pickers (#29070)
24+
- Added security badges to the trending tokens list (#29112)
25+
- Added live mUSD and Veda vault USD balance display on the Money account home page (#28889)
26+
- Added a new hardware connection page (#28019)
27+
- Added an A/B-tested homepage layout that separates trending sections and tracks swap analytics attribution for actions launched from homepage trending sections (#28085)
28+
- Added follow/unfollow functionality for traders (#28843)
29+
- Added hold time to the trader profile view (#28873)
30+
- Extended notification account toggles to all wallet keyrings (#27254)
31+
- Enabled MetaMask Card Cashback for US users (#29138)
32+
- Added an Ondo campaign rewards stats page (#28734)
33+
- Added a migration that resets the native balance to 0 on Tempo chains (#28869)
34+
35+
### Changed
36+
37+
- Hid token warnings in the Swaps asset picker temporarily (#29278)
38+
- Improved MetaMask Card login fields to use the design-system `TextField` with correct username/password autocomplete hints for accessibility and password managers (#29215)
39+
- Moved the Cashback action on Card Home directly under Change asset; the Change asset row no longer shows a trailing chevron in the bottom sheet (#29219)
40+
- Updated the Tempo native token logo (#29105)
41+
- Only show the Transak verify-identity policy screen once on Unified Buy; later visits skip to email entry when not logged in to Transak (#28952)
42+
- Updated token avatars to use only asset image URLs, without a curated token list fallback (#28552)
43+
- Updated the perps section on the Explore screen to display horizontal tile cards with sparkline charts (#28512)
44+
- Stopped using the token list cache for asset overview token details; decimals, aggregators, and market data now come from the asset and token rates (#28533)
45+
- Improved scroll-back user experience in the advanced chart integration on the token details page (#28451)
46+
- Updated app typography and font assets to align with the latest MetaMask design system semibold bold-weight migration (#28363)
47+
- Updated perps chart volume bars to use 30% opacity, matching the transparency style of the spot token details chart (#29132)
48+
- Updated Settings copy so the IPFS gateway is described under Security and privacy instead of Advanced (#29045)
49+
50+
### Fixed
51+
52+
- Fixed featured carousel showing secondary markets instead of the match winner for sports events (#29001)
53+
- Fixed featured carousel showing sports games that had already ended (#29000)
54+
- Fixed Tempo transactions to fall back to a classic transaction when contract deployment is required (#29078)
55+
- Fixed the Confirmation button state by adding a gasless-loading guard, consistent with Extension (#29188)
56+
- Fixed rapid market switching triggering Hyperliquid rate-limit errors (#29056)
57+
- Fixed max mUSD conversion displaying an inflated receive amount (#29175)
58+
- Fixed the mUSD logo not displayed when opening mUSD swap from Rewards (#29194)
59+
- Fixed MetaMask Card home showing zero token balances when the user is not authenticated with the card provider (#29146)
60+
- Fixed a Perps position size formatting bug that stripped valid trailing zeros on whole-unit assets (szDecimals=0), e.g. displaying "1" instead of "100" (#29016)
61+
- Fixed SRP reveal QR code styling to display consistently across light and dark themes (#28969)
62+
- Fixed a visual alignment issue in the Top Traders list where double-digit ranks appeared to be missing their trailing dot (#29099)
63+
- Fixed an iOS-only bug where the header and web content overlapped in the in-app web view screen (#29020)
64+
- Fixed quote polling so the timer stops and interactions are blocked while a quote is being processed (#28862)
65+
- Fixed `wallet_watchAsset` failing with `"Expected a value of type JSON, but received: [object Object]"` when a dapp requested the wallet to watch a token (#29030)
66+
- Fixed bridge quotes showing a misleading 0% price impact when quote price data was unavailable (#28931)
67+
- Fixed incorrect TRX "locked for" value (#29038)
68+
- Fixed a layout shift that happened when following/unfollowing traders with high PnL (#29021)
69+
- Fixed NFT ownership status not refreshing across all enabled networks when pulling to refresh (#28655)
70+
- Fixed noisy Sentry error reports from expected candle fetch cancellations during navigation (#28953)
71+
- Fixed transient UI flashes on the Buy screen (stale "Powered by" text, brief quote-fetch error banner, and a disabled-looking Continue button) when the selected token isn't supported by the current provider and the app is silently switching to a supporting one (#29178)
72+
- Fixed missing error sheet on auth server and seedless login errors (#29227)
73+
- Fixed missing token icons in the predictions pay-with picker for zero-balance tokens (#27702)
74+
75+
## [7.74.3]
76+
77+
### Fixed
78+
79+
- Fix polymarket adapter contract addresses for Android
80+
81+
## [7.74.2]
82+
83+
### Fixed
84+
85+
- Updated Polymarket adapter contracts so Polymarket prediction transactions continue working after the relayer migration. (#29573)
86+
87+
## [7.74.1]
88+
89+
### Fixed
90+
91+
- Fixed the environmental issue that push notifications not received on Android
92+
1093
## [7.74.0]
1194

1295
### Added
@@ -11288,7 +11371,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1128811371
- [#957](https://github.com/MetaMask/metamask-mobile/pull/957): fix timeouts (#957)
1128911372
- [#954](https://github.com/MetaMask/metamask-mobile/pull/954): Bugfix: onboarding navigation (#954)
1129011373

11291-
[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.0...HEAD
11374+
[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.75.1...HEAD
11375+
[7.75.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.75.0...v7.75.1
11376+
[7.75.0]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.3...v7.75.0
11377+
[7.74.3]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.2...v7.74.3
11378+
[7.74.2]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.1...v7.74.2
11379+
[7.74.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.0...v7.74.1
1129211380
[7.74.0]: https://github.com/MetaMask/metamask-mobile/compare/v7.73.2...v7.74.0
1129311381
[7.73.2]: https://github.com/MetaMask/metamask-mobile/compare/v7.73.1...v7.73.2
1129411382
[7.73.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.73.0...v7.73.1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const SHOW_TOKEN_WARNINGS = false;

app/components/UI/Bridge/utils/tokenUtils.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
getNativeSourceToken,
44
getDefaultDestToken,
55
tokenMatchesQuery,
6+
getSecurityWarnings,
67
} from './tokenUtils';
78
import { getSecurityWarnings } from './tokenSecurityUtils';
89
import { BridgeToken } from '../types';

app/components/UI/Bridge/utils/tokenUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ import { DefaultSwapDestTokens } from '../constants/default-swap-dest-tokens';
1212
import { IncludeAsset } from '../hooks/usePopularTokens';
1313
import { POLYGON_NATIVE_TOKEN } from '../constants/assets';
1414

15+
/**
16+
* Extracts security warning descriptions from a token's securityData metadata features.
17+
* Returns an empty array when the token has no security warnings.
18+
*/
19+
export const getSecurityWarnings = (
20+
token: BridgeToken | undefined | null,
21+
): string[] =>
22+
token?.securityData?.metadata?.features?.map((f) => f.description) ?? [];
23+
1524
/**
1625
* Normalizes chain-specific native token addresses to the zero address for the bridge flow.
1726
*

app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.test.tsx

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,68 +1301,6 @@ describe('EarnMusdConversionEducationView', () => {
13011301
expect(mockTrackEvent).toHaveBeenCalledWith({ name: 'mock-built-event' });
13021302
});
13031303

1304-
it('includes redirects_to money_hub when secondary button pressed with deeplink, Money Hub enabled, and geo-eligible', () => {
1305-
mockSelectMoneyHubEnabledFlag.mockReturnValue(true);
1306-
mockUseParams.mockReturnValue({ isDeeplink: true });
1307-
1308-
const { getByTestId } = renderWithProvider(
1309-
<EarnMusdConversionEducationView />,
1310-
{ state: {} },
1311-
);
1312-
1313-
mockTrackEvent.mockClear();
1314-
mockCreateEventBuilder.mockClear();
1315-
mockAddProperties.mockClear();
1316-
mockBuild.mockClear();
1317-
1318-
fireEvent.press(
1319-
getByTestId(
1320-
EARN_TEST_IDS.MUSD.CONVERSION_EDUCATION_VIEW.SECONDARY_BUTTON,
1321-
),
1322-
);
1323-
1324-
expect(mockCreateEventBuilder).toHaveBeenCalledWith(
1325-
MetaMetricsEvents.MUSD_FULLSCREEN_ANNOUNCEMENT_BUTTON_CLICKED,
1326-
);
1327-
expect(mockAddProperties).toHaveBeenCalledWith({
1328-
location:
1329-
MUSD_EVENTS_CONSTANTS.EVENT_LOCATIONS.CONVERSION_EDUCATION_SCREEN,
1330-
button_type: 'secondary',
1331-
button_text: strings('earn.musd_conversion.education.secondary_button'),
1332-
redirects_to: MONEY_EVENTS_CONSTANTS.EVENT_LOCATIONS.MONEY_HUB,
1333-
});
1334-
});
1335-
1336-
it('omits redirects_to when secondary button pressed in normal non-deeplink flow', () => {
1337-
mockUseParams.mockReturnValue({ isDeeplink: false });
1338-
1339-
const { getByTestId } = renderWithProvider(
1340-
<EarnMusdConversionEducationView />,
1341-
{ state: {} },
1342-
);
1343-
1344-
mockTrackEvent.mockClear();
1345-
mockCreateEventBuilder.mockClear();
1346-
mockAddProperties.mockClear();
1347-
mockBuild.mockClear();
1348-
1349-
fireEvent.press(
1350-
getByTestId(
1351-
EARN_TEST_IDS.MUSD.CONVERSION_EDUCATION_VIEW.SECONDARY_BUTTON,
1352-
),
1353-
);
1354-
1355-
expect(mockAddProperties).toHaveBeenCalledWith({
1356-
location:
1357-
MUSD_EVENTS_CONSTANTS.EVENT_LOCATIONS.CONVERSION_EDUCATION_SCREEN,
1358-
button_type: 'secondary',
1359-
button_text: strings('earn.musd_conversion.education.secondary_button'),
1360-
});
1361-
expect(mockAddProperties).not.toHaveBeenCalledWith(
1362-
expect.objectContaining({ redirects_to: expect.anything() }),
1363-
);
1364-
});
1365-
13661304
it('tracks money_hub redirect when continue is pressed with returnTo', async () => {
13671305
mockUseParams.mockReturnValue({
13681306
returnTo: { screen: Routes.WALLET.CASH_TOKENS_FULL_VIEW },

app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import { selectMusdQuickConvertEnabledFlag } from '../../selectors/featureFlags'
4848
import { toChecksumAddress } from '../../../../../util/address';
4949
import { safeFormatChainIdToHex } from '../../../Card/util/safeFormatChainIdToHex';
5050
import { MONEY_EVENTS_CONSTANTS } from '../../../Money/constants/moneyEvents';
51-
import { selectMoneyHubEnabledFlag } from '../../../Money/selectors/featureFlags';
51+
import { selectMoneyHubEnabledFlag } from '../../../Money/selectors/featureFlags.ts';
5252
interface EarnMusdConversionEducationViewRouteParams {
5353
/**
5454
* Indicates if this navigation originated from a deeplink
@@ -224,8 +224,6 @@ const EarnMusdConversionEducationView = () => {
224224
: MUSD_EVENT_LOCATIONS.CUSTOM_AMOUNT_SCREEN;
225225
if (returnTo) {
226226
redirectsTo = MONEY_EVENT_LOCATIONS.MONEY_HUB;
227-
} else if (deeplinkState?.action === 'navigate_money_hub') {
228-
redirectsTo = MONEY_EVENT_LOCATIONS.MONEY_HUB;
229227
} else if (deeplinkState?.action === 'navigate_home') {
230228
redirectsTo = MUSD_EVENT_LOCATIONS.HOME_SCREEN;
231229
} else if (deeplinkState?.action === 'buy') {

app/components/UI/Predict/providers/polymarket/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ export const COLLATERAL_ONRAMP_ADDRESS =
8989
'0x93070a847efEf7F70739046A929D47a521F5B8ee';
9090

9191
export const CTF_COLLATERAL_ADAPTER_ADDRESS =
92-
'0xADa100874d00e3331D00F2007a9c336a65009718';
92+
'0xAdA100Db00Ca00073811820692005400218FcE1f';
9393

9494
export const NEG_RISK_CTF_COLLATERAL_ADAPTER_ADDRESS =
95-
'0xAdA200001000ef00D07553cEE7006808F895c6F1';
95+
'0xadA2005600Dec949baf300f4C6120000bDB6eAab';
9696

9797
export const POLYGON_PUSD_CAIP_ASSET_ID =
9898
`${POLYGON_MAINNET_CAIP_CHAIN_ID}/erc20:${MATIC_CONTRACTS_V2.collateral}` as const;

app/components/UI/Rewards/Views/OndoCampaignDetailsView.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ const OndoCampaignDetailsView: React.FC = () => {
211211
);
212212

213213
const {
214-
leaderboard,
215214
selectedTier,
216215
selectedTierData,
217216
setSelectedTier,
@@ -298,6 +297,13 @@ const OndoCampaignDetailsView: React.FC = () => {
298297
});
299298
}, [navigation, effectiveCampaignId, campaign]);
300299

300+
const navigateToWinningView = useCallback(() => {
301+
navigation.navigate(Routes.REWARDS_ONDO_CAMPAIGN_WINNING_VIEW, {
302+
campaignId: effectiveCampaignId,
303+
campaignName: campaign?.name ?? '',
304+
});
305+
}, [navigation, effectiveCampaignId, campaign]);
306+
301307
return (
302308
<ErrorBoundary navigation={navigation} view="OndoCampaignDetailsView">
303309
<SafeAreaView

0 commit comments

Comments
 (0)