Skip to content

Commit c5f2005

Browse files
committed
docs: add workflows for EVM network bridge-controller and mobile support
1 parent fad21fb commit c5f2005

5 files changed

Lines changed: 261 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ tools/
145145
| `performance` | MM product eng | React rendering, hooks, state perf |
146146
| `perps` | MM product eng | Perps feature dev + review |
147147
| `pr-workflow` | MM product eng | PR title, description, changelog |
148-
| `swaps` | MM product eng | Non-EVM swap integration |
148+
| `swaps` | MM product eng | EVM and non-EVM network integration |
149149
| `testing` | MM product eng | E2E, unit, visual, perf testing |
150150
| `ui` | MM product eng | Component development |
151151

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
repo: core
3+
parent: add-evm-network-bridge-controller
4+
---
5+
6+
# Add an EVM Network to Bridge Controller
7+
8+
Add the chain as an additive public contract in `packages/bridge-controller`.
9+
Do not change quote, transaction, or controller behavior unless the task
10+
explicitly requires it.
11+
12+
## Gather authoritative inputs
13+
14+
Before editing, confirm these implementation inputs:
15+
16+
- canonical network name and the uppercase TypeScript identifier;
17+
- decimal chain ID, lowercase `0x` chain ID, and `eip155:<decimal>` CAIP ID;
18+
- user-facing display name and desired picker rank;
19+
- native gas token symbol, name, decimals, and representation used by Bridge;
20+
- whether the zero address represents the native asset for this chain;
21+
- whether a nonstandard native symbol needs a `SYMBOL_TO_SLIP44_MAP` entry.
22+
23+
Also identify the downstream Mobile and Extension rollout owners and intended
24+
package release when known. Missing handoff ownership or release timing does
25+
not block the additive Core implementation; record it as a remaining gap.
26+
27+
Derive the hex and CAIP forms from the decimal chain ID and verify the round
28+
trip. Use authoritative network/token data; do not copy token decimals or an
29+
address from another network merely because its integration is structurally
30+
similar. Stop and report missing product or token metadata rather than inventing
31+
it. Picker rank and native-token representation are implementation inputs;
32+
downstream scheduling is not.
33+
34+
## Review reference implementations
35+
36+
Read the current files before editing because names and types evolve. Compare:
37+
38+
- [MetaMask/core#9007 — ARC](https://github.com/MetaMask/core/pull/9007),
39+
including its non-ETH native/default token.
40+
- [MetaMask/core#9459 — Robinhood Chain](https://github.com/MetaMask/core/pull/9459),
41+
including an ETH-native chain.
42+
43+
Use the newest adjacent EVM entry in each target file as the formatting and
44+
ordering reference.
45+
46+
## Implement every registration point
47+
48+
1. In `packages/bridge-controller/src/constants/chains.ts`:
49+
- add the lowercase hex value to `CHAIN_IDS`;
50+
- add a display-name constant;
51+
- add the chain to `NETWORK_TO_NAME_MAP`.
52+
2. In `packages/bridge-controller/src/constants/bridge.ts`:
53+
- add the hex chain ID to `ALLOWED_BRIDGE_CHAIN_IDS`;
54+
- add `{ chainId: 'eip155:<decimal>', name: '<display name>' }` to
55+
`DEFAULT_CHAIN_RANKING` at the intended picker position.
56+
3. In `packages/bridge-controller/src/constants/tokens.ts`:
57+
- register the native currency symbol if the current file maintains a
58+
currency-symbol map;
59+
- define a dedicated swaps token object and add it to
60+
`SWAPS_CHAINID_DEFAULT_TOKEN_MAP`;
61+
- reuse the existing ETH token metadata for an ETH-native chain;
62+
- for a non-ETH native asset, provide the exact symbol, name, address,
63+
decimals, and icon behavior expected by consumers;
64+
- update `SYMBOL_TO_SLIP44_MAP` only when the symbol is new and a valid
65+
asset identifier is known.
66+
4. In `packages/bridge-controller/src/types.ts`, add the decimal member to the
67+
public `ChainId` enum.
68+
5. Add an `Unreleased` entry to
69+
`packages/bridge-controller/CHANGELOG.md` and link the PR when its number is
70+
available.
71+
72+
Preserve the three representations deliberately: `CHAIN_IDS` and allowlists
73+
use hex, `ChainId` uses decimal, and rankings use CAIP IDs. Search for the
74+
identifier, decimal ID, hex ID, and CAIP ID after editing to catch omissions or
75+
collisions.
76+
77+
## Validate the package contract
78+
79+
Use existing focused tests when the package already covers the changed maps.
80+
For each invariant below, either cite an existing or new assertion or record a
81+
static inspection backed by the package build and typecheck:
82+
83+
- the chain is in `ALLOWED_BRIDGE_CHAIN_IDS`;
84+
- its default ranking uses the correct CAIP ID;
85+
- `NETWORK_TO_NAME_MAP` resolves its display name;
86+
- `SWAPS_CHAINID_DEFAULT_TOKEN_MAP` resolves correct token metadata;
87+
- the public enum value equals the decimal chain ID.
88+
89+
Do not create a new low-value suite solely to restate additive constant entries.
90+
Add tests when an established seam exists or behavior, validation, or public
91+
serialization changes.
92+
93+
Run the checks supported by the checkout:
94+
95+
```bash
96+
yarn workspace @metamask/bridge-controller run test
97+
yarn workspace @metamask/bridge-controller run build
98+
yarn workspace @metamask/bridge-controller run changelog:validate
99+
yarn build
100+
yarn lint:misc:check
101+
```
102+
103+
If invoking Jest directly, include `--collectCoverage=false`. Report unavailable
104+
or unrelated failing checks instead of masking them.
105+
106+
## Hand off downstream rollout
107+
108+
State that Core support is only the hard allowlist layer. Mobile and Extension
109+
must consume a released `@metamask/bridge-controller` version and their remote
110+
`bridgeConfigV2.chainRanking` must include the CAIP chain ID before the network
111+
can surface. Report the package release requirement, default token decision,
112+
tests run, and any downstream gaps.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
name: add-evm-network-bridge-controller
3+
description: >-
4+
Add a new EVM network to the @metamask/bridge-controller package in the
5+
MetaMask/core monorepo. Use when a task asks to register an EVM chain for
6+
Swaps or Bridge, extend ALLOWED_BRIDGE_CHAIN_IDS or DEFAULT_CHAIN_RANKING,
7+
add bridge chain constants and display names, define the chain's default
8+
swaps token, or expose a new bridge ChainId enum member.
9+
---
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
repo: metamask-mobile
3+
parent: add-evm-network-mobile
4+
---
5+
6+
# Add an EVM Network to Mobile Swaps and Bridge
7+
8+
Wire only the unified Swaps/Bridge flow. Do not modify legacy swaps or wrapping
9+
logic unless the task explicitly includes them.
10+
11+
## Separate implementation and launch readiness
12+
13+
Confirm these code inputs before implementation:
14+
15+
- Mobile already exposes the chain through its current network constants,
16+
including the canonical `NETWORK_CHAIN_ID` entry and network metadata.
17+
- A released `@metamask/bridge-controller` version contains the chain in
18+
`CHAIN_IDS`, `ChainId`, and `ALLOWED_BRIDGE_CHAIN_IDS`.
19+
- The default destination token address, symbol, name, decimals, and icon URL
20+
are authoritative.
21+
- Stablecoin addresses are known if stable-to-stable swaps should receive the
22+
reduced default slippage.
23+
24+
Stop and report a missing code input rather than inventing metadata or leaving
25+
a partial implementation.
26+
27+
Track these separate launch requirements without blocking an otherwise valid
28+
Mobile code change:
29+
30+
- the Bridge API supports at least one approved source/destination route and
31+
token pair for the chain;
32+
- the `bridgeConfigV2` owner has the decimal/CAIP chain ID, display name,
33+
ranking position, activation direction, rollout percentage, and minimum
34+
Mobile version.
35+
36+
The network picker intersects two gates: the controller hard allowlist and the
37+
remote `bridgeConfigV2.chainRanking`. Missing API or remote configuration blocks
38+
claiming the network is launch-ready, not preparing the client PR. Continue with
39+
the code when its inputs are complete and report every launch gap explicitly.
40+
41+
## Review reference implementations and live shapes
42+
43+
Inspect current types and neighboring network entries before editing; the
44+
default-token map has changed shape over time. Use these PRs as behavioral
45+
references, not as patches to replay:
46+
47+
- [MetaMask/metamask-mobile#31413 — ARC](https://github.com/MetaMask/metamask-mobile/pull/31413),
48+
covering the default destination token, stablecoin slippage, and network
49+
label.
50+
- [MetaMask/metamask-mobile#33110 — Robinhood Chain](https://github.com/MetaMask/metamask-mobile/pull/33110),
51+
covering the bridge-controller upgrade, default token, and label. Treat
52+
dependency-driven cleanup in that PR as incidental rather than required.
53+
54+
## Implement the Mobile layer
55+
56+
1. Verify the installed `@metamask/bridge-controller` exports the chain. If it
57+
does not, update `package.json` to the first compatible released version and
58+
regenerate `yarn.lock` with the repository's package-manager workflow.
59+
Avoid unrelated dependency upgrades where the lockfile permits it.
60+
2. In
61+
`app/components/UI/Bridge/constants/default-swap-dest-tokens.ts`, add the
62+
chain's default destination token. Follow the current value shape exactly
63+
(for example, a token entry may be nested under `'*'`). Include the canonical
64+
address, decimals, image URL, and chain ID. Checksum source addresses where
65+
current entries do so; use the lowercase address in the token-icon URL.
66+
3. In `app/constants/bridge.ts`, add the concise UI label to
67+
`NETWORK_TO_SHORT_NETWORK_NAME_MAP` using the existing Mobile chain
68+
constant.
69+
4. Find the current stablecoin registry used by default-slippage logic. If the
70+
chain supports reduced stablecoin slippage, add every approved stablecoin
71+
address using the registry's existing normalization and update its tests.
72+
Do not treat the default destination token as a stablecoin without product
73+
confirmation.
74+
5. Compile after a controller upgrade. Resolve only type errors or stale
75+
suppressions directly caused by the new dependency version. Keep unrelated
76+
fee, quote, and behavior cleanup out of the network integration.
77+
78+
Search for the chain identifier, decimal ID, hex ID, and CAIP ID after editing.
79+
Confirm there is no second Mobile bridge label, token map, stablecoin registry,
80+
or test fixture that also requires the network.
81+
82+
## Specify the remote rollout
83+
84+
Record the required `bridgeConfigV2` change even when LaunchDarkly is outside
85+
the repository:
86+
87+
- add `chains["<decimalChainId>"]` with the approved source/destination and
88+
unified-button activation fields;
89+
- add `{ "chainId": "eip155:<decimal>", "name": "<display name>" }` to
90+
`chainRanking` at the intended position;
91+
- add approved assets to `topAssets`, `batchSellDestStablecoins`, and the
92+
top-level `stablecoins` list only when the product configuration requires
93+
them;
94+
- define percentage rollout and `minimumVersion` gating.
95+
96+
Do not claim the network is available in the picker until both controller and
97+
remote gates are satisfied.
98+
99+
## Test and manually verify
100+
101+
Use established test seams for behavior that the integration changes. Add or
102+
update focused tests for the default token, label, or stablecoin registry only
103+
when those areas already have meaningful coverage. Verify through tests or
104+
documented static inspection that:
105+
106+
- the default token resolves for the new destination chain;
107+
- the short network label resolves;
108+
- approved stablecoin pairs receive the intended default slippage;
109+
- the existing bridge selector tests still enforce exclusion when either
110+
allowlist layer is absent and inclusion when both layers contain a chain.
111+
112+
Do not add a per-network copy of generic allowlist-intersection tests unless the
113+
selector behavior itself changes. Run the existing bridge slice tests instead.
114+
115+
Run the narrowest relevant Jest suites with `--collectCoverage=false`, then the
116+
repository's applicable typecheck and lint commands. Review lockfile changes
117+
when the controller dependency changes.
118+
119+
Manually exercise both directions supported by the flag:
120+
121+
1. select the new network as a destination and confirm the intended default
122+
token;
123+
2. request a real quote for an approved token pair;
124+
3. select it as a source if source activation is enabled;
125+
4. confirm the display label, token icon, decimals, balance, fee, and slippage;
126+
5. repeat on iOS and Android when preparing the PR for review.
127+
128+
Finish with a prerequisites result, files changed, remote flag changes, tests
129+
run, manual-test evidence, dependency/release status, and remaining gaps.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
name: add-evm-network-mobile
3+
description: >-
4+
Add a new EVM network to the unified Swaps and Bridge flow in
5+
MetaMask/metamask-mobile. Use when a task asks to consume a newly supported
6+
bridge-controller chain, add a Mobile bridge network label, configure its
7+
default destination token or stablecoin slippage, update bridgeConfigV2
8+
rollout requirements, or validate that a new EVM network appears in Mobile's
9+
source and destination network pickers.
10+
---

0 commit comments

Comments
 (0)