Skip to content

Commit f736d82

Browse files
authored
chore(earn): type Earn navigators with feature param lists (Phase 3) (#33291)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> **Phase 3 of the incremental React Navigation typing migration — Earn feature.** Earn’s nested navigators (`EarnScreens` / `EarnModals`) were loosely typed (`EarnScreensParams` / `NestedNavigationParams`), so nested `navigate(container, { screen, params })` calls could not be checked against real screen param shapes. This PR introduces feature-level param lists and wires them into the Earn navigators and `RootStackParamList`, following the same pattern used for Perps / Rewards / Predict / Card. This is **types-only** — no intentional runtime navigation behavior change. ### What changed **Feature param lists (`app/components/UI/Earn/types/navigation.ts`)** - `EarnScreensStackParamList` — screen stack (`EarnScreenStack`): lending deposit/withdrawal confirmation, mUSD conversion education, redesigned confirmations - `EarnModalsNavigationParamList` — modal stack (`EarnModalStack`): lending max withdrawal, lending learn more, redesigned confirmations - `EarnNavigationParamList` — feature union + nested `EarnScreens` / `EarnModals` entries - `RedesignedConfirmations` typed as `ConfirmationParams | undefined` **Navigators (`app/components/UI/Earn/routes/index.tsx`)** - `createNativeStackNavigator<EarnScreensStackParamList>()` for `EarnScreenStack` - `createNativeStackNavigator<EarnModalsNavigationParamList>()` for `EarnModalStack` **Root stack (`app/core/NavigationService/types.ts`)** - `EarnScreens` → `NavigatorScreenParams<EarnScreensStackParamList>` - `EarnModals` → `NavigatorScreenParams<EarnModalsNavigationParamList>` - Leaf Earn routes now reference the feature param lists **Cleanup** - Removed unused loose `EarnScreensParams` from `Earn.types.ts` ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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** <!-- mms-check: type=issue-link required=true --> Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-674 ## **Manual testing steps** N/A ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> N/A ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] 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 - [ ] 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** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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** > Types-only refactor with no runtime navigation changes; risk is limited to possible TypeScript breakage at navigate call sites. > > **Overview** > **Phase 3** of the React Navigation typing migration for Earn: nested `EarnScreens` / `EarnModals` stacks now use dedicated param lists instead of loose `EarnScreensParams` and generic nested params. > > A new `app/components/UI/Earn/types/navigation.ts` defines `EarnScreensStackParamList`, `EarnModalsNavigationParamList`, and `EarnNavigationParamList`, wiring lending confirmation, mUSD education, max withdrawal, learn more, and `RedesignedConfirmations` to their existing param types. `EarnScreenStack` and `EarnModalStack` pass these types into `createNativeStackNavigator`, and `RootStackParamList` uses `NavigatorScreenParams<>` for nested entry routes while leaf Earn routes alias the feature lists. Unused `EarnScreensParams` is removed from `Earn.types.ts`. > > No intentional runtime navigation changes—compile-time safety only, aligned with Perps / Rewards / Predict / Card. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0e20dec. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent ff2a6df commit f736d82

4 files changed

Lines changed: 65 additions & 26 deletions

File tree

app/components/UI/Earn/Earn.types.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,6 @@ export interface GasImpactModalParams {
4848
chainId: string;
4949
}
5050

51-
/** Earn screens parameters */
52-
export interface EarnScreensParams {
53-
screen?: string;
54-
params?: {
55-
token?: Record<string, unknown>;
56-
};
57-
}
58-
5951
/**
6052
* Lending deposit confirmation parameters
6153
* Matches LendingDepositViewRouteParams in EarnLendingDepositConfirmationView

app/components/UI/Earn/routes/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ import {
1212
clearNativeStackNavigatorOptions,
1313
transparentModalScreenOptions,
1414
} from '../../../../constants/navigation/clearStackNavigatorOptions';
15+
import type {
16+
EarnModalsNavigationParamList,
17+
EarnScreensStackParamList,
18+
} from '../types/navigation';
1519

16-
const Stack = createNativeStackNavigator();
17-
const ModalStack = createNativeStackNavigator();
20+
const Stack = createNativeStackNavigator<EarnScreensStackParamList>();
21+
const ModalStack = createNativeStackNavigator<EarnModalsNavigationParamList>();
1822

1923
const EarnScreenStack = () => {
2024
const emptyNavHeaderOptions = useEmptyNavHeaderForConfirmations();
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { NavigatorScreenParams } from '@react-navigation/native';
2+
import type { ConfirmationParams } from '../../../Views/confirmations/components/confirm/confirm-component';
3+
import type { EarnMusdConversionEducationViewRouteParams } from '../Views/EarnMusdConversionEducationView';
4+
import type {
5+
LendingDepositConfirmationParams,
6+
LendingMaxWithdrawalModalParams,
7+
LendingWithdrawalConfirmationParams,
8+
} from '../Earn.types';
9+
10+
/**
11+
* Param list for screens inside the Earn screen stack (`EarnScreenStack`).
12+
*/
13+
// ParamListBase requires `type`; `interface` cannot satisfy it.
14+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
15+
export type EarnScreensStackParamList = {
16+
EarnLendingDepositConfirmation: LendingDepositConfirmationParams | undefined;
17+
EarnLendingWithdrawalConfirmation:
18+
| LendingWithdrawalConfirmationParams
19+
| undefined;
20+
EarnMusdConversionEducation:
21+
| EarnMusdConversionEducationViewRouteParams
22+
| undefined;
23+
RedesignedConfirmations: ConfirmationParams | undefined;
24+
};
25+
26+
/**
27+
* Param list for screens inside the Earn modal stack (`EarnModalStack`).
28+
*/
29+
// ParamListBase requires `type`; `interface` cannot satisfy it.
30+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
31+
export type EarnModalsNavigationParamList = {
32+
EarnLendingMaxWithdrawalModal: LendingMaxWithdrawalModalParams | undefined;
33+
EarnLendingLearnMoreModal: undefined;
34+
RedesignedConfirmations: ConfirmationParams | undefined;
35+
};
36+
37+
/**
38+
* Feature-level Earn navigation params for nested `EarnScreens` / `EarnModals` entry.
39+
*/
40+
// Intersection (`&`) requires `type`; `interface` cannot express this.
41+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
42+
export type EarnNavigationParamList = EarnScreensStackParamList &
43+
EarnModalsNavigationParamList & {
44+
EarnScreens: NavigatorScreenParams<EarnScreensStackParamList> | undefined;
45+
EarnModals:
46+
| NavigatorScreenParams<EarnModalsNavigationParamList>
47+
| undefined;
48+
};

app/core/NavigationService/types.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,12 @@ import type {
216216
LearnMoreModalParams,
217217
MaxInputModalParams,
218218
GasImpactModalParams,
219-
EarnScreensParams,
220-
LendingDepositConfirmationParams,
221-
LendingWithdrawalConfirmationParams,
222-
LendingMaxWithdrawalModalParams,
223219
} from '../../components/UI/Earn/Earn.types';
224220
import type { EarnTokenListViewRouteParams } from '../../components/UI/Earn/components/EarnTokenList';
225-
import type { EarnMusdConversionEducationViewRouteParams } from '../../components/UI/Earn/Views/EarnMusdConversionEducationView';
221+
import type {
222+
EarnModalsNavigationParamList,
223+
EarnScreensStackParamList,
224+
} from '../../components/UI/Earn/types/navigation';
226225

227226
// Modal params
228227
import type {
@@ -857,17 +856,13 @@ export type RootStackParamList = {
857856
EarnTokenList: EarnTokenListViewRouteParams | undefined;
858857

859858
// Earn routes
860-
EarnScreens: EarnScreensParams | undefined;
861-
EarnLendingDepositConfirmation: LendingDepositConfirmationParams | undefined;
862-
EarnLendingWithdrawalConfirmation:
863-
| LendingWithdrawalConfirmationParams
864-
| undefined;
865-
EarnMusdConversionEducation:
866-
| EarnMusdConversionEducationViewRouteParams
867-
| undefined;
868-
EarnModals: NestedNavigationParams | undefined;
869-
EarnLendingMaxWithdrawalModal: LendingMaxWithdrawalModalParams | undefined;
870-
EarnLendingLearnMoreModal: undefined;
859+
EarnScreens: NavigatorScreenParams<EarnScreensStackParamList> | undefined;
860+
EarnLendingDepositConfirmation: EarnScreensStackParamList['EarnLendingDepositConfirmation'];
861+
EarnLendingWithdrawalConfirmation: EarnScreensStackParamList['EarnLendingWithdrawalConfirmation'];
862+
EarnMusdConversionEducation: EarnScreensStackParamList['EarnMusdConversionEducation'];
863+
EarnModals: NavigatorScreenParams<EarnModalsNavigationParamList> | undefined;
864+
EarnLendingMaxWithdrawalModal: EarnModalsNavigationParamList['EarnLendingMaxWithdrawalModal'];
865+
EarnLendingLearnMoreModal: EarnModalsNavigationParamList['EarnLendingLearnMoreModal'];
871866

872867
// Full screen confirmation routes
873868
RedesignedConfirmations: undefined;

0 commit comments

Comments
 (0)