Skip to content

chore: cherry-pick feat: MUSD-518: Add segment event that tracks when the claim CTA is shown cp-7.70.0#27618

Closed
chloeYue wants to merge 1 commit into
release/7.70.0from
cherry-pick-7-70-0-2e4645a
Closed

chore: cherry-pick feat: MUSD-518: Add segment event that tracks when the claim CTA is shown cp-7.70.0#27618
chloeYue wants to merge 1 commit into
release/7.70.0from
cherry-pick-7-70-0-2e4645a

Conversation

@chloeYue
Copy link
Copy Markdown
Contributor

@chloeYue chloeYue commented Mar 18, 2026

Cherry-pick of #27353 into release/7.70.0 release branch.

Adds mUSD Claim Bonus CTA Available event that fires when the Merkl claim CTA is mounted.

mUSD Claim Bonus CTA Available Event Properties

Property Type Description
location string Where the CTA is rendered (e.g. token_list_item, home_cash_section)
view_trigger string E.g. component_mounted
network_chain_id string Chain ID of the token's network
asset_symbol string Token symbol (e.g. mUSD)
has_claimed_before boolean Whether the user has previously claimed a Merkl reward for this token

CHANGELOG entry: added mUSD Claim Bonus CTA Available event that fires when the Merkl claim CTA is mounted.

Fixes: MUSD-518: Mobile - Add segment event which tracks when the claim CTA is shown and how much the user would have to
claim

Feature: Merkl claim bonus CTA impression tracking

  Scenario: user sees claim bonus CTA in token list
    Given user has a claimable Merkl reward on an eligible token

    When the token list item scrolls into view
    Then a "mUSD Claim Bonus CTA Available" event fires once with reward range, location, and network metadata

  Scenario: user sees claim bonus CTA in home cash section
    Given user holds mUSD on Linea and has a claimable Merkl bonus

    When the mUSD aggregated row is visible on the home screen
    Then a "mUSD Claim Bonus CTA Available" event fires once with location "home_cash_section"

N/A -mUSD Claim Bonus CTA Available event doesn't exist

musd-518-claim-cta-available-after-demo.mov
  • I've followed MetaMask Contributor Docs and MetaMask Mobile Coding
    Standards
    .

  • 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 format if applicable

  • I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

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


Note

Medium Risk
Adds new analytics side effects and changes the useMerklBonusClaim API to require location/visibility inputs, plus introduces viewability state in the token list; mistakes here could cause missing/duplicate events or extra re-renders.

Overview
Adds a new MetaMetrics event MUSD_CLAIM_BONUS_CTA_DISPLAYED emitted from useMerklBonusClaim when a claimable Merkl bonus CTA is eligible, above threshold, not pending, and the hosting component is visible; the event includes location, network/asset metadata, claim history, and a bucketed bonus amount range.

Updates useMerklRewards to also return hasClaimedBefore (derived from on-chain claimed amount), and updates token list surfaces (TokenListItem, TokenListItemV2, MusdAggregatedRow) to pass a required location plus a new isVisible signal. TokenList now tracks FlashList viewability and forwards per-row visibility to support impression tracking. Tests are expanded/updated for the new hook signature, reward threshold handling, and analytics firing semantics.

Written by Cursor Bugbot for commit 2451fa1. This will update automatically on new commits. Configure here.


Description

Changelog

CHANGELOG entry:

Related issues

Fixes:

Manual testing steps

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

Before

After

Pre-merge author checklist

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.

…hown cp-7.70.0 (#27353)

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

Adds `mUSD Claim Bonus CTA Available` event that fires when the Merkl
claim CTA is mounted.

`mUSD Claim Bonus CTA Available` Event Properties
| Property | Type | Description |
|---|---|---|
| `location` | `string` | Where the CTA is rendered (e.g.
`token_list_item`, `home_cash_section`) |
| `view_trigger` | `string` | E.g. `component_mounted` |
| `button_text` | `string` | E.g. `Claim bonus` |
| `network_chain_id` | `string` | Chain ID of the token's network |
| `network_name` | `string` | Human-readable network name (e.g.
`Ethereum Mainnet`) |
| `asset_symbol` | `string` | Token symbol (e.g. `mUSD`) |
| `bonus_amount_range` | `string` | Bucketed reward value: `< 0.01`,
`0.01 - 0.99`, `1.00 - 9.99`, `10.00 - 99.99`, `100.00 - 999.99`,
`1000.00+` |
| `has_claimed_before` | `boolean` | Whether the user has previously
claimed a Merkl reward for this token |
<!--
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?
-->

<!--
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: added mUSD Claim Bonus CTA Available event that fires
when the Merkl claim CTA is mounted.

Fixes: [MUSD-518: Mobile - Add segment event which tracks when the claim
CTA is shown and how much the user would have to
claim](https://consensyssoftware.atlassian.net/browse/MUSD-518)

```gherkin
Feature: Merkl claim bonus CTA impression tracking

  Scenario: user sees claim bonus CTA in token list
    Given user has a claimable Merkl reward on an eligible token

    When the token list item scrolls into view
    Then a "mUSD Claim Bonus CTA Available" event fires once with reward range, location, and network metadata

  Scenario: user sees claim bonus CTA in home cash section
    Given user holds mUSD on Linea and has a claimable Merkl bonus

    When the mUSD aggregated row is visible on the home screen
    Then a "mUSD Claim Bonus CTA Available" event fires once with location "home_cash_section"
```

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

N/A -`mUSD Claim Bonus CTA Available` event doesn't exist
<!-- [screenshots/recordings] -->

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

https://github.com/user-attachments/assets/bf04a706-7a64-42a3-b21a-e522cbc7b38b

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

- [ ] 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 analytics emission tied to token-list viewport visibility and
extends Merkl reward hooks, which could impact event volume/accuracy and
token list rendering performance if mis-triggered.
>
> **Overview**
> Adds a new MetaMetrics event, `MUSD_CLAIM_BONUS_CTA_DISPLAYED`, fired
from `useMerklBonusClaim` **once per mount** when a Merkl bonus is
claimable, there is no pending claim, and the CTA is *visible*; the
event includes location, network metadata, a bucketed
`bonus_amount_range`, and a new `has_claimed_before` flag derived from
on-chain claimed amount.
>
> Updates token list rows (`TokenListItem`/`TokenListItemV2`) and the
home cash section to pass `location` and viewport visibility into
`useMerklBonusClaim`, and teaches `TokenList` (FlashList mode) to track
visible items via `onViewableItemsChanged` and propagate `isVisible`
down. Tests are expanded/updated to cover the new hook signature,
impression gating, and reward-range bucketing.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
784b6b7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Matthew Grainger <matthew.grainger@consensys.net>
Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
@chloeYue chloeYue requested review from a team as code owners March 18, 2026 14:25
@chloeYue chloeYue added skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-earn labels Mar 18, 2026
@metamaskbot metamaskbot added the team-qa QA team label Mar 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - base branch is not main (base: release/7.70.0)

All E2E tests pre-selected.

View GitHub Actions results

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

const hasClaimableBonus =
isEligible &&
isClaimableBonusAboveThreshold(claimableReward) &&
!hasPendingClaim;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined function isClaimableBonusAboveThreshold crashes eligible tokens

High Severity

isClaimableBonusAboveThreshold is called on line 105 but is never defined or imported anywhere in the codebase (verified via exhaustive search). For eligible tokens where isEligible is true, evaluating this expression will throw a ReferenceError, crashing the component. Additionally, the hook's return path at line 147–158 passes through raw claimableReward without any threshold filtering, so even if the function were defined, sub-threshold values like "< 0.01" would still be returned instead of null — contradicting the behavior the new tests expect.

Additional Locations (1)
Fix in Cursor Fix in Web

@chloeYue
Copy link
Copy Markdown
Contributor Author

chloeYue commented Mar 18, 2026

close this PR in favour of #27605

@chloeYue chloeYue closed this Mar 18, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

size-L skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-earn team-qa QA team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants