Skip to content

[pull] main from MetaMask:main#630

Merged
pull[bot] merged 15 commits into
Reality2byte:mainfrom
MetaMask:main
Mar 26, 2026
Merged

[pull] main from MetaMask:main#630
pull[bot] merged 15 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Mar 26, 2026

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 : )

metamaskbot and others added 15 commits March 25, 2026 17:44
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Closes / refs: https://consensyssoftware.atlassian.net/browse/RWDS-1104

CHANGELOG entry: Added Ondo leaderboard view displaying user's rank,
tier, and financial position within the campaign

## Screenshots

- Leaderboard position component in loadedn, loading & error state. This
component will be shown on the ondo details page if a user has opted in.

<img width="1073" height="532" alt="Screenshot from 2026-03-25 17-10-59"
src="https://github.com/user-attachments/assets/b98751ac-0b90-42fa-a0dd-a3e5a4fea172"
/>

<img width="1073" height="532" alt="Screenshot from 2026-03-25 17-09-56"
src="https://github.com/user-attachments/assets/8ed5db14-2c89-4bec-8c16-0506fe369fde"
/>

<img width="1241" height="1355" alt="Screenshot from 2026-03-25
17-03-53"
src="https://github.com/user-attachments/assets/e69eaa55-47e7-4840-9ba8-e226df5bdb43"
/>

- Leaderboard page containing position at the top and the leaderboard
below. Accessible via the ondo details page if opted in (via tap on
section) or rendered inline on that page if campaign has passed.
(regardless of opt in)

<img width="987" height="1812" alt="Screenshot from 2026-03-25 17-01-49"
src="https://github.com/user-attachments/assets/24a386ea-caf3-423a-845f-12ac0adb9175"
/>


🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new rewards API calls, controller caching/state, and UI
navigation for Ondo leaderboard/position; moderate risk of regressions
in rewards state persistence/invalidation and leaderboard fetch/display
behavior.
> 
> **Overview**
> Adds an **Ondo campaign leaderboard experience**: a new
`RewardsOndoCampaignLeaderboard` screen plus reusable `OndoLeaderboard`
and `OndoLeaderboardPosition` components, wired into `RewardsNavigator`
and linked from `OndoCampaignDetailsView`.
> 
> Updates the campaign details UI to show *entered* status,
conditionally render leaderboard content (inline leaderboard for
completed campaigns when not opted in; position card + tappable header
when opted in), and only fetch leaderboard data when it will be
displayed.
> 
> Extends the rewards stack end-to-end with new public/authenticated
endpoints and caching: `RewardsDataService` + `RewardsController`
actions for `getOndoCampaignLeaderboard` and
`getOndoCampaignLeaderboardPosition`, new persisted controller state
(`ondoCampaignLeaderboard`, `ondoCampaignLeaderboardPositions` with a
not-found sentinel), and cache invalidation on
opt-in/logout/subscription cache resets.
> 
> Adds Redux state/actions for leaderboard UI (loading/error/selected
tier and per-subscription positions), updates rehydration/reset
behavior, and includes comprehensive unit tests for the new views,
hooks, utilities, controller, and data service.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
92ef86c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
<!--
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?
-->

Replaced `Button` with DSRN component equivalent.

## **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/DSYS-445

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


https://github.com/user-attachments/assets/62fd7302-f338-4936-8a78-54cbc9ecde5b

### **After**


https://github.com/user-attachments/assets/8bcbcb1b-f407-4970-bf2a-7e94b1357ce6

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

- [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]
> **Medium Risk**
> Replaces multiple Bridge UI actions (confirm swap, quick-picks, token
select, block explorer links) with the new design-system `Button`, which
can subtly change press/disabled/loading behavior and accessibility.
Risk is moderate because it touches core swap/bridge user interactions
but is largely a UI component swap with updated tests.
> 
> **Overview**
> Migrates Bridge-scoped buttons from the legacy component-library
`Button` to `@metamask/design-system-react-native` `Button`, updating
props/APIs (e.g., `variant`, `isDisabled`, `isLoading`, `isFullWidth`)
and switching from `label` prop to children rendering.
> 
> Updates Bridge tests to match the new button behavior: disabled state
assertions now use `accessibilityState.disabled`, loading assertions
look for a `spinner-container` overlay, and one navigation test invokes
the `Button` component’s `onPress` directly due to Pressable host
limitations when disabled.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1edf81a. 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**

Fixes Card spending-limit delegation when the token’s chain (e.g. Monad)
is **not yet added** to the user’s network list. Previously,
`useCardDelegation` resolved the approval transaction’s
`networkClientId` via
**`NetworkController.findNetworkClientIdByChainId`**, which only works
for networks the wallet already knows about—so flows could fail for
Card-supported chains that were missing from the client.

**What changed**:

- **`useEnsureCardNetworkExists` (new)**: Hook that, given a CAIP chain
ID, returns the correct `networkClientId`. If the EVM network is already
in **`selectEvmNetworkConfigurationsByChainId`**, it returns the
existing client id. If not, it looks up the chain in **`PopularList`**,
calls **`NetworkController.addNetwork`** with that RPC/metadata,
**`enableNetwork`** so the network filter includes it, then returns the
new `networkClientId`. Throws a clear error if the chain is not in
`PopularList` or if `addNetwork` does not yield a client id.
- **`useCardDelegation`**: Replaces `findNetworkClientIdByChainId` +
`safeFormatChainIdToHex` with **`await
ensureNetworkExists(token.caipChainId)`** before
**`TransactionController.addTransaction`** for the approval.
- **Tests**: **`useEnsureCardNetworkExists.test.ts`** covers existing vs
missing network, Monad-style `PopularList` add + enable, errors for
unknown chains and failed adds; **`useCardDelegation.test.ts`** mocks
the new hook and asserts **`ensureNetworkExists`** is called with the
token’s CAIP chain id.

## **Changelog**

CHANGELOG entry: Card delegation now auto-adds Card-supported EVM
networks from the popular list when missing, so approval transactions
get a valid `networkClientId` (e.g. Monad).

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Card delegation when network is not in the wallet

  Scenario: Delegation on a chain already in the network list
    Given I have the Card token’s chain already added (e.g. Polygon)
    When I complete the spending limit / delegation approval flow
    Then the approval transaction submits without adding a duplicate network

  Scenario: Delegation on a Card-supported chain not yet added (e.g. Monad)
    Given the token’s CAIP chain is in PopularList but not in my networks
    When I run the Card delegation approval flow
    Then the app adds the network from the popular list, enables it, and submits the approval on that network

  Scenario: Unsupported chain not in PopularList
    Given a chain ID that is not in PopularList (if testable)
    When delegation runs
    Then the user sees a failure path consistent with the thrown error (network not found in PopularList)
```

## **Screenshots/Recordings**


https://github.com/user-attachments/assets/0cd1b22f-5296-41f3-b961-316f05c3ae79

## **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]
> **Medium Risk**
> Medium risk because it changes transaction routing by potentially
auto-adding and enabling EVM networks at runtime, which could impact
network configuration/state if the PopularList entry or enablement flow
is wrong.
> 
> **Overview**
> Fixes Card spending-limit delegation failing when the token’s chain
isn’t already in the user’s configured networks by resolving a valid
`networkClientId` even for missing chains.
> 
> Adds `useEnsureCardNetworkExists`, which checks existing EVM network
configs and otherwise adds the chain from `PopularList` via
`NetworkController.addNetwork` and enables it before returning the new
`networkClientId`. `useCardDelegation` now calls this hook (replacing
`findNetworkClientIdByChainId`) and tests are updated/added to cover the
new behavior and error cases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9386501. 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**

Previously, long outcome names in the footer CTA buttons on the sports
prediction market details screen could wrap awkwardly and break the
button layout. This PR updates those CTA buttons to switch to a stacked
title-and-price layout for longer labels and allows the buttons to grow
vertically when needed, so the content stays readable, centered, and
visually consistent. It also adds regression coverage for long outcome
names.

## **Changelog**

CHANGELOG entry: Fixed a bug where long sports prediction outcome names
could break the action button layout on market details.

## **Related issues**

Fixes: N/A

## **Manual testing steps**

```gherkin
Feature: sports prediction market CTA layout

  Scenario: user views a market with long outcome names
    Given user is on an open sports prediction market details screen with long team names
    And the About tab is selected

    When the footer action buttons are shown
    Then each outcome name wraps cleanly within its button
    And each button grows tall enough to fit the wrapped text
    And the price remains visible and centered
```

## **Screenshots/Recordings**

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

### **Before**

<img width="391" height="777" alt="Screenshot 2026-03-23 at 4 41 02 PM"
src="https://github.com/user-attachments/assets/f797efb4-fa64-4b7a-b429-9b463d754470"
/>

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

### **After**

<img width="379" height="758" alt="Screenshot 2026-03-23 at 4 40 53 PM"
src="https://github.com/user-attachments/assets/526a7a5d-64af-4c09-a9c4-839e0fbd9594"
/>

<!-- [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]
> **Low Risk**
> Low risk UI-only change to footer action button rendering plus test
updates; main risk is minor layout regressions or missing token/title
edge cases in the new label logic.
> 
> **Overview**
> Fixes footer CTA button layout for sports Predict markets by switching
to a *stacked title + price* label when outcome names exceed a length
threshold, and allowing the buttons to grow vertically (min
height/padding) so long text wraps cleanly.
> 
> Updates `PredictMarketDetails` tests to match the new button label
format, makes button selection resilient by parsing the trailing `¢`
price instead of exact label strings, and adds a regression test
asserting long outcome names render with visible title and price.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cf74e3b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
… option (#27926)

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

We weren't requiring a reason for the Something else option, now we are
verifying it and disabling the button if the user doesn't have one
written.

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

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

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

## **Pre-merge author checklist**

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Low Risk**
> Low risk UI validation change that only affects when the feedback
submit button is enabled and what payload gets sent; no new data flows
or backend changes.
> 
> **Overview**
> Tightens Market Insights feedback submission validation so users must
select a reason, and when choosing `SomethingElse` must also enter
non-whitespace text before submitting.
> 
> Introduces a shared `canSubmit` gate to both disable the submit button
and prevent `onSubmit` from firing, and only includes `feedbackText`
when the trimmed input is non-empty.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0b05cbd. 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**

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

Migrated `Button` to DSRN package usage.

## **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/DSYS-445

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


https://github.com/user-attachments/assets/8451661e-92d8-4648-a9b9-5cc8429a4fe9

### **After**

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


https://github.com/user-attachments/assets/83551d29-95dc-432d-95e7-0b2714d95e87

## **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]
> **Low Risk**
> UI-only refactor that swaps button components/props in SDK session
management flows; risk is limited to potential styling/interaction
regressions from the new `Button` API (variants/sizing/labels).
> 
> **Overview**
> Migrates SDK session-management screens (`SDKDisconnectModal`,
`SDKSessionModal`, `SDKSessionsManager`, and session list items) from
the legacy component-library `Button` to
`@metamask/design-system-react-native`.
> 
> Updates button usage to the new API (text as children instead of
`label`, `ButtonVariants`/`ButtonSize` ->
`ButtonVariant`/`ButtonBaseSize`, and link-style buttons mapped to
`Tertiary`), without changing the underlying disconnect/navigation
logic.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
281febd. 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**

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

Replace deprecated `Button` usage with DSRN package.

## **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/DSYS-445

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


https://github.com/user-attachments/assets/d022ebd3-23b0-4f82-9684-c3d99810eca3

### **After**


https://github.com/user-attachments/assets/3fcd6842-1a84-4f3f-b9fb-21fbcf2608a9

## **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]
> **Medium Risk**
> Moderate risk because it swaps the underlying `Button` implementation
across multiple confirmation keyboards/modals, which could subtly change
disabled/press behavior and layout in transaction-critical screens.
> 
> **Overview**
> Migrates confirmation-flow buttons from the deprecated
component-library `Button` to `@metamask/design-system-react-native`,
updating APIs (e.g., `label` to children, `disabled` to `isDisabled`,
`width` to `isFullWidth`, and new `ButtonVariant` enums) across
keyboards, developer options, transaction retry, and
gas/alert/spending-cap modals.
> 
> Updates associated tests and snapshots to match the new rendered
structure/props, including switching assertions to `toBeDisabled()` /
`toBeEnabled()`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
845cb73. 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**
Add warning prompt for ios <17.4 for google login 

Supports the fix for:
MetaMask/MetaMask-planning#7148
Part 1/ 4 - #27741
Part 2/ 4 - #27848
Part 3/ 4 - #27850 (deferred to 7.72.0)
Part 4/ 4 - #27875


<!--
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: Add warning prompt for ios <17.4 for google login

## **Related issues**

Fixes:

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

<!-- [screenshots/recordings] -->
For  < iOS 17.4



https://github.com/user-attachments/assets/f6f3a031-82cc-486d-af5f-e6e1bbc7ed10


For >= iOS 17.4


https://github.com/user-attachments/assets/2cdc0bf3-d59b-4858-be81-baae5e0a4dd2



## **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
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Medium Risk**
> Modifies the onboarding social login path by inserting a conditional
pre-login warning and new navigation helper, which could affect Google
login flow timing/navigation on iOS devices. Changes are localized but
touch user authentication entrypoints and analytics tracking.
> 
> **Overview**
> Adds an **iOS < 17.4 warning gate** before starting Google OAuth
during onboarding (both create and import flows), showing a
non-interactable `SuccessErrorSheet` that must be acknowledged before
proceeding.
> 
> Introduces `Device.comparePlatformVersionTo()` (using
`compare-versions`) and a reusable
`navigateToSuccessErrorSheetPromise()` helper to await sheet dismissal,
plus a new MetaMetrics event (`WALLET_GOOGLE_IOS_WARNING_VIEWED`) and
localized warning copy.
> 
> Updates onboarding tests to mock the new device helper/navigation and
to assert the warning sheet + tracking fire before continuing with
Google login.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3b43b83. 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**

<img width="394" height="160" alt="Screenshot 2026-03-25 at 16 08 01"
src="https://github.com/user-attachments/assets/9ad9a343-dd96-429f-8909-2fda7e5e8197"
/>


https://github.com/user-attachments/assets/1c9dead2-ab01-47e9-ad20-498f3a74e008


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

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

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

## **Pre-merge author checklist**

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Medium Risk**
> Adds new Reanimated/SVG border animation and a polling-based
`useViewportTracking` hook, which may impact UI performance or behave
differently across layouts if measurement/visibility is off.
> 
> **Overview**
> Updates the Market Insights entry card visuals by switching to a new
rounded, muted-background card layout and replacing the prior
header/arrow treatment with an inline AI icon plus footer text.
> 
> Introduces an `AnimatedGradientBorder` (SVG + Reanimated) that sweeps
a gradient stroke around the card when it becomes fully visible, driven
by new `useViewportTracking` viewport detection.
> 
> Adds targeted tests for the new trace behavior, layout/dimension
updates, and the viewport-tracking hook; also excludes the legacy
`MarketInsightsEntryCardOriginal.tsx` and the animation component from
coverage/sonar, and moves the entry card placement earlier in
`AssetOverviewContent`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f96c206. 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**

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

Replace deprecated `Button` usage with DSRN package.

## **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/DSYS-445

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


https://github.com/user-attachments/assets/8597813f-5f65-4225-9660-c8b939a8675d

### **After**


https://github.com/user-attachments/assets/37d71232-f8d1-497a-8a5c-3effed6338c7

## **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]
> **Medium Risk**
> Touches many card/onboarding screens to swap a core UI component;
while mostly prop/markup changes, subtle differences in
disabled/loading/accessibility behavior could affect user flows and
tests.
> 
> **Overview**
> Migrates card-related screens/components from the deprecated
component-library `Button` to the design-system
`@metamask/design-system-react-native` `Button` (e.g., auth, home,
cashback, checkout/onboarding, spending limit, message box, and dev
options).
> 
> Updates callsites to the new API (`variant` enums, `isLoading`,
`isDisabled`, `isFullWidth`, and children-based labels) and adjusts
tests/snapshots accordingly (including assertions using
`toBeDisabled`/`toBeEnabled` and checking `accessibilityState.busy`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
66e6d97. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Fixes an issue where after a WCv2 connection could still send
chainChanged events to the WC relay when the connection was removed.
This was happening regardless of if the connection was removed on the
wallet side or signaled removed from the WC side.

This PR fixes that by properly unsubscribing from the store.

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

Not user facing.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/WAPI-1355

## **Manual testing steps**

1. Open app in iOS expo build
2. Open js debugger
3. add breakpoint to onStoreChange in WalletConnect2Session.ts
4. Connect a new WC session via [demo
app](https://react-app.walletconnect.com/)
5. You should see onStoreChange fire
6. Visit settings, experimental, and disconnect this session (long tap)
7. You should not see onStoreChange fire anymore
8. reconnect to demo dapp
9. You should see onStoreChange fire
10. disconnect from the demo dapp
11. you should not see onStoreChange fire anymore



Visit https://react-app.walletconnect.com/ in the native browser and
smoke test

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

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Medium Risk**
> Touches WalletConnect v2 session lifecycle/cleanup, so mistakes could
leave sessions partially disconnected or change disconnect timing. Logic
is straightforward and covered by updated unit tests, limiting risk.
> 
> **Overview**
> Fixes a WalletConnect v2 listener leak by storing the Redux
`store.subscribe` unsubscribe in `WalletConnect2Session` and invoking it
during `removeListeners()`.
> 
> Updates `WC2Manager.removeAll()` to **tear down every
`WalletConnect2Session` via `removeListeners()` before clearing the
sessions map**, preventing orphaned subscriptions/bridges when
`session_delete` fires after local state is cleared. Tests were extended
to assert the unsubscribe is called and `removeAll()` invokes
`removeListeners()` for each session.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7633be5. 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**

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

This PR provides some minor fixes and improvements to the mUSD
calculator:

- Guard against / set default value for a variable
- Use swap navigation instead of deeplink for reduced friction
- Move the disclaimer to the bottom of the page content

## **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: n/a

## **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="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2026-03-25 at 16 09 28"
src="https://github.com/user-attachments/assets/918eeaf3-0f22-41fb-aabc-a96013925e08"
/>

## **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
- [ ] 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]
> **Medium Risk**
> Medium risk because it changes the mUSD swap action from a deeplink to
in-app swap navigation and adjusts rewards state rehydration/selectors
to tolerate missing campaign status data, which could affect routing and
campaign UI behavior if misconfigured.
> 
> **Overview**
> Updates the mUSD calculator header to use a new localized
`rewards.musd.page_title` string and tweaks layout by moving the
disclaimer to the bottom with updated styling.
> 
> Replaces the Swap button’s deeplink (`link.metamask.io/swap`) with
in-app swap navigation via `useSwapBridgeNavigation`, preconfiguring
ETH→mUSD tokens, and updates tests accordingly.
> 
> Hardens Rewards redux state handling by defaulting
`campaignParticipantStatuses` to `{}` on rehydrate and making related
selectors null-safe, preventing crashes when the field is missing from
persisted payloads.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fc1814e. 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**

Changes WCv2 session/connection restores to be sequential. Previously
they were concurrent. The concurrency was problematic because it would
cause a large spike in relay traffic for users with numerous WCv2
connections.

## **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/WAPI-1357

## **Manual testing steps**

1. Change `SESSION_RESTORE_STAGGER_MS` to be something larger like 10000
2. Make an ios expo build
3. Using safari native browser, connect to
https://react-app.walletconnect.com/ AND https://wagmi-app.vercel.app/
using WalletConnect
4. Swipe away MetaMask
5. On the dapp you connected to last, trigger a personal sign
6. Ignore the deeplink
7. Reopen MetaMask manually from the homescreen
8. Login
9. It should take at least your `SESSION_RESTORE_STAGGER_MS` delay
before you see the approval appear


Why this way instead of using the js debugger? Unfortunately restarting
the app causes the debugger to disconnect, and so it isn't a reliable
way to probe startup based flows.

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

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Medium Risk**
> Changes WCv2 startup session restoration from concurrent async updates
to a serialized loop with an added delay, which can impact connection
readiness timing and expose ordering/regression issues in
session/account syncing.
> 
> **Overview**
> WCv2 startup now restores existing WalletConnect sessions
**sequentially** via a new `restoreSessions()` flow, adding a small
stagger (`SESSION_RESTORE_STAGGER_MS`) between `updateSession` calls to
avoid relay-traffic spikes.
> 
> Initialization (`WC2Manager.init`) now triggers this restore pass
after constructing the manager, and tests were extended to assert serial
execution, the per-session delay, and that sessions with
internal/invalid URLs are skipped.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2c7c339. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…27945)

## Description

`removeSession()` calls
`permissionsController.revokeAllPermissions(session.topic)`, but
permissions are stored under `session.pairingTopic` (used as `channelId`
/ `origin` when `requestPermissions` is called in
`_handleSessionProposal` — lines 468, 581).

Since `topic` and `pairingTopic` are always different values, the
revocation was targeting a non-existent subject and silently failing
(caught by the surrounding try/catch). Stale permission entries
accumulated in the `PermissionController` for every disconnected WC
session.

This changes the revocation key to `session.pairingTopic` to match how
permissions are created.

## Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/WAPI-1361


## **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 - Fixed removeSession() using session.topic
instead of session.pairingTopic when revoking WalletConnect permissions,
which caused stale permission entries to persist in the
PermissionController
([#27945](#27945))

## Manual testing steps

1. Connect a dapp via WalletConnect
2. Inspect `PermissionController.state.subjects` — the dapp's entry
should be keyed by `pairingTopic`
3. Disconnect the session (long-press in Settings > Experimental > WC
Sessions)
4. Inspect `PermissionController.state.subjects` — the entry should now
be removed

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how WalletConnect v2 session teardown revokes permissions,
which impacts permission state cleanup and could affect disconnect
behavior if the wrong identifier is used elsewhere. Scope is small and
covered by an updated unit test.
> 
> **Overview**
> Fixes `WC2Manager.removeSession()` to revoke permissions using
`session.pairingTopic` (and logs that identifier) instead of
`session.topic`, preventing stale `PermissionController` subjects from
accumulating after disconnects.
> 
> Updates the `WalletConnectV2` unit test to assert
`revokeAllPermissions` is called with the pairing topic.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8ba16c9. 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 Mar 26, 2026
@pull pull Bot added the ⤵️ pull label Mar 26, 2026
@pull pull Bot merged commit 98e65ea into Reality2byte:main Mar 26, 2026
3 of 26 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.

10 participants