Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1f75271
test: updates e2e-testing.md to reflect the current status (#22990)
christopherferreira9 Nov 20, 2025
6427f22
fix(perps): add missing returnOnEquity calculation in HyperLiquidSubs…
michalconsensys Nov 20, 2025
4eb7060
feat: add trending tokens page (#22568)
sahar-fehri Nov 20, 2025
fe2980a
fix: cp-7.60.0 filter out tron staked tokens from send flow (#22979)
Prithpal-Sooriya Nov 20, 2025
ba52e16
feat: allow enroll rewards account in perps flows (#22918)
VGR-GIT Nov 20, 2025
d6c93e0
ci: Change Flask E2E test artifact name (#23035)
GuillaumeRx Nov 20, 2025
cfd16f1
fix: cp-7.60.0 bump transaction controller and transaction pay contro…
matthewwalsh0 Nov 20, 2025
a78c99b
chore: require build number in bug report template (#22948)
gauthierpetetin Nov 20, 2025
e177a12
chore: Bump Snaps packages (#22919)
FrederikBolding Nov 20, 2025
36f7ec4
refactor(perps): decompose PerpsController into specialized services …
abretonc7s Nov 20, 2025
522d6b6
fix: invalid id in bug report template (#23047)
gauthierpetetin Nov 20, 2025
5732b4f
fix: hard code remove GNS feature flag (#22961)
vinnyhoward Nov 20, 2025
3e06436
fix(predict): refactor Predict component tests to remove mocks (#22967)
caieu Nov 20, 2025
1519271
fix: ubuntu-latest instead of cirrus (#23050)
makemesteaks Nov 20, 2025
f29ec33
feat: OTA update exp workflow (#22168)
weitingsun Nov 20, 2025
27e3f35
feat(perps): add recent activity section to market details view (#22865)
michalconsensys Nov 20, 2025
5180a8c
chore: remove MM_REMOVE_GLOBAL_NETWORK_SELECTOR from hooks, lists, an…
vinnyhoward Nov 20, 2025
2b1a33a
chore: timeout build android apk for e2e 30 minutes (#23056)
tommasini Nov 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,18 @@ body:
id: version
attributes:
label: Version
description: What version of MetaMask are you running? You can find the version in "Settings" > "About"
description: What version of MetaMask are you running? You can find the version in "Settings" > "About MetaMask"
placeholder: "7.50.0"
validations:
required: true
- type: input
id: build-number
attributes:
label: Build number
description: What build number of MetaMask are you running? You can find the build number in "Settings" > "About MetaMask"
placeholder: "3055"
validations:
required: true
- type: dropdown
id: build
attributes:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-android-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
build-android-apks:
name: Build Android E2E APKs
runs-on: ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg
timeout-minutes: 40
env:
GRADLE_USER_HOME: /home/admin/_work/.gradle
CACHE_GENERATION: v1 # Increment this to bust the cache (v1, v2, v3, etc.)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/needs-e2e-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ on:
jobs:
needs-e2e-build:
name: Check if builds will happen
runs-on: ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md
runs-on: ubuntu-latest
outputs:
android: ${{ steps.set-outputs.outputs.android_final }}
ios: ${{ steps.set-outputs.outputs.ios_final }}
Expand Down
273 changes: 273 additions & 0 deletions .github/workflows/push-eas-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
name: Push OTA Update (Test)

on:
workflow_dispatch:
inputs:
pr_number:
description: 'Pull request number to publish'
required: true
type: string
base_branch:
description: 'Base branch ref to compare fingerprints against (e.g., main)'
required: true
type: string

permissions:
contents: read
id-token: write

env:
TARGET_PR_NUMBER: ${{ inputs.pr_number }}
BASE_BRANCH_REF: ${{ inputs.base_branch }}

jobs:
fingerprint-comparison:
name: Compare Expo Fingerprints
runs-on: ubuntu-latest
outputs:
branch_fingerprint: ${{ steps.branch_fingerprint.outputs.fingerprint }}
main_fingerprint: ${{ steps.main_fingerprint.outputs.fingerprint }}
fingerprints_equal: ${{ steps.compare.outputs.equal }}
steps:
- name: Checkout target PR branch
uses: actions/checkout@v4
with:
ref: refs/pull/${{ env.TARGET_PR_NUMBER }}/head
fetch-depth: 0

- name: Checkout base branch snapshot
uses: actions/checkout@v4
with:
ref: ${{ env.BASE_BRANCH_REF }}
path: main
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'

- name: Install dependencies (workflow branch)
run: |
echo "📦 Installing dependencies for current branch..."
yarn install --immutable

- name: Generate fingerprint (workflow branch)
id: branch_fingerprint
run: |
echo "🧬 Generating fingerprint for current branch..."
FINGERPRINT=$(yarn fingerprint:generate)
echo "fingerprint=$FINGERPRINT" >> "$GITHUB_OUTPUT"
echo "Target PR fingerprint: $FINGERPRINT"
echo "Writing detailed fingerprint file to fingerprint-pr.json"
npx @expo/fingerprint ./ > fingerprint-pr.json

- name: Install dependencies (base branch)
working-directory: main
run: |
echo "📦 Installing dependencies for base branch snapshot (${BASE_BRANCH_REF})..."
yarn install --immutable

- name: Generate fingerprint (base branch)
id: main_fingerprint
working-directory: main
run: |
echo "🧬 Generating fingerprint for base branch (${BASE_BRANCH_REF})..."
FINGERPRINT=$(yarn fingerprint:generate)
echo "fingerprint=$FINGERPRINT" >> "$GITHUB_OUTPUT"
echo "Base branch fingerprint: $FINGERPRINT"
echo "Writing detailed fingerprint file to ../fingerprint-base.json"
npx @expo/fingerprint ./ > ../fingerprint-base.json

- name: Compare fingerprints
id: compare
env:
BRANCH_FP: ${{ steps.branch_fingerprint.outputs.fingerprint }}
MAIN_FP: ${{ steps.main_fingerprint.outputs.fingerprint }}
run: |
if [ -z "$BRANCH_FP" ] || [ -z "$MAIN_FP" ]; then
echo "❌ Fingerprint generation failed." >&2
exit 1
fi

echo "Target PR fingerprint: $BRANCH_FP"
echo "Base branch fingerprint: $MAIN_FP"

if [ "$BRANCH_FP" = "$MAIN_FP" ]; then
echo "✅ Fingerprints match. No native changes detected."
echo "equal=true" >> "$GITHUB_OUTPUT"
else
echo "⚠️ Fingerprints differ. Native changes detected."
echo "equal=false" >> "$GITHUB_OUTPUT"
if [ -f fingerprint-base.json ] && [ -f fingerprint-pr.json ]; then
echo "Fingerprint differences:"
npx @expo/fingerprint ./ fingerprint-base.json fingerprint-pr.json || true
else
echo "Detailed fingerprint files not found; skipping diff."
fi
fi

- name: Record fingerprint summary
env:
BRANCH_FP: ${{ steps.branch_fingerprint.outputs.fingerprint }}
MAIN_FP: ${{ steps.main_fingerprint.outputs.fingerprint }}
MATCHES: ${{ steps.compare.outputs.equal }}
TARGET_PR_NUMBER: ${{ env.TARGET_PR_NUMBER }}
BASE_BRANCH_REF: ${{ env.BASE_BRANCH_REF }}
run: |
{
echo "### Expo Fingerprint Comparison"
echo ""
echo "- Target PR (#$TARGET_PR_NUMBER) fingerprint: \`$BRANCH_FP\`"
echo "- Base branch (\`$BASE_BRANCH_REF\`) fingerprint: \`$MAIN_FP\`"
echo "- Match: \`$MATCHES\`"
} >> "$GITHUB_STEP_SUMMARY"

approval:
name: Require OTA Update Approval
needs: fingerprint-comparison
if: ${{ needs.fingerprint-comparison.outputs.fingerprints_equal == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Await approval from mobile platform team
uses: op5dev/require-team-approval@dfd7b8b9a88bf82a955c103f7e19642b0411aecd
with:
team: mobile-platform
pr-number: ${{ env.TARGET_PR_NUMBER }}
token: ${{ secrets.METAMASK_MOBILE_ORG_READ_TOKEN }}

push-update:
name: Push EAS Update
runs-on: ubuntu-latest
environment: expo-update
needs:
- fingerprint-comparison
- approval
if: ${{ needs.fingerprint-comparison.outputs.fingerprints_equal == 'true' }}
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
EXPO_PROJECT_ID: ${{ secrets.EXPO_PROJECT_ID }}
EXPO_CHANNEL: ${{ vars.EXPO_CHANNEL }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: refs/pull/${{ env.TARGET_PR_NUMBER }}/head
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'

- name: Install dependencies
run: |
echo "📦 Installing dependencies..."
yarn install --immutable

- name: Setup project
run: |
echo "🔧 Running setup for GitHub CI..."
yarn setup:github-ci

- name: Display configuration
run: |
TARGET_RUNTIME_VERSION=$(node -p "require('./package.json').version")
TARGET_PROJECT_ID=$(node -p "require('./ota.config.js').PROJECT_ID")
echo "🔧 Configuration:"
echo " Channel: ${EXPO_CHANNEL:-<not set>}"
echo " Channel (vars.EXPO_CHANNEL): ${{ vars.EXPO_CHANNEL }}"
echo " Message: test eas update workflow"
echo " Runtime Version (target): ${TARGET_RUNTIME_VERSION}"
# Fingerprint comparison temporarily disabled
echo ""
echo "📱 Project Info:"
echo " Project ID (target branch): ${TARGET_PROJECT_ID}"
echo " EXPO_PROJECT_ID (from secrets): $EXPO_PROJECT_ID"
echo " EXPO_TOKEN (from secrets): $EXPO_TOKEN"

- name: Prepare Expo update signing key
env:
EXPO_KEY_PRIV: ${{ secrets.EXPO_KEY_PRIV }}
run: |
if [ -z "${EXPO_KEY_PRIV}" ]; then
echo "::error title=Missing EXPO_KEY_PRIV::EXPO_KEY_PRIV secret is not configured. Cannot sign update." >&2
exit 1
fi
mkdir -p keys
echo "Writing Expo private key to ./keys/private-key.pem"
printf '%s' "${EXPO_KEY_PRIV}" > keys/private-key.pem

- name: Push EAS Update
env:
# Skip linting during Metro transform in CI (linting already done separately)
SKIP_TRANSFORM_LINT: 'true'
# Increase Node heap to avoid OOM during Expo export in CI
NODE_OPTIONS: '--max_old_space_size=8192'
# Disable LavaMoat sandbox to prevent duplicate bundle executions in CI
EXPO_NO_LAVAMOAT: '1'
run: |
echo "🚀 Publishing EAS update..."

if [ -z "${EXPO_CHANNEL}" ]; then
echo "::error title=Missing EXPO_CHANNEL::EXPO_CHANNEL environment variable is not set. Cannot publish update." >&2
exit 1
fi

if [ ! -f keys/private-key.pem ]; then
echo "::error title=Missing signing key::keys/private-key.pem not found. Ensure the signing key step ran successfully." >&2
exit 1
fi

echo "ℹ️ Git head: $(git rev-parse HEAD)"
echo "ℹ️ Checking for eas script in package.json..."
if ! grep -q '"eas": "eas"' package.json; then
echo "::error title=Missing eas script::package.json does not include an \"eas\" script. Commit hash: $(git rev-parse HEAD)." >&2
exit 1
fi

echo "ℹ️ Available yarn scripts containing eas:"
yarn run --json | grep '"name":"eas"' || true

yarn run eas update \
--channel "${EXPO_CHANNEL}" \
--private-key-path "./keys/private-key.pem" \
--message "test eas update workflow" \
--non-interactive

- name: Update summary
if: success()
run: |
{
echo "### ✅ EAS Update Published Successfully"
echo
echo "**Channel:** \`${EXPO_CHANNEL:-<not set>}\`"
echo "**Message:** test eas update workflow"
echo
echo "Users on the \`${EXPO_CHANNEL:-<not set>}\` channel will receive this update on their next app launch."
} >> "$GITHUB_STEP_SUMMARY"

- name: Update summary on failure
if: failure()
run: |
{
echo "### ❌ EAS Update Failed"
echo
echo "Check the logs above for error details."
} >> "$GITHUB_STEP_SUMMARY"

fingerprint-mismatch:
name: Fingerprint Mismatch Guard
needs: fingerprint-comparison
if: ${{ needs.fingerprint-comparison.outputs.fingerprints_equal != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Fail on native changes
run: |
echo "::error title=Fingerprint mismatch::Current branch fingerprint differs from main. Native changes detected; aborting workflow."
echo "Current fingerprint: ${{ needs.fingerprint-comparison.outputs.branch_fingerprint }}"
echo "Main fingerprint: ${{ needs.fingerprint-comparison.outputs.main_fingerprint }}"
exit 1
2 changes: 1 addition & 1 deletion .github/workflows/run-e2e-smoke-tests-android-flask.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ jobs:
- name: Upload all test artifacts (XMLs + Screenshots)
uses: actions/upload-artifact@v4
with:
name: e2e-smoke-android-all-test-artifacts
name: e2e-smoke-android-flask-all-test-artifacts
path: all-test-artifacts/
24 changes: 23 additions & 1 deletion app/components/Nav/Main/MainNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import AddAsset from '../../Views/AddAsset';
import Collectible from '../../Views/Collectible';
import NftFullView from '../../Views/NftFullView';
import TokensFullView from '../../Views/TokensFullView';
import TrendingTokensFullView from '../../Views/TrendingTokens/TrendingTokensFullView/TrendingTokensFullView';
import SendLegacy from '../../Views/confirmations/legacy/Send';
import SendTo from '../../Views/confirmations/legacy/SendFlow/SendTo';
import { RevealPrivateCredential } from '../../Views/RevealPrivateCredential';
Expand Down Expand Up @@ -920,7 +921,6 @@ const MainNavigator = () => {
const perpsEnabledFlag = useFeatureFlag(
FeatureFlagNames.perpsPerpTradingEnabled,
);
const isEvmSelected = useSelector(selectIsEvmNetworkSelected);
const isPerpsEnabled = useMemo(() => perpsEnabledFlag, [perpsEnabledFlag]);
// Get feature flag state for conditional Predict screen registration
const predictEnabledFlag = useFeatureFlag(
Expand All @@ -933,6 +933,9 @@ const MainNavigator = () => {
const { enabled: isSendRedesignEnabled } = useSelector(
selectSendRedesignFlags,
);
const isAssetsTrendingTokensEnabled = useSelector(
selectAssetsTrendingTokensEnabled,
);

return (
<Stack.Navigator
Expand Down Expand Up @@ -1013,6 +1016,25 @@ const MainNavigator = () => {
}}
/>
<Stack.Screen name="Asset" component={AssetModalFlow} />
<Stack.Screen
name="TrendingTokensFullView"
component={TrendingTokensFullView}
options={{
animationEnabled: true,
cardStyleInterpolator: ({ current, layouts }) => ({
cardStyle: {
transform: [
{
translateX: current.progress.interpolate({
inputRange: [0, 1],
outputRange: [layouts.screen.width, 0],
}),
},
],
},
}),
}}
/>
<Stack.Screen name="Webview" component={Webview} />
<Stack.Screen name="SendView" component={SendView} />
<Stack.Screen
Expand Down
10 changes: 10 additions & 0 deletions app/components/Nav/Main/__snapshots__/MainNavigator.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ exports[`MainNavigator matches rendered snapshot 1`] = `
component={[Function]}
name="Asset"
/>
<Screen
component={[Function]}
name="TrendingTokensFullView"
options={
{
"animationEnabled": true,
"cardStyleInterpolator": [Function],
}
}
/>
<Screen
component={[Function]}
name="Webview"
Expand Down
Loading
Loading