|
| 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. |
0 commit comments