Mobile web browser providing access to websites that use the Ethereum blockchain https://metamask.io
  • TypeScript 96.4%
  • JavaScript 3.1%
  • Shell 0.2%
  • HTML 0.2%
Find a file
Kirill Zyusko c6cc33f4ef
feat: Skeleton migration (predict team) (#29052)
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

Migrate `Skeleton` component (predict team).

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-465

## **Manual testing steps**

```gherkin
Feature: skeleton migration

  Scenario: user checks prediction
    Given the user on prediction page

    When user clicks yes for a prediction
    Then skeleton should be visible
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/82e49081-c108-4588-b972-df29cc8acc48"
/>

### **After**

<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/f41fa30c-1245-4114-9340-b9b9799f6130"
/>

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Import-only design-system path updates with no behavior changes; low
regression risk beyond loading UI appearance if the temp Skeleton API
differs.
> 
> **Overview**
> Updates Predict buy flow UI to import **Skeleton** from
`component-library/components-temp/Skeleton` instead of the legacy
`components/Skeleton` path.
> 
> **PredictBuyAmountSection** and **PredictFeeSummary** keep the same
loading placeholders; only the module path changes. The
**PredictBuyAmountSection** test mock is updated to match the new
import.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
20d9b1d0ac. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-06-10 12:20:02 +00:00
.ai-pr-analyzer fix: re-enable AI PR analysis condition in workflow (#30034) 2026-05-29 11:16:59 +00:00
.bundle
.claude refactor(tooling): replace SQLite skill tracking with CSV log and Cursor slash-command hook (#29139) 2026-05-18 09:34:30 +00:00
.cursor refactor(tooling): replace SQLite skill tracking with CSV log and Cursor slash-command hook (#29139) 2026-05-18 09:34:30 +00:00
.github test: Fix/aggregate reports search dirs + performance smart selection (#29106) 2026-06-10 11:00:09 +00:00
.husky
.storybook feat(component-library): add shared Pressable primitive and migrate Settings Drawer (#30543) 2026-05-27 12:56:05 +00:00
.vscode
.yarn refactor(transaction-controller): migrate to v67 (#31241) 2026-06-09 10:27:31 +00:00
android release: Bump main version to 7.82.0 (#31102) 2026-06-04 23:02:45 +00:00
app feat: Skeleton migration (predict team) (#29052) 2026-06-10 12:20:02 +00:00
certs
docs chore(predict): add minimal analytics for predict portfolio module and positions screen (#30980) 2026-06-09 15:58:45 +00:00
ios release: Bump main version to 7.82.0 (#31102) 2026-06-04 23:02:45 +00:00
locales feat: conditionally display predict account selector on predict deposit page (#31407) 2026-06-10 11:02:04 +00:00
patches fix: react-native-scrollable-tab-view underline style positioning (#30133) 2026-05-14 14:29:36 +00:00
scripts chore(skills): add opt-in install auto-update (#30924) 2026-06-09 13:49:43 +00:00
sourcemaps
tests test: Fix/aggregate reports search dirs + performance smart selection (#29106) 2026-06-10 11:00:09 +00:00
.android.env.example feat: Braze SDK integration [GE-107] cp-7.72.0 (#27881) 2026-03-31 08:39:00 +00:00
.buckconfig
.depcheckrc.yml feat: add agent-device tooling for AI simulator control (#30302) 2026-05-25 13:52:09 +00:00
.detoxrc.js chore: Remove all bitrise artifacts (#30204) 2026-05-14 14:47:53 -07:00
.e2e.env.example test: decouples METAMASK_ENVIRONMENT from having test overrides (#30747) 2026-06-03 11:02:09 +01:00
.editorconfig
.eslintignore refactor(tests): reorganize CI tests scripts and update QA CODEOWNERS file (#29181) 2026-04-22 16:25:17 +00:00
.eslintrc.js feat(perps): TAT-3187 remove local perps-controller, depend on @metamask/perps-controller (#30507) 2026-05-27 16:47:47 +00:00
.git-blame-ignore-revs
.gitattributes fix(skills): pin *.sh to LF so scripts run in WSL (#30078) 2026-05-14 14:51:00 +00:00
.gitignore chore(skills): switch to public MetaMask/skills with optional Consensys overlay (#30180) 2026-05-21 06:19:03 +00:00
.gitmodules chore: podfile and pbxproj alignment (#29893) 2026-05-08 11:29:13 +00:00
.ios.env.example feat: Braze SDK integration [GE-107] cp-7.72.0 (#27881) 2026-03-31 08:39:00 +00:00
.js.env.example chore: bump compliance controller to 2.1.0 (#30906) 2026-06-04 17:20:11 +00:00
.npmrc chore: add npmrc file with ignore-scripts. yes, and offline configuration (#29882) 2026-05-08 17:29:25 +00:00
.nvmrc
.prettierignore
.prettierrc.js
.ruby-version
.skills.local.example chore(skills): add opt-in install auto-update (#30924) 2026-06-09 13:49:43 +00:00
.watchmanconfig
.yarnrc.yml chore: update uuid to v14.0.0 (#29224) 2026-05-19 22:21:54 +00:00
AGENTS.md docs(performance): restructure performance docs into docs/performance/ (#30866) 2026-06-05 16:45:29 +00:00
app.config.js feat: Fully enable react compiler and bump to stable version (#31171) 2026-06-08 14:56:07 -07:00
architecture.svg
attribution.txt
babel.config.js feat: Fully enable react compiler and bump to stable version (#31171) 2026-06-08 14:56:07 -07:00
babel.config.tests.js test: add Playwright performance debug logging (#31214) 2026-06-09 18:33:09 +00:00
bitrise.yml release: Bump main version to 7.82.0 (#31102) 2026-06-04 23:02:45 +00:00
branch.json fix: disable Branch test instance and debug mode in branch.json cp-7.71.0 (#27879) 2026-03-24 20:17:07 +00:00
builds.yml chore: bump compliance controller to 2.1.0 (#30906) 2026-06-04 17:20:11 +00:00
ccache.conf
CHANGELOG.md chore(release): release-changelog/7.80.0 (#30777) 2026-06-04 23:52:07 +01:00
CLAUDE.md chore: add CLAUDE.md to wrap AGENTS.md (#30395) 2026-05-21 09:34:09 +00:00
codecov.yml
coverage-thresholds.json
crowdin.yml
fingerprint.config.js fix(fingerprint): exclude JS-only changes from EAS fingerprint (#30332) 2026-06-02 15:51:57 +00:00
firebase.json
image.png
index.js test: decouples METAMASK_ENVIRONMENT from having test overrides (#30747) 2026-06-03 11:02:09 +01:00
jest.config.js chore: bump compliance controller to 2.1.0 (#30906) 2026-06-04 17:20:11 +00:00
jest.config.view.js test: decouples METAMASK_ENVIRONMENT from having test overrides (#30747) 2026-06-03 11:02:09 +01:00
junitProperties.js
LICENSE
logo.png
metro.config.js test: decouples METAMASK_ENVIRONMENT from having test overrides (#30747) 2026-06-03 11:02:09 +01:00
metro.transform.js chore: Remove all bitrise artifacts (#30204) 2026-05-14 14:47:53 -07:00
ota.config.js
package.json feat: add snap-account-service (#30329) 2026-06-10 12:03:58 +00:00
react-native.config.js feat: React Native Upgrade / 0.81.5 (#29195) 2026-05-07 23:54:37 +01:00
ReactotronConfig.js
README.md chore(skills): add opt-in install auto-update (#30924) 2026-06-09 13:49:43 +00:00
sentry.debug.properties.example
sentry.properties
sentry.release.properties.example
shim.js test: decouples METAMASK_ENVIRONMENT from having test overrides (#30747) 2026-06-03 11:02:09 +01:00
shim.test.js fix(perps): investigate Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event' (#30612) 2026-05-26 16:39:33 +00:00
shimPerf.js
sonar-project.properties chore: exclude store migrations from SonarCloud CPD (#28292) 2026-04-01 22:59:48 +00:00
tailwind.config.js
tsconfig.json feat: add snap-account-service (#30329) 2026-06-10 12:03:58 +00:00
tsdoc.json
wdyr.js
yarn.lock feat: add snap-account-service (#30329) 2026-06-10 12:03:58 +00:00

MetaMask logo

MetaMask Mobile

CI CLA

MetaMask is a mobile wallet that provides easy access to websites that use the Ethereum blockchain.

For up to the minute news, follow our Twitter or Medium pages.

To learn how to develop MetaMask-compatible applications, visit our Developer Docs.

To learn how to contribute to the MetaMask codebase, visit our Contributor Docs.

Documentation

Getting started

Infura Project Setup

MetaMask Mobile requires an Infura project ID to connect to blockchain networks.

Internal Contributors

  1. Grab the .js.env file from 1Password, ask around for the correct vault. This file contains the MM_INFURA_PROJECT_ID.

External Contributors

  1. Go to https://developer.metamask.io and create an account
  2. Generate an API key
  3. Add API key to MM_INFURA_PROJECT_ID in .js.env.example
  4. Rename .js.env.example to .js.env
  5. Rebuild the app

[!CAUTION]

Without an Infura project ID, the app cannot connect to blockchain networks.

Expo is the fastest way to start developing. With the Expo framework, developers don't need to compile the native side of the application as before, hence no need for any native environment setup, developers only need to download a precompiled development build and run the javascript bundler. The development build will then connect with the bundler to load the javascript code.

Expo Environment Setup

Install node, yarn v4 and watchman.

Clone the project

git clone git@github.com:MetaMask/metamask-mobile.git && \
cd metamask-mobile

Install dependencies

yarn setup:expo

Run the bundler

yarn watch

Download and install the development build

  • Expo development builds are hosted in Runway buckets and are made available to all contributors through the public bucket links below. A new build is generated every time a PR is merged into the main branch.

  • For Android:

    • Download and install an .apk file from this Runway bucket onto your Android device or emulator.
  • For iOS:

    • Physical device
      • Your test device needs to first be registered with our Apple developer account.
      • Once registered, download and install an .ipa file from this Runway bucket onto your device.
    • Simulator
      • Download and install an .app file from this Runway bucket onto your simulator.
      • Note: Our .app files are zipped and hosted under Additional Artifacts in the bucket. Since this hosting additional artifacts in public buckets is a relatively new feature, contributors may find that some builds are missing additional artifacts. Under the hood, these are usually associated with failed or aborted CI builds. We are working with the Runway team to better filter out these builds and are subject to change in the future.

Load the app

If on a simulator:

  • use the initial expo screen that appears when starting the development to choose the bundler url
  • OR press "a" for Android or "i" for iOS on the terminal where the bundler is running

If on a physical device:

  • Use the camera app to scan the QR code presented by the bundler running on the terminal

That's it! This will work for any javascript development, if you need to develop or modify native code please see the next section.

Native Development

If developing or modifying native code or installing any library that introduces or uses native code, it is not possible to use an Expo precompiled development build as you need to compile the native side of the application again. To do so, please follow the steps stated in this section.

Native Environment setup

Before running the app for native development, make sure your development environment has all the required tools. Several of these tools (ie Node and Ruby) may require specific versions in order to successfully build the app.

Setup your development environment

Building the app

Clone the project

git clone git@github.com:MetaMask/metamask-mobile.git && \
cd metamask-mobile
Firebase Messaging Setup

MetaMask uses Firebase Cloud Messaging (FCM) to enable app communications. To integrate FCM, you'll need configuration files for both iOS and Android platforms.

Internal Contributor instructions
  1. Grab the .js.env file from 1Password, ask around for the correct vault. This file contains the GOOGLE_SERVICES_B64_ANDROID and GOOGLE_SERVICES_B64_IOS secrets that will be used to generate the relevant configuration files for IOS/Android.
  2. Install and run & start the application as documented below.
External Contributor instructions

As an external contributor, you need to provide your own Firebase project configuration files:

  • GoogleService-Info.plist (iOS)
  • google-services.json (Android)
  1. Create a Free Firebase Project
    • Set up a Firebase project in the Firebase Console.
    • Configure the project with a client package name matching io.metamask (IMPORTANT).
  2. Add Configuration Files
    • Create/Update the google-services.json and GoogleService-Info.plist files in:
    • android/app/google-services.json (for Android)
    • ios/GoogleServices/GoogleService-Info.plist directory (for iOS)
  3. Create the correct base64 environments variables.
# Generate Android Base64 Version of Google Services
export GOOGLE_SERVICES_B64_ANDROID="$(base64 -w0 -i ./android/app/google-services.json)" && echo "export GOOGLE_SERVICES_B64_ANDROID=\"$GOOGLE_SERVICES_B64_ANDROID\"" | tee -a .js.env

# Generate IOS Base64 Version of Google Services
export GOOGLE_SERVICES_B64_IOS="$(base64 -w0 -i ./ios/GoogleServices/GoogleService-Info.plist)" && echo "export GOOGLE_SERVICES_B64_IOS=\"$GOOGLE_SERVICES_B64_IOS\"" | tee -a .js.env

[!CAUTION]

In case you don't provide your own Firebase project config file or run the steps above, you will face the error No matching client found for package name 'io.metamask'.

In case of any doubt, please follow the instructions in the link below to get your Firebase project config file. Firebase Project Quickstart

Install dependencies
yarn setup

Not the usual install command, this will run scripts and a lengthy postinstall flow

Running the app for native development

Run Metro bundler

yarn watch

Like a local server for the app

Run on a iOS device

yarn start:ios

Run on an Android device

yarn start:android

Development Tools

AI Agent Skills (yarn skills)

AI coding agents (Cursor, Claude Code, Codex) consume shared skills from the MetaMask/skills repo, with an optional private overlay from Consensys/skills. Per ADR #57 this content is not committed hereyarn skills syncs it on demand into local-only paths under .cursor/, .claude/, and .agents/.

Zero-config setup:

yarn install # refreshes the MetaMask/skills cache via the shared @metamask/skills CLI
yarn skills  # syncs all default skills through metamask-skills sync

Optional local configuration:

cp .skills.local.example .skills.local
# edit .skills.local to set SKILLS_DOMAINS or override skills source paths
yarn skills --select                         # interactively pick domains
SKILLS_DOMAINS=perps,testing yarn skills      # one-off domain override

Use .skills.local for persistent skills configuration. Shell environment variables with the same names are supported for one-off or CI overrides and take precedence.

Skipping yarn skills is fine — it only affects agent tooling, not the app build. The repo uses the shared @metamask/skills package so sync/cache behavior stays uniform across MetaMask packages. To opt into best-effort regeneration during install/setup, set SKILLS_AUTO_UPDATE=1 in your shell or .skills.local.

Git Hooks (Husky)

This project uses Husky to run pre-commit hooks that automatically format and lint your code before commits. The pre-commit hook runs lint-staged which executes:

  • Prettier - Code formatting for *.{js,jsx,ts,tsx,json,feature} files
  • ESLint - Linting and auto-fixing for *.{js,jsx,ts,tsx} files

Disabling Husky Locally

If you need to disable Husky pre-commit hooks temporarily (e.g., for emergency commits or debugging), you have several options:

Option 1: Skip hooks for a single commit
git commit --no-verify -m "your commit message"
Option 2: Bypass hooks with environment variable
# Disable for current session
export HUSKY=0
git commit -m "your commit message"

# Or disable for a single command
HUSKY=0 git commit -m "your commit message"

Note: While these methods allow you to bypass the pre-commit hooks, remember that the CI/CD pipeline will still run linting checks. It's recommended to fix linting issues before pushing your changes to avoid build failures.