Skip to content

Commit d0bcd2b

Browse files
authored
Merge branch 'main' into MUSD-660-money-account-activity
2 parents 7910ef5 + c66572b commit d0bcd2b

272 files changed

Lines changed: 14307 additions & 6420 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ app/components/Views/Homepage/Sections/Perpetuals/ @MetaMask/perps
206206
# Social & AI Team
207207
app/components/Views/SocialLeaderboard/ @MetaMask/social-ai
208208
app/components/UI/MarketInsights/ @MetaMask/social-ai
209-
app/components/Views/Homepage/Sections/WhatsHappening/ @MetaMask/social-ai
209+
app/components/UI/WhatsHappening/ @MetaMask/social-ai
210210
app/components/Views/Homepage/Sections/TopTraders/ @MetaMask/social-ai
211211
app/core/Engine/controllers/social-controller-init* @MetaMask/social-ai
212212
app/core/Engine/controllers/social-service-init* @MetaMask/social-ai

.github/workflows/ci.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,14 @@ jobs:
9696
outputs:
9797
fingerprint: ${{ steps.publish.outputs.fingerprint }}
9898
steps:
99-
- uses: actions/checkout@v4
100-
with:
101-
ref: ${{ github.event.pull_request.head.sha || github.sha }}
102-
- uses: actions/setup-node@v4
99+
# Use the default ref (refs/pull/N/merge on pull_request, github.sha otherwise) so the
100+
# fingerprint is computed against the SAME working tree that `build-android-e2e.yml`,
101+
# `build-ios-e2e.yml`, and `run-e2e-workflow.yml` check out and build/test against.
102+
# Posting on `pull_request.head.sha` while fingerprinting the PR head tree would let
103+
# two PRs with identical heads but different merges collide on the cache key — and the
104+
# native build then runs against a different (merge) tree than the one we fingerprinted.
105+
- uses: actions/checkout@v6
106+
- uses: actions/setup-node@v6
103107
with:
104108
node-version-file: '.nvmrc'
105109
cache: yarn
@@ -115,8 +119,11 @@ jobs:
115119
uses: ./.github/actions/post-build-source-hash
116120
with:
117121
github-token: ${{ github.token }}
118-
# .head.sha = PR head (pull_request events); github.sha fallback = pushed/scheduled commit
119-
# (push to main, merge_group, schedule) where no PR payload exists.
122+
# Commit statuses must be posted on a real commit SHA (not the merge ref).
123+
# `find-reusable-build` looks up the status via `run.head_sha` from
124+
# `listWorkflowRuns`, which GitHub reports as the PR head SHA for pull_request
125+
# events and as the pushed/scheduled commit SHA otherwise — so this is the same
126+
# SHA the lookup queries against.
120127
target-sha: ${{ github.event.pull_request.head.sha || github.sha }}
121128

122129
dedupe:

.github/workflows/nightly-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
source_branch: main
4444
environment: rc
4545
testflight_group: 'MetaMask BETA & Release Candidates'
46-
distribute_external: true
46+
distribute_external: false
4747
secrets: inherit
4848

4949
# ── Android exp: ephemeral branch + build ──────────────────────────────

.github/workflows/release-branch-sync.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ jobs:
2323
env:
2424
BRANCH: ${{ github.event.pull_request.head.ref }}
2525
run: |
26-
if [[ "$BRANCH" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
27-
echo "Branch '$BRANCH' matches release/X.Y.Z format"
26+
if [[ "$BRANCH" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+ ]]; then
27+
echo "Branch '$BRANCH' starts with release/X.Y.Z"
2828
echo "is-valid=true" >> "$GITHUB_OUTPUT"
2929
else
30-
echo "Branch '$BRANCH' does not match release/X.Y.Z format. Skipping."
30+
echo "Branch '$BRANCH' does not start with release/X.Y.Z. Skipping."
3131
echo "is-valid=false" >> "$GITHUB_OUTPUT"
3232
fi
3333
@@ -38,7 +38,7 @@ jobs:
3838
runs-on: ubuntu-latest
3939
steps:
4040
- name: Sync release branches with stable
41-
uses: metamask/github-tools/.github/actions/release-branch-sync@v1.2.0
41+
uses: metamask/github-tools/.github/actions/release-branch-sync@v1
4242
with:
4343
merged-release-branch: ${{ github.event.pull_request.head.ref }}
4444
github-token: ${{ secrets.STABLE_SYNC_TOKEN }}

CHANGELOG.md

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [7.76.3]
11+
12+
### Added
13+
14+
- Added Predict transaction publishing hooks to support the Polymarket Deposit Wallet flow. (#29914)
15+
- Added support for depositing to a Polymarket Deposit Wallet in Predict, while preserving legacy Safe behavior for users with existing Polymarket activity. (#29917)
16+
- Added Polymarket Deposit Wallet order placement support in Predict. (#29933)
17+
- Added support for claiming Predict positions through the Polymarket Deposit Wallet. (#29936)
18+
19+
### Fixed
20+
21+
- Disabled Predict withdrawals for Polymarket Deposit Wallet users with a temporary "withdrawals unavailable" bottom sheet, while legacy Safe users keep the existing flow. (#29941)
22+
23+
## [7.76.0]
24+
25+
### Added
26+
27+
- Added the Tempo chain to the additional networks list. (#29515)
28+
- Added security trust badges in the token list. (#29509)
29+
- Added a new "Add money" bottom sheet to the Money Account homepage with Convert crypto, Deposit funds, Move mUSD, and Receive from external wallet options. (#29336)
30+
- Added a developer options button to clear dismissed mUSD conversion asset details CTAs. (#29510)
31+
- Added a quickbuy smart default. (#29472)
32+
- Added SOL as a "Pay with" option on Quickbuy. (#29424)
33+
- Added a transaction fees expandable section to Quickbuy. (#29321)
34+
- Added a General Settings toggle for haptic feedback and centralized in-app haptics behind a single module, with an optional remote kill switch. (#28975)
35+
- Added haptic feedback across Top Traders surfaces (Follow, Buy, notification preferences, per-trader notifications). (#29467)
36+
- Added support for additional sports market types (spreads, totals, halftime result, exact score, player props) on prediction market event detail screens. (#29216)
37+
- Added inline error banners in the Predict buy bottom sheet for price-changed and order-failed scenarios, replacing the secondary retry sheet and failure toast when the predictBottomSheet flag is enabled. (#29184)
38+
- Added a Quickbuy half sheet. (#28863)
39+
- Added a warning flow in bridge quotes when token price data is unavailable. (#29250)
40+
1041
### Changed
1142

12-
- Aligned previously base-enabled custom network logos (Stable, Flow, XDC, Fraxtal, Hemi, Plasma, Lukso, Rootstock, MSU, Lens, Plume) to a square format consistent with Popular networks (#29943)
43+
- Enabled Suspicious and Malicious security badges on tokens in the Swaps/Bridge asset picker. (#29570)
44+
- Updated the description under the "Smart account requests from dapps" setting to clarify that MetaMask will only upgrade to our audited smart account. (#29211)
45+
- Updated Predict confirmations to display pUSD as the Predict token. (#29450)
46+
- Updated the token details security trust designs. (#29230)
47+
- Polished the social leaderboard with podium decorations on the top 3 traders, a tighter loading skeleton, and a chain icon overlay on token avatars in the trader position and quick buy views. (#29408)
48+
- QR wallet now shares the signing flow with Ledger. (#29087)
49+
- In-app browser sessions opened from MetaMask Card (manage card and travel) now return to Card Home on close instead of the Explore tab. (#29218)
50+
- Updated the Bridge/Swaps token warning modal to match the new design and fixed swapped warning/malicious icons in the token selector. (#29197)
51+
- Updated the account selector to use the full-page list for all users and removed the dropdown arrow from the wallet account picker. (#28701)
52+
- Refined section and header styles for Perps. (#29009)
53+
- Refined explore page design patterns. (#29396)
54+
- Adjusted spacing for money activity filters. (#29463)
55+
56+
### Fixed
57+
58+
- Fixed a bug where the -1%/-2% limit price preset buttons only applied on the first press. (#29373)
59+
- Fixed Card Home flickering during refresh and kept Add funds available for frozen cards. (#29513)
60+
- Fixed a bug that caused the MetaMask Card spending limit screen to default to full access when a custom limit was already set. (#29517)
61+
- Fixed cashback redemption to require an approved Linea funding source. (#29489)
62+
- Fixed UB2 Transak order details to hide interim provider messages during processing states. (#29131)
63+
- Fixed a bug where a stale secondary minimum purchase message could briefly appear after entering a valid buy amount. (#29365)
64+
- Fixed a bug that caused live Predict sports scores to appear in reverse order for some leagues. (#29453)
65+
- Fixed Ledger BLE transport that prevented reconnecting to a Ledger device after a timeout or completed signing flow. (#29367)
66+
- Fixed chart re-rendering and flickering. (#29344)
67+
- Fixed excessive red flashing while entering buy amounts near minimum and maximum provider limits. (#29360)
68+
- Fixed stale unauthenticated MetaMask Card data after login by refetching when card feature flags change. (#29350)
69+
- Prevented invalid bridge transaction hashes from being persisted in transaction history. (#29136)
70+
- Fixed WalletConnect sign requests occasionally displaying a garbled string in the "Request from" field instead of the dapp's domain. (#29102)
71+
- Fixed Perps Withdraw Max so users actually withdraw their full HyperLiquid balance; replaced 90% with a Max button and aligned Perps home and Withdraw to show the same balance. (#29257)
72+
- Hid the sponsored label on cross-chain bridge with insufficient balance. (#29490)
1373

1474
## [7.75.1]
1575

@@ -11375,7 +11435,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1137511435
- [#957](https://github.com/MetaMask/metamask-mobile/pull/957): fix timeouts (#957)
1137611436
- [#954](https://github.com/MetaMask/metamask-mobile/pull/954): Bugfix: onboarding navigation (#954)
1137711437

11378-
[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.75.1...HEAD
11438+
[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.76.3...HEAD
11439+
[7.76.3]: https://github.com/MetaMask/metamask-mobile/compare/v7.76.0...v7.76.3
11440+
[7.76.0]: https://github.com/MetaMask/metamask-mobile/compare/v7.75.1...v7.76.0
1137911441
[7.75.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.75.0...v7.75.1
1138011442
[7.75.0]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.3...v7.75.0
1138111443
[7.74.3]: https://github.com/MetaMask/metamask-mobile/compare/v7.74.2...v7.74.3

android/gradle.properties.release

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Gradle settings for GitHub Actions release/production builds (LG runner, 48GB RAM)
22

33
# JVM: 8GB heap to leave room for Metro workers + Kotlin daemon
4-
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+UseStringDeduplication -XX:+OptimizeStringConcat -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
4+
# MaxMetaspaceSize 2g to match gradle.properties.github (512m causes daemon OOM)
5+
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=2g -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+UseStringDeduplication -XX:+OptimizeStringConcat -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
56

67
org.gradle.parallel=true
78
org.gradle.configureondemand=true
@@ -16,8 +17,8 @@ org.gradle.vfs.watch=false
1617
kotlin.incremental=true
1718
kotlin.incremental.android=true
1819
kotlin.caching.enabled=true
19-
# Kotlin daemon: 2GB cap to prevent memory contention
20-
kotlin.daemon.jvmargs=-Xmx2g -XX:+UseG1GC -XX:+ExitOnOutOfMemoryError
20+
# Kotlin daemon: 2GB heap, 1GB metaspace to match gradle.properties.github
21+
kotlin.daemon.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:+ExitOnOutOfMemoryError
2122

2223
# File system optimizations
2324
org.gradle.vfs.verbose=false

app/__mocks__/react-native-vision-camera.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { CAMERA_PERMISSION_STATUS } from '../constants/permissions';
23

34
const mockDevice = {
45
id: 'back',
@@ -21,7 +22,9 @@ const mockDevice = {
2122

2223
const mockPermission = {
2324
hasPermission: true,
24-
requestPermission: jest.fn().mockResolvedValue('granted'),
25+
requestPermission: jest
26+
.fn()
27+
.mockResolvedValue(CAMERA_PERMISSION_STATUS.granted),
2528
};
2629

2730
let capturedOnCodeScanned:
@@ -76,8 +79,10 @@ const useCodeScanner = jest.fn((config) => {
7679
// Static methods on Camera - using Object.assign to avoid TypeScript issues
7780
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7881
(Object as any).assign(Camera, {
79-
getCameraPermissionStatus: jest.fn(() => 'granted'),
80-
requestCameraPermission: jest.fn().mockResolvedValue('granted'),
82+
getCameraPermissionStatus: jest.fn(() => CAMERA_PERMISSION_STATUS.granted),
83+
requestCameraPermission: jest
84+
.fn()
85+
.mockResolvedValue(CAMERA_PERMISSION_STATUS.granted),
8186
});
8287

8388
export { Camera, useCameraDevice, useCameraPermission, useCodeScanner };

app/components/UI/AssetOverview/Balance/Balance.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ import BadgeWrapper, {
2323
} from '../../../../component-library/components/Badges/BadgeWrapper';
2424
import { BadgeVariant } from '../../../../component-library/components/Badges/Badge/Badge.types';
2525
import Badge from '../../../../component-library/components/Badges/Badge/Badge';
26-
import AvatarToken from '../../../../component-library/components/Avatars/Avatar/variants/AvatarToken';
27-
import { AvatarSize } from '../../../../component-library/components/Avatars/Avatar';
2826
import NetworkAssetLogo from '../../NetworkAssetLogo';
2927
import Text, {
3028
TextColor,
@@ -53,6 +51,7 @@ import { ACCOUNT_TYPE_LABELS } from '../../../../constants/account-type-labels';
5351
import { useRWAToken } from '../../Bridge/hooks/useRWAToken';
5452
import { BridgeToken } from '../../Bridge/types';
5553
import StockBadge from '../../shared/StockBadge';
54+
import AssetLogo from '../../Assets/components/AssetLogo/AssetLogo';
5655

5756
export const ACCOUNT_TYPE_LABEL_TEST_ID = 'account-type-label';
5857

@@ -186,13 +185,7 @@ const Balance = ({
186185
);
187186
}
188187

189-
return (
190-
<AvatarToken
191-
name={asset.symbol}
192-
imageSource={{ uri: asset.image }}
193-
size={AvatarSize.Lg}
194-
/>
195-
);
188+
return <AssetLogo asset={asset} />;
196189
}, [asset, styles.ethLogo]);
197190

198191
const isDisabled = useMemo(

app/components/UI/Assets/components/Balance/AccountGroupBalance.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import AccountGroupBalanceChange from '../../components/BalanceChange/AccountGro
3737
import BalanceEmptyState from '../../../BalanceEmptyState';
3838
import WalletHomeOnboardingSteps from '../../../WalletHomeOnboardingSteps';
3939
import { useRampNavigation } from '../../../Ramp/hooks/useRampNavigation';
40+
import { useWalletHomeOnboardingChecklistFundPress } from '../../../WalletHomeOnboardingSteps/useWalletHomeOnboardingChecklistFundPress';
4041

4142
/**
4243
* Timeout for account group balance fetch
@@ -82,6 +83,8 @@ const AccountGroupBalance = ({
8283
selectWalletHomeOnboardingSkipInitialBalanceWait,
8384
);
8485
const { goToBuy } = useRampNavigation();
86+
const onFundPrimaryPressWithChecklistAnalytics =
87+
useWalletHomeOnboardingChecklistFundPress(goToBuy);
8588
const { popularNetworks } = useNetworkEnablement();
8689

8790
// Stabilize chain IDs by content so selector identity doesn't change every render (avoids max depth / infinite loop).
@@ -266,7 +269,7 @@ const AccountGroupBalance = ({
266269
isAwaitingBalance={awaitBalanceForPostOnboardingSteps}
267270
onCoordinatedFlowExit={onCoordinatedFlowExit}
268271
suspendRiveForCurtain={suspendRiveForCurtain}
269-
onFundPrimaryPress={goToBuy}
272+
onFundPrimaryPress={onFundPrimaryPressWithChecklistAnalytics}
270273
canAdvanceFundStepAfterBalance={canAdvanceFundStepAfterBalance}
271274
onTradePrimaryPress={onTradePrimaryPress}
272275
onNotificationsPrimaryPress={onNotificationsPrimaryPress}

app/components/UI/Bridge/hooks/useBridgeQuoteData/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ export const useBridgeQuoteData = ({
280280
);
281281

282282
const validateQuote = useCallback(async () => {
283-
if (!activeQuote || (!isSolanaSwap && !isSolanaToNonSolana)) {
283+
if (
284+
!activeQuote ||
285+
(!isSolanaSwap && !isSolanaToNonSolana) ||
286+
// Skip validation for gas-included quotes on Solana
287+
activeQuote?.quote?.gasIncluded === true
288+
) {
284289
lastValidatedQuoteRef.current = null;
285290
setBlockaidError(null);
286291
return;

0 commit comments

Comments
 (0)