Skip to content

feat(perps): add competition banner to perps home screen cp-7.79.0#30731

Merged
michalconsensys merged 11 commits into
mainfrom
feat/perps-competition-banner
May 28, 2026
Merged

feat(perps): add competition banner to perps home screen cp-7.79.0#30731
michalconsensys merged 11 commits into
mainfrom
feat/perps-competition-banner

Conversation

@michalconsensys

@michalconsensys michalconsensys commented May 28, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a dismissible "Perps trading competition" promotional banner to the perps home screen. The banner is positioned between the balance actions (Add funds / Withdraw) and the positions section, matching the Figma design spec.

Motivation: Drive user engagement with the perps trading competition by surfacing a discoverable CTA on the perps home screen, alongside the existing carousel banner on wallet home and details in the Rewards tab.

Solution:

  • New PerpsCompetitionBanner component with trophy icon, title, description, close (X) button, and tap-to-navigate behavior
  • Tapping the banner navigates to the Rewards tab (Routes.REWARDS_VIEW)
  • Dismissing via the X button persists the dismissed state to StorageWrapper so the banner is not shown again
  • Visibility is gated by a new LaunchDarkly feature flag perps-competition-banner-enabled (disabled by default)
  • Full unit test coverage for the banner component (7 tests) and the feature flag selector (8 tests)

Changelog

CHANGELOG entry: Added a promotional banner for the perps trading competition on the perps home screen

Related issues

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

Manual testing steps

Feature: Perps competition banner

  Scenario: Banner is displayed when feature flag is enabled
    Given the feature flag "perps-competition-banner-enabled" is enabled
    And the user has not previously dismissed the banner

    When user navigates to the Perps home screen
    Then a banner with title "Perps trading competition" is displayed below the balance actions

  Scenario: Banner navigates to Rewards tab on tap
    Given the competition banner is visible on the Perps home screen

    When user taps the banner body
    Then the app navigates to the Rewards tab

  Scenario: Banner is permanently dismissed
    Given the competition banner is visible on the Perps home screen

    When user taps the close (X) button on the banner
    Then the banner disappears
    And the banner does not reappear on subsequent visits to the Perps home screen

  Scenario: Banner is hidden when feature flag is disabled
    Given the feature flag "perps-competition-banner-enabled" is disabled

    When user navigates to the Perps home screen
    Then no competition banner is displayed

Screenshots/Recordings

Before

N/A - new feature behind a feature flag (disabled by default)

After

simulator_screenshot_858AE3BA-CCC3-4997-A550-DAED44D90308

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

Note

Low Risk
Promotional UI behind a remote feature flag (off by default); dismiss state and Rewards navigation only—no auth, payments, or trading logic changes.

Overview
Adds a dismissible competition promotion banner on the Perps home screen, placed between balance actions and the positions section.

The new PerpsCompetitionBanner is shown only when the remote LaunchDarkly flag perps-competition-banner-enabled is on and the user has not dismissed it. Dismissal is stored via PERPS_COMPETITION_BANNER_DISMISSED in StorageWrapper (best-effort; still hides for the session if persistence fails). Tapping the banner sets a rewards pending deeplink (campaign: 'perps-comp') and navigates to Rewards. Close and engage actions emit PERPS_UI_INTERACTION analytics with competition_banner_close / competition_banner_engage.

Supporting changes: selectPerpsCompetitionBannerEnabledFlag, feature-flag registry entry, English copy, Perps home test ID, mocks, and docs/metrics reference updates. Unit tests cover the component and selector.

Reviewed by Cursor Bugbot for commit bb535c7. Bugbot is set up for automated code reviews on this repo. Configure here.

Add a dismissible promotional banner for the perps trading competition,
displayed between the balance actions and positions section. The banner
navigates to the Rewards tab on tap and persists its dismissed state via
StorageWrapper. Visibility is gated by a new LaunchDarkly feature flag
`perps-competition-banner-enabled` (disabled by default).
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-perps Perps team label May 28, 2026
…ndling

Replace placeholder icon with actual competition image asset, update
banner copy, fix close button event bubbling, and add error handling
for storage operations.
@github-actions github-actions Bot added size-L and removed size-M labels May 28, 2026
@michalconsensys michalconsensys marked this pull request as ready for review May 28, 2026 10:54
@michalconsensys michalconsensys requested review from a team as code owners May 28, 2026 10:54
… fontWeight

Verify exact deeplink payload in navigation test, add coverage for
storage write failure on dismiss, and replace raw fontWeight style
override with FontWeight.Medium prop from the design system.
…iew tests

The PerpsCompetitionBanner component uses useDispatch, which was not
included in the PerpsHomeView test's react-redux mock.
@michalconsensys michalconsensys changed the title feat(perps): add competition banner to perps home screen feat(perps): add competition banner to perps home screen cp-7.79.0 May 28, 2026
@michalconsensys michalconsensys enabled auto-merge May 28, 2026 11:28
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.54839% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.58%. Comparing base (de13f1e) to head (5c30872).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
.../PerpsCompetitionBanner/PerpsCompetitionBanner.tsx 92.30% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #30731   +/-   ##
=======================================
  Coverage   82.58%   82.58%           
=======================================
  Files        5514     5516    +2     
  Lines      141398   141443   +45     
  Branches    32564    32574   +10     
=======================================
+ Hits       116774   116814   +40     
- Misses      16823    16829    +6     
+ Partials     7801     7800    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

@abretonc7s

Copy link
Copy Markdown
Contributor

Automated Review — PR #30731

Posted directly after Farmslot UI publish stale/recovery failure. Review input refreshed to head 5c30872.

Recommendation REQUEST_CHANGES
Runner codex / gpt-5.5

PR Review: #30731 — feat(perps): add competition banner to perps home screen cp-7.79.0

Tier: standard

Summary

The PR adds the Perps competition banner behind a feature flag, places it below balance actions and above positions, navigates to the Rewards Perps campaign, and persists dismissal. The visible banner flow works on iOS, but the ticket requirement to track banner engage/close in Mixpanel is not implemented.

Recipe Coverage

# AC (verbatim) Target platform Recipe nodes (IDs) Screenshot filename Visual verdict Justification
1 "Then a banner with title "Perps trading competition" is displayed below the balance actions" both (ios slot) ac1-wait-banner-visible, ac1-assert-banner-context, ac1-screenshot-banner-placement evidence-ac1-banner-placement.png PROVEN Banner is visible directly below Withdraw/Add funds and above positions; screenshot shows the implemented banner copy "Competition leaderboard".
2 "Then the app navigates to the Rewards tab" both (ios slot) ac2-press-banner, ac2-wait-rewards-route, ac2-screenshot-rewards evidence-ac2-rewards-route.png PROVEN Tapping the banner navigated to RewardsPerpsTradingCampaignDetails, a Rewards route for the Perps trading competition.
3 "Then the banner disappears" both (ios slot) ac3-wait-banner-visible, ac3-press-close, ac3-wait-banner-hidden evidence-ac3-dismissal-failure.png, debug-close-failure.png PROVEN Fiber wait timed out, but both failure/debug screenshots show the banner visually gone after close.
4 "And the banner does not reappear on subsequent visits to the Perps home screen" both (ios slot) manual revisit after ac3-press-close evidence-ac4-revisit-hidden.png PROVEN After navigating to Wallet home and back to Perps home, the banner remained absent.
5 "Then no competition banner is displayed" both (ios slot) gate-ac5-disabled-flag-untestable n/a UNTESTABLE Live slot cannot safely toggle LaunchDarkly/env flag without remote override or rebuild; selector unit tests cover disabled flag behavior.

Overall recipe coverage: 4/5 ACs PROVEN
Untestable: AC5 live flag-disabled scenario; covered by unit tests.

Prior Reviews

No prior reviews.

Acceptance Criteria Validation

# Criterion Status Evidence
1 Banner displayed below balance actions PASS evidence-ac1-banner-placement.png
2 Banner navigates to Rewards PASS ac2-wait-rewards-route reached RewardsPerpsTradingCampaignDetails
3 Banner disappears PASS evidence-ac3-dismissal-failure.png and debug-close-failure.png show banner absent
4 Banner stays dismissed on revisit PASS evidence-ac4-revisit-hidden.png
5 Banner hidden when flag disabled PASS (unit), UNTESTABLE (live) Feature flag selector tests passed
Ticket Track Mixpanel engage/close FAIL No tracking calls in handlePress or handleDismiss

Code Quality

  • Pattern adherence: mostly follows local Perps feature flag and component patterns.
  • Complexity: appropriate for a small UI banner.
  • Type safety: yarn lint:tsc passed.
  • Error handling: storage read/write failures degrade safely.
  • Anti-pattern findings: missing Perps UI interaction tracking on new CTA and close paths.

Fix Quality

  • Best approach: Isolated banner component plus selector/storage key is a pragmatic implementation.
  • Would not ship: PerpsCompetitionBanner.tsx:80 and :89 do not track close/engage events required by the ticket.
  • Test quality: Relevant tests pass, but banner tests emit act(...) warnings around the async storage effect.
  • Brittleness: The tests mock ButtonIcon, so they do not exercise real design-system touch behavior; visual validation covered the live dismissal path.

Live Validation

  • Recipe: generated
  • Result: FAIL in trace due stale fiber hidden wait after close; screenshot audit proves AC3/AC4 visually.
  • Video: failed; simctl recordVideo produced a no-moov artifact and then reported host recording busy.
  • Native changes: none
  • Metro errors: unrelated wallet/card/snap warnings observed; recipe issue review was clean for unexpected runtime warnings/errors.
  • Log monitoring: Metro log tail checked after validation.

Correctness

  • Diff vs stated goal: mostly aligned, except ticket analytics requirement is missing.
  • Edge cases: storage read/write failure covered; disabled flag covered by unit tests.
  • Race conditions: no product race found.
  • Backward compatibility: preserved behind a default-off remote flag.

Static Analysis

  • lint:tsc: PASS
  • Tests: 146/146 pass

Architecture & Domain

The new flag follows existing Perps version-gated selector conventions and registry documentation. No controller, provider, or websocket behavior changes.

Risk Assessment

  • MEDIUM — UI-only and flag-gated, but missing required analytics blocks ticket completion.

Recommended Action

REQUEST_CHANGES

Add MetaMetrics/Mixpanel tracking for both banner engage and close paths, with tests asserting the emitted event payloads.

Line comments JSON
{
  "pr_number": "30731",
  "recommendation": "REQUEST_CHANGES",
  "summary": "The banner display, Rewards navigation, and dismissal behavior are visually validated, but the linked ticket's Mixpanel tracking requirement is missing for both engage and close.",
  "comments": [
    {
      "path": "app/components/UI/Perps/components/PerpsCompetitionBanner/PerpsCompetitionBanner.tsx",
      "line": 80,
      "body": "The linked ticket requires tracking whether users close the banner, but `handleDismiss` only updates local/storage state. Please emit the Perps UI interaction/MetaMetrics event for the close action here and add an assertion in `PerpsCompetitionBanner.test.tsx` for the event payload.",
      "severity": "must_fix"
    },
    {
      "path": "app/components/UI/Perps/components/PerpsCompetitionBanner/PerpsCompetitionBanner.tsx",
      "line": 89,
      "body": "The linked ticket also requires tracking whether users engage with the banner. This press handler dispatches the Rewards deeplink and navigates, but it never records the banner tap. Please add the corresponding Perps UI interaction/MetaMetrics event before navigation and cover it in tests.",
      "severity": "must_fix"
    },
    {
      "path": "app/components/UI/Perps/selectors/featureFlags/index.test.ts",
      "line": 899,
      "body": "This selector test file is now 2,099 lines, which crosses the review guardrail's suggestion threshold. Follow-up suggestion: split Perps feature-flag selector tests by flag group so new flags do not keep growing one large suite.",
      "severity": "suggestion"
    }
  ]
}

@abretonc7s abretonc7s left a comment

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.

Automated review — see comment above for full details.

…nd close

Track PERPS_UI_INTERACTION events when users tap (engage) or dismiss
(close) the competition banner on the perps home screen. Includes
local constants for button_clicked values pending upstream addition
to @metamask/perps-controller, and updates the MetaMetrics reference
doc with the new event payloads.
@michalconsensys

Copy link
Copy Markdown
Contributor Author

@abretonc7s I've addressed yoru comments

Competition banner is now controlled exclusively via remote feature flag
(LaunchDarkly). The local env var fallback is no longer needed.
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR introduces a new PerpsCompetitionBanner component added to the PerpsHomeView. Key changes:

  1. New PerpsCompetitionBanner component - Feature-flagged UI banner on the Perps home screen. The flag defaults to false in production, so the banner is hidden by default. However, the component is now rendered in PerpsHomeView and could affect layout/rendering.

  2. Feature flag registry (critical file) - Adds perpsCompetitionBannerEnabled entry. This is an additive change that doesn't modify existing flags, so risk to other features is minimal.

  3. Storage constant - New PERPS_COMPETITION_BANNER_DISMISSED key for persisting dismissal state via StorageWrapper.

  4. Test IDs - New COMPETITION_BANNER test ID added to PerpsHomeViewSelectorsIDs.

  5. Localization - New strings for competition banner.

Tag Selection Rationale:

  • SmokePerps: Primary tag - the PerpsHomeView is directly modified with a new component. Existing Perps E2E tests (add-funds, position, limit-long-fill, stop-loss) should be run to verify the new banner doesn't break existing Perps flows.
  • SmokeWalletPlatform: Required per SmokePerps tag description - "Perps is also a section inside the Trending tab (SmokeWalletPlatform); changes to Perps views affect Trending."
  • SmokeConfirmations: Required per SmokePerps tag description - "When selecting SmokePerps, also select SmokeConfirmations (Add Funds deposits are on-chain transactions)."

No changes to core navigation, account management, network, swap, or other wallet features, so other tags are not warranted.

Performance Test Selection:
The PerpsHomeView now conditionally renders a new PerpsCompetitionBanner component. While the banner returns null when the feature flag is disabled (default), the component is still instantiated and runs async storage checks on mount. The @PerformancePreps tag covers perps market loading and the add funds flow, which includes PerpsHomeView rendering. This warrants a performance check to ensure the new component doesn't introduce measurable overhead in the Perps home screen render path.

View GitHub Actions results

@michalconsensys michalconsensys added this pull request to the merge queue May 28, 2026
Merged via the queue into main with commit 94ea783 May 28, 2026
199 checks passed
@michalconsensys michalconsensys deleted the feat/perps-competition-banner branch May 28, 2026 17:03
@github-actions github-actions Bot locked and limited conversation to collaborators May 28, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.80.0 Issue or pull request that will be included in release 7.80.0 label May 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.80.0 Issue or pull request that will be included in release 7.80.0 size-L team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants