Skip to content

[pull] main from MetaMask:main#329

Merged
pull[bot] merged 6 commits into
Reality2byte:mainfrom
MetaMask:main
Nov 17, 2025
Merged

[pull] main from MetaMask:main#329
pull[bot] merged 6 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Nov 17, 2025

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

ieow and others added 6 commits November 17, 2025 06:15
<!--
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?
-->
False positive logging of error due to appTriggerAuth for Password login
type.
Password login type do not have password stored in keychain, calling
appTriggerAuth will throw error `Error: Password does not exist when
calling SecureKeychain.getGenericPassword`

This PR fix the issue by check for Password login type and navigate to
Login screen instead of calling appTriggerAuth
It fixed part for the root cause of the sentry issue
#20246

Jira link
https://consensyssoftware.atlassian.net/browse/SL-295

## **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: Password type login will not call appTriggerAuth during
app open

## **Related issues**

Fixes:
#20246

## **Manual testing steps**

```gherkin
Feature: Password type login during app open

  Scenario: user create wallet without biometric ( auth type password)
    Given user close app

    When user reopen the app
    Then appTriggerAuth should not be called ( no error logging)
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **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.

## **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]
> On app start, detect password auth type and navigate to Login instead
of triggering biometric auth; adds corresponding tests.
> 
> - **App startup auth flow (`app/components/Nav/App/App.tsx`)**:
> - Import `AUTHENTICATION_TYPE` and query `Authentication.getType()`
before auto-auth.
> - If `currentAuthType === AUTHENTICATION_TYPE.PASSWORD`,
`navigation.reset` to `Routes.ONBOARDING.LOGIN` and skip
`Authentication.appTriggeredAuth`.
>   - Otherwise, proceed with biometric auth trace as before.
> - **Tests (`app/components/Nav/App/App.test.tsx`)**:
>   - Mock `Authentication.getType()` and default to biometric.
> - Add test: when auth type is `PASSWORD`, reset to
`Routes.ONBOARDING.LOGIN` and do not call `appTriggeredAuth`.
>   - Minor test description tweak for opt-in metrics case.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
59fa601. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
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**

Re validate gas fees after users move from swap to bridge while they
have selected max balance on a gasless transaction.

<!--
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?
-->

## **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: Re validate gas fees after users move from swap to
bridge while they have selected max balance on a gasless transaction.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3417

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

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

### **Before**



<!-- [screenshots/recordings] -->

### **After**
<img width="455" height="902" alt="Screenshot 2025-11-11 at 2 02 32 PM"
src="https://github.com/user-attachments/assets/87e0f398-66d0-48e0-ab3c-ab76f232c9ed"
/>

<!-- [screenshots/recordings] -->

## **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.

## **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]
> Updates `useIsInsufficientBalance` to include native-token gas and SOL
rent checks, handle scientific notation, and adds thorough unit tests
across tokens and edge cases.
> 
> - **Bridge hook `useInsufficientBalance`**:
> - Handle native-token gas by summing `sourceAmount + gasFee` using
`quotes.recommendedQuote.gasFee.effective.amount` when `gasIncluded` is
false.
> - Preserve SOL rent exemption check using `selectMinSolBalance` with
lamports comparison.
> - Normalize numeric inputs (incl. scientific notation) via
`BigNumber.js`/`normalizeAmount`; validate decimal precision.
> - Refactor native token detection (`isNativeAddress`) and branch
logic; early-return safeguards for invalid inputs and gasless swaps.
> - **Tests**:
> - Add comprehensive unit tests covering ERC-20 (gasless/cross-chain),
ETH/MATIC native gas scenarios, SOL rent exemption, scientific notation,
and edge cases (undefined inputs, no quote, zero balance).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b1025b2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
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**

the `provider` param was not properly passed to the ChoosePassword page.
This PR fixes this.

## **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/SL-301

## **Manual testing steps**
1. Create a new social login account
2. Choose your password
3. A segment event called 'Wallet Setup Completed' should have a prop
named 'account_type' with 'google' or 'apple' in its value

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **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.

## **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]
> Forwards the `provider` route param across onboarding flows, ensuring
it’s passed to `ChoosePassword`, account status redirects, and iOS
social login success screens.
> 
> - **Onboarding navigation**
> - Pass `provider` in navigations after social login:
`AccountAlreadyExists`, `AccountNotFound`, iOS
`SOCIAL_LOGIN_SUCCESS_NEW_USER`, and Android `ChoosePassword`
(`app/components/Views/Onboarding/index.js`).
> - Add `provider` to `AccountStatus` route params and forward it when
redirecting to `Rehydrate` or `ChoosePassword`
(`app/components/Views/AccountStatus/index.tsx`).
> - Read `provider` from route and include it when navigating to
`CHOOSE_PASSWORD` on iOS social login success
(`app/components/Views/SocialLoginIosUser/index.tsx`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6e88d31. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
… previosuly fetched quote (#22540)

<!--
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**

Currently, the input amount persists after clicking the
source/destination flipper on Mobile. Ideally, the token amounts and
tokens should flip. We introduce this functionality with this PR.

<!--
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?
-->

## **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: clicking src/dest swap flipper should invert token
amounts from previosuly fetched quote

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3265

## **Manual testing steps**

```gherkin
- Ensure clicking flip src/dest button swaps the amounts as well as the tokens.
- While quotes are fetching, if user click the flip amount, it should set the source amount to zero.
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->

### **After**


https://github.com/user-attachments/assets/1f50b741-fd31-4c26-a272-d8605726719f


<!-- [screenshots/recordings] -->

## **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.

## **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]
> Swapping tokens now also inverts amounts from the latest quote, and
bridge quote requests now pass the current insufficient balance flag
with expanded tests.
> 
> - **Bridge UI**:
> - `BridgeView/index.tsx`: Swap button now calls
`handleSwitchTokens(destTokenAmount)` so flipping tokens also swaps
amounts.
> - **Token Switch Logic**:
> - `useSwitchTokens`: Accepts optional `destTokenAmount`; dispatches
`setSourceAmount(destTokenAmount)` when flipping, resets controller
state, and preserves network switching logic.
> - Tests updated/added to cover amount swapping, clearing when absent,
and existing EVM/Non-EVM paths.
> - **Quote Request**:
> - `useBridgeQuoteRequest`: Simplifies state handling; directly
computes and passes `insufficientBal` in
`updateBridgeQuoteRequestParams` and adds it to dependencies; retains
debouncing.
> - Tests expanded to validate `insufficientBal`, balance hook
parameters, and `gasIncluded` behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f373d7f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
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**
This PR fixes styling on the dapp add new network screen.
<!--
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?
-->

## **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: Fixed a bug causing improper styling on the dapp add
new network screen.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-17

## **Manual testing steps**

```gherkin
Feature: Add new network from dapp

  Scenario: user adds new network from dapp
    Given user goes to the dapp (ie. chainlist.org)

    When user clicks Add network button 
    Then the screen has proper styling
```

## **Screenshots/Recordings**

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

### **Before**
<img width="377" height="761" alt="Screenshot 2025-11-13 at 15 10 07"
src="https://github.com/user-attachments/assets/aa32531f-83f6-4abf-82d3-ccbdb2ae44d1"
/>

<!-- [screenshots/recordings] -->

### **After**
<img width="399" height="833" alt="Screenshot 2025-11-14 at 10 11 16"
src="https://github.com/user-attachments/assets/4d61c060-1728-4ad6-8cbe-6f127bf87cd2"
/>

<!-- [screenshots/recordings] -->

## **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.

## **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]
> Inline network details in NetworkVerificationInfo, simplify
styles/layout, and update tests/snapshots accordingly.
> 
> - **UI (NetworkVerificationInfo)**:
> - Remove `Accordion`; always render details inline: `Chain ID`,
`Display name`, and `Block explorer URL`.
> - Simplify layout: add `flex: 1` to `accountCardWrapper`, set
`contentContainerStyle` with `paddingBottom: 24`, and remove
`onLayout`/max-height logic.
> - Keep RPC URL row with optional "Review" tag; show URL with
`hideKeyFromUrl`.
> - **Styles**:
> - Update `NetworkVerificationInfo.styles.ts`: add `flex: 1` to
`accountCardWrapper`; define `nestedScrollContent` with bottom padding.
> - **Tests/Snapshots**:
> - Update snapshots in `NetworkVerificationInfo` and `NetworkModal` to
reflect inline details and style changes.
> - Remove accordion interaction in tests; adjust test name to "renders
chainId as a decimal" and expectations.
> - **Cleanup**:
> - Remove unused state/imports related to accordion and layout
measurement.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e6b74c0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR completes the fix for missing MetaMask referral code display in
the Perps PnL Hero Card. PR #22175 attempted to fix this issue but was
incomplete due to a missing data dependency.

### What is the reason for the change?

Despite PR #22175 adding the `useReferralDetails()` hook to fetch
referral codes, users reported that the referral code still only appears
**after** visiting the Rewards page first. Investigation revealed a
critical dependency chain issue:

- `useReferralDetails()` requires both `subscriptionId` and `seasonId`
to fetch data
- If either is missing, the hook returns early without fetching
- `seasonId` is only populated by `useSeasonStatus()` hook
- `useSeasonStatus()` was never called in the Perps flow, only in
Rewards

**Result**: When users accessed Perps directly, `seasonId` was null �
`useReferralDetails()` returned early � no referral code fetched � UI
remained empty.

Issue: https://consensyssoftware.atlassian.net/browse/TAT-1981

### What is the improvement/solution?

Added the missing `useSeasonStatus()` hook call to
`PerpsHeroCardView.tsx` to ensure `seasonId` is populated before
`useReferralDetails()` attempts to fetch.

**Data flow after fix:**
```
PerpsHeroCardView mounts
        �
useSeasonStatus() fetches season data
        �
seasonId stored in Redux
        �
useReferralDetails() now has seasonId
        �
Fetches referral code successfully
        �
Referral code displays in UI
```

**Key changes:**
- Added `useSeasonStatus({ onlyForExplicitFetch: false })` before
`useReferralDetails()`
- Only 2 lines added (import + hook call)
- Mirrors the approach used in `RewardsNavigator.tsx` (line 23)

## **Changelog**

CHANGELOG entry: Fixed MetaMask referral code not displaying in Perps
PnL card without first visiting Rewards page

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1981

## **Manual testing steps**

```gherkin
Feature: Display referral code on Perps PnL Hero Card without Rewards prerequisite

  Scenario: Fresh app session - user accesses Perps directly without visiting Rewards
    Given user is opted into MetaMask Rewards
    And user has a referral code assigned (e.g., "MMCSI")
    And user has a fresh app session (no persisted Redux state)
    And user has NOT visited the Rewards section

    When user navigates directly to Perps tab
    And user opens an existing position
    And user taps the "Share" button to open PnL Hero Card
    Then the referral code should appear in the top-right corner
    And the referral code should be included in the share message
    And no errors should appear in console logs

  Scenario: Verify prerequisite data is fetched
    Given user is opted into MetaMask Rewards
    And app state is cleared (no cached seasonId)

    When user opens Perps Hero Card
    Then useSeasonStatus() should be called
    And seasonId should be populated in Redux state
    And useReferralDetails() should be called after seasonId is available
    And referral code should be fetched and displayed

  Scenario: Works consistently across multiple sessions
    Given user has referral code
    And user opens app multiple times

    When user goes directly to Perps (never visits Rewards)
    And opens PnL Hero Card in each session
    Then referral code displays correctly every time
    And no manual navigation to Rewards is required
```

## **Screenshots/Recordings**

### **Before**

PR #22175 fixed the issue IF user visited Rewards first, but referral
code remained missing when accessing Perps directly in a fresh session.

**Root cause**: Missing `seasonId` dependency caused
`useReferralDetails()` to return early without fetching.

### **After**

Referral code now displays correctly in all scenarios:
- � Fresh app install � directly to Perps � referral code shows
- � Cleared app data � directly to Perps � referral code shows
- � No requirement to visit Rewards page first
- � Works consistently across sessions


https://github.com/user-attachments/assets/aac690cc-aaa6-4b68-b2ca-26e162f401d0


## **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.

## **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.

---

## Technical Implementation Details

### Root Cause Analysis

**Why PR #22175 was incomplete:**

1. **Added**: `useReferralDetails()` hook to PerpsHeroCardView
2. **Missing**: `useSeasonStatus()` hook (required prerequisite)

**Dependency chain exposed by investigation:**

```typescript
// useReferralDetails.ts - lines 24-28
if (!subscriptionId || !seasonId) {  // �� Early exit if seasonId missing
  dispatch(setReferralDetailsError(false));
  dispatch(setReferralDetailsLoading(false));
  return;  // NO FETCH HAPPENS
}
```

**Where seasonId comes from:**
- Only set by `setSeasonStatus` Redux action
(reducers/rewards/index.ts:147)
- Only dispatched by `useSeasonStatus()` hook (useSeasonStatus.ts:68)
- `useSeasonStatus()` only called in `RewardsNavigator.tsx` (line 23)
- **NEVER called in Perps flow** � seasonId remains null � fetch never
happens

### Files Modified

**Single file changed:**
-
`app/components/UI/Perps/Views/PerpsHeroCardView/PerpsHeroCardView.tsx`

### Code Changes

**Added 2 lines:**

```typescript
// Line 63: Import added
import { useSeasonStatus } from '../../../Rewards/hooks/useSeasonStatus';

// Lines 92-93: Hook call added BEFORE useReferralDetails
// Fetch season status to populate seasonId (required by useReferralDetails)
useSeasonStatus({ onlyForExplicitFetch: false });
```

### Why This Fixes The Issue

1. **Prerequisite satisfied**: `useSeasonStatus()` populates `seasonId`
in Redux
2. **Correct order**: Called before `useReferralDetails()` so dependency
is available
3. **Same pattern**: Mirrors `RewardsNavigator.tsx` implementation (line
23)
4. **No race condition**: Both hooks use `useFocusEffect` which runs
synchronously on mount
5. **Redux caching**: Once fetched, `seasonId` persists for session

### Data Flow Verification

```
PerpsHeroCardView mounts
        �
useSeasonStatus({ onlyForExplicitFetch: false }) called
        �
Fetches: RewardsController:getSeasonStatus
        �
dispatch(setSeasonStatus({ season: { id: "123" } }))
        �
Redux: state.rewards.seasonId = "123" �
        �
useReferralDetails() called
        �
Checks: subscriptionId � && seasonId �
        �
Fetches: RewardsController:getReferralDetails
        �
dispatch(setReferralDetails({ referralCode: "MMCSI" }))
        �
useSelector(selectReferralCode) re-renders
        �
Referral code displays in UI �
```

### Testing Verification

� **ESLint**: No errors
� **TypeScript**: Types validated
� **Code review**: Matches Rewards implementation pattern
� **Dependency analysis**: All prerequisites satisfied

### Performance Impact

- **Minimal overhead**: Single additional API call on Hero Card mount
- **Cached**: Season data persists in Redux for session (no redundant
fetches)
- **Same cost as Rewards**: Uses identical hooks as Rewards section
- **No extra renders**: Hooks run during mount phase

### Comparison with PR #22175

| Aspect | PR #22175 | This PR |
|--------|-----------|---------|
| Hooks added | `useReferralDetails()` | `useSeasonStatus()` +
`useReferralDetails()` |
| Lines changed | 2 | 4 |
| Dependencies satisfied | L Missing seasonId | � All dependencies |
| Works after Rewards visit | � Yes | � Yes |
| Works on direct Perps access | L No | � Yes |
| Works on fresh install | L No | � Yes |

### Related Code References

- `useSeasonStatus` hook:
`app/components/UI/Rewards/hooks/useSeasonStatus.ts`
- `useReferralDetails` hook:
`app/components/UI/Rewards/hooks/useReferralDetails.ts`
- Rewards implementation:
`app/components/UI/Rewards/RewardsNavigator.tsx:23`
- Redux seasonId: `app/reducers/rewards/index.ts:147`
- Redux referralCode:
`app/reducers/rewards/selectors.ts:selectReferralCode`

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Integrates `useSeasonStatus` into `PerpsHeroCardView` to ensure
referral code data loads without visiting Rewards, and updates tests to
mock the hook.
> 
> - **Perps**:
> -
`app/components/UI/Perps/Views/PerpsHeroCardView/PerpsHeroCardView.tsx`
> - Import and call `useSeasonStatus({ onlyForExplicitFetch: false })`
before `useReferralDetails()` to populate `seasonId` and load referral
code for the PnL Hero Card and share message.
> - **Tests**:
> -
`app/components/UI/Perps/Views/PerpsHeroCardView/PerpsHeroCardView.test.tsx`
>     - Add Jest mock for `../../../Rewards/hooks/useSeasonStatus`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
14baca8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Nov 17, 2025
@pull pull Bot added the ⤵️ pull label Nov 17, 2025
@pull pull Bot merged commit b23a0c7 into Reality2byte:main Nov 17, 2025
0 of 8 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants