Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ tools/
| `performance` | MM product eng | React rendering, hooks, state perf |
| `perps` | MM product eng | Perps feature dev + review |
| `pr-workflow` | MM product eng | PR title, description, changelog |
| `swaps` | MM product eng | Non-EVM swap integration |
| `swaps` | MM product eng | EVM and non-EVM network integration |
| `testing` | MM product eng | E2E, unit, visual, perf testing |
| `ui` | MM product eng | Component development |

Expand Down
112 changes: 112 additions & 0 deletions domains/swaps/skills/add-evm-network-bridge-controller/repos/core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
repo: core
parent: add-evm-network-bridge-controller
---

# Add an EVM Network to Bridge Controller

Add the chain as an additive public contract in `packages/bridge-controller`.
Do not change quote, transaction, or controller behavior unless the task
explicitly requires it.

## Gather authoritative inputs

Before editing, confirm these implementation inputs:

- canonical network name and the uppercase TypeScript identifier;
- decimal chain ID, lowercase `0x` chain ID, and `eip155:<decimal>` CAIP ID;
- user-facing display name and desired picker rank;
- native gas token symbol, name, decimals, and representation used by Bridge;
- whether the zero address represents the native asset for this chain;
- whether a nonstandard native symbol needs a `SYMBOL_TO_SLIP44_MAP` entry.

Also identify the downstream Mobile and Extension rollout owners and intended
package release when known. Missing handoff ownership or release timing does
not block the additive Core implementation; record it as a remaining gap.

Derive the hex and CAIP forms from the decimal chain ID and verify the round
trip. Use authoritative network/token data; do not copy token decimals or an
address from another network merely because its integration is structurally
similar. Stop and report missing product or token metadata rather than inventing
it. Picker rank and native-token representation are implementation inputs;
downstream scheduling is not.

## Review reference implementations

Read the current files before editing because names and types evolve. Compare:

- [MetaMask/core#9007 — ARC](https://github.com/MetaMask/core/pull/9007),
including its non-ETH native/default token.
- [MetaMask/core#9459 — Robinhood Chain](https://github.com/MetaMask/core/pull/9459),
including an ETH-native chain.

Use the newest adjacent EVM entry in each target file as the formatting and
ordering reference.

## Implement every registration point

1. In `packages/bridge-controller/src/constants/chains.ts`:
- add the lowercase hex value to `CHAIN_IDS`;
- add a display-name constant;
- add the chain to `NETWORK_TO_NAME_MAP`.
2. In `packages/bridge-controller/src/constants/bridge.ts`:
- add the hex chain ID to `ALLOWED_BRIDGE_CHAIN_IDS`;
- add `{ chainId: 'eip155:<decimal>', name: '<display name>' }` to
`DEFAULT_CHAIN_RANKING` at the intended picker position.
3. In `packages/bridge-controller/src/constants/tokens.ts`:
- register the native currency symbol if the current file maintains a
currency-symbol map;
- define a dedicated swaps token object and add it to
`SWAPS_CHAINID_DEFAULT_TOKEN_MAP`;
- reuse the existing ETH token metadata for an ETH-native chain;
- for a non-ETH native asset, provide the exact symbol, name, address,
decimals, and icon behavior expected by consumers;
- update `SYMBOL_TO_SLIP44_MAP` only when the symbol is new and a valid
asset identifier is known.
4. In `packages/bridge-controller/src/types.ts`, add the decimal member to the
public `ChainId` enum.
5. Add an `Unreleased` entry to
`packages/bridge-controller/CHANGELOG.md` and link the PR when its number is
available.

Preserve the three representations deliberately: `CHAIN_IDS` and allowlists
use hex, `ChainId` uses decimal, and rankings use CAIP IDs. Search for the
identifier, decimal ID, hex ID, and CAIP ID after editing to catch omissions or
collisions.

## Validate the package contract

Use existing focused tests when the package already covers the changed maps.
For each invariant below, either cite an existing or new assertion or record a
static inspection backed by the package build and typecheck:

- the chain is in `ALLOWED_BRIDGE_CHAIN_IDS`;
- its default ranking uses the correct CAIP ID;
- `NETWORK_TO_NAME_MAP` resolves its display name;
- `SWAPS_CHAINID_DEFAULT_TOKEN_MAP` resolves correct token metadata;
- the public enum value equals the decimal chain ID.

Do not create a new low-value suite solely to restate additive constant entries.
Add tests when an established seam exists or behavior, validation, or public
serialization changes.

Run the checks supported by the checkout:

```bash
yarn workspace @metamask/bridge-controller run test
yarn workspace @metamask/bridge-controller run build
yarn workspace @metamask/bridge-controller run changelog:validate
yarn build
yarn lint:misc:check
```

If invoking Jest directly, include `--collectCoverage=false`. Report unavailable
or unrelated failing checks instead of masking them.

## Hand off downstream rollout

State that Core support is only the hard allowlist layer. Mobile and Extension
must consume a released `@metamask/bridge-controller` version and their remote
`bridgeConfigV2.chainRanking` must include the CAIP chain ID before the network
can surface. Report the package release requirement, default token decision,
tests run, and any downstream gaps.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: add-evm-network-bridge-controller
description: >-
Add a new EVM network to the @metamask/bridge-controller package in the
MetaMask/core monorepo. Use when a task asks to register an EVM chain for
Swaps or Bridge, extend ALLOWED_BRIDGE_CHAIN_IDS or DEFAULT_CHAIN_RANKING,
add bridge chain constants and display names, define the chain's default
swaps token, or expose a new bridge ChainId enum member.
---
129 changes: 129 additions & 0 deletions domains/swaps/skills/add-evm-network-mobile/repos/metamask-mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
repo: metamask-mobile
parent: add-evm-network-mobile
---

# Add an EVM Network to Mobile Swaps and Bridge

Wire only the unified Swaps/Bridge flow. Do not modify legacy swaps or wrapping
logic unless the task explicitly includes them.

## Separate implementation and launch readiness

Confirm these code inputs before implementation:

- Mobile already exposes the chain through its current network constants,
including the canonical `NETWORK_CHAIN_ID` entry and network metadata.
- A released `@metamask/bridge-controller` version contains the chain in
`CHAIN_IDS`, `ChainId`, and `ALLOWED_BRIDGE_CHAIN_IDS`.
- The default destination token address, symbol, name, decimals, and icon URL
are authoritative.
- Stablecoin addresses are known if stable-to-stable swaps should receive the
reduced default slippage.

Stop and report a missing code input rather than inventing metadata or leaving
a partial implementation.

Track these separate launch requirements without blocking an otherwise valid
Mobile code change:

- the Bridge API supports at least one approved source/destination route and
token pair for the chain;
- the `bridgeConfigV2` owner has the decimal/CAIP chain ID, display name,
ranking position, activation direction, rollout percentage, and minimum
Mobile version.

The network picker intersects two gates: the controller hard allowlist and the
remote `bridgeConfigV2.chainRanking`. Missing API or remote configuration blocks
claiming the network is launch-ready, not preparing the client PR. Continue with
the code when its inputs are complete and report every launch gap explicitly.

## Review reference implementations and live shapes

Inspect current types and neighboring network entries before editing; the
default-token map has changed shape over time. Use these PRs as behavioral
references, not as patches to replay:

- [MetaMask/metamask-mobile#31413 — ARC](https://github.com/MetaMask/metamask-mobile/pull/31413),
covering the default destination token, stablecoin slippage, and network
label.
- [MetaMask/metamask-mobile#33110 — Robinhood Chain](https://github.com/MetaMask/metamask-mobile/pull/33110),
covering the bridge-controller upgrade, default token, and label. Treat
dependency-driven cleanup in that PR as incidental rather than required.

## Implement the Mobile layer

1. Verify the installed `@metamask/bridge-controller` exports the chain. If it
does not, update `package.json` to the first compatible released version and
regenerate `yarn.lock` with the repository's package-manager workflow.
Avoid unrelated dependency upgrades where the lockfile permits it.
2. In
`app/components/UI/Bridge/constants/default-swap-dest-tokens.ts`, add the
chain's default destination token. Follow the current value shape exactly
(for example, a token entry may be nested under `'*'`). Include the canonical
address, decimals, image URL, and chain ID. Checksum source addresses where
current entries do so; use the lowercase address in the token-icon URL.
3. In `app/constants/bridge.ts`, add the concise UI label to
`NETWORK_TO_SHORT_NETWORK_NAME_MAP` using the existing Mobile chain
constant.
4. Find the current stablecoin registry used by default-slippage logic. If the
chain supports reduced stablecoin slippage, add every approved stablecoin
address using the registry's existing normalization and update its tests.
Do not treat the default destination token as a stablecoin without product
confirmation.
5. Compile after a controller upgrade. Resolve only type errors or stale
suppressions directly caused by the new dependency version. Keep unrelated
fee, quote, and behavior cleanup out of the network integration.

Search for the chain identifier, decimal ID, hex ID, and CAIP ID after editing.
Confirm there is no second Mobile bridge label, token map, stablecoin registry,
or test fixture that also requires the network.

## Specify the remote rollout

Record the required `bridgeConfigV2` change even when LaunchDarkly is outside
the repository:

- add `chains["<decimalChainId>"]` with the approved source/destination and
unified-button activation fields;
- add `{ "chainId": "eip155:<decimal>", "name": "<display name>" }` to
`chainRanking` at the intended position;
- add approved assets to `topAssets`, `batchSellDestStablecoins`, and the
top-level `stablecoins` list only when the product configuration requires
them;
- define percentage rollout and `minimumVersion` gating.

Do not claim the network is available in the picker until both controller and
remote gates are satisfied.

## Test and manually verify

Use established test seams for behavior that the integration changes. Add or
update focused tests for the default token, label, or stablecoin registry only
when those areas already have meaningful coverage. Verify through tests or
documented static inspection that:

- the default token resolves for the new destination chain;
- the short network label resolves;
- approved stablecoin pairs receive the intended default slippage;
- the existing bridge selector tests still enforce exclusion when either
allowlist layer is absent and inclusion when both layers contain a chain.

Do not add a per-network copy of generic allowlist-intersection tests unless the
selector behavior itself changes. Run the existing bridge slice tests instead.

Run the narrowest relevant Jest suites with `--collectCoverage=false`, then the
repository's applicable typecheck and lint commands. Review lockfile changes
when the controller dependency changes.

Manually exercise both directions supported by the flag:

1. select the new network as a destination and confirm the intended default
token;
2. request a real quote for an approved token pair;
3. select it as a source if source activation is enabled;
4. confirm the display label, token icon, decimals, balance, fee, and slippage;
5. repeat on iOS and Android when preparing the PR for review.

Finish with a prerequisites result, files changed, remote flag changes, tests
run, manual-test evidence, dependency/release status, and remaining gaps.
10 changes: 10 additions & 0 deletions domains/swaps/skills/add-evm-network-mobile/skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: add-evm-network-mobile
description: >-
Add a new EVM network to the unified Swaps and Bridge flow in
MetaMask/metamask-mobile. Use when a task asks to consume a newly supported
bridge-controller chain, add a Mobile bridge network label, configure its
default destination token or stablecoin slippage, update bridgeConfigV2
rollout requirements, or validate that a new EVM network appears in Mobile's
source and destination network pickers.
---