Skip to content

feat(perps): default pay token when no balance and Add funds CTA on market details#26281

Merged
michalconsensys merged 19 commits into
mainfrom
feat/perps/tokens-defaults
Mar 6, 2026
Merged

feat(perps): default pay token when no balance and Add funds CTA on market details#26281
michalconsensys merged 19 commits into
mainfrom
feat/perps/tokens-defaults

Conversation

@michalconsensys
Copy link
Copy Markdown
Contributor

@michalconsensys michalconsensys commented Feb 19, 2026

Description

  1. Why: Users with no perps balance saw an unclear flow (e.g. no preselected pay token, or Long/Short with no way to fund).
  2. What: (a) When the user has no perps balance and the pay-with-any-token allowlist is enabled, we preselect the allowlist token with the highest USD balance in the order Pay row. (b) When they have no perps balance and no such token can be preselected, we show a single "Add funds" CTA on the market details screen instead of Long/Short; tapping it navigates to the perps confirmation stack and opens the deposit flow.
  • New hook useDefaultPayWithTokenWhenNoPerpsBalance: returns the allowlist token with highest balance when availableBalance <= PERPS_MIN_BALANCE_THRESHOLD, otherwise null. Respects perpsPayWithAnyTokenAllowlistAssets.
  • Constant PERPS_MIN_BALANCE_THRESHOLD (0.01) in perpsConfig.ts for the "no perps balance" threshold and minimum token balance for preselection.
  • PerpsPayRow: uses the hook; when pending config has no selected token, either preselects that token (via setPayToken + setSelectedPaymentToken) or sets selected payment to Perps balance (null).
  • PerpsMarketDetailsView: uses usePerpsLiveAccount, the new hook, and useConfirmNavigation. When showAddFundsCTA (no position, not at OI cap, balance < 0.01, and hook returns null), footer shows "Add funds" only; handleAddFunds calls navigateToConfirmation({ stack: Routes.PERPS.ROOT }) then depositWithConfirmation(). Otherwise Long/Short buttons are shown as before.

Changelog

CHANGELOG entry: When users have no perps balance, the app now preselects the allowlist token with the highest balance for payment when available, and shows an "Add funds" button on the market details screen when no token can be preselected.

Related issues

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

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

simulator_screenshot_EB73FD6D-B607-4611-8B08-3C6B63737730

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.

Note

Medium Risk
Changes the perps funding/payment-token selection and deposit entrypoint from PerpsMarketDetailsView, which can affect how users land in confirmations and which token is preselected. Logic is gated by balance thresholds/allowlists but still touches trading UX flows and error handling.

Overview
Improves the zero/low perps balance onboarding flow by adding useDefaultPayWithTokenWhenNoPerpsBalance, which selects the allowlisted pay-with-any-token asset with the highest fiat balance (above PERPS_MIN_BALANCE_THRESHOLD) while excluding the current provider’s native chain.

PerpsPayRow now uses this hook to auto-preselect that token when pending trade config has no selected token; otherwise it keeps defaulting to Perps balance (null). PerpsMarketDetailsView conditionally replaces Long/Short with a single Add funds CTA when balance is below threshold and no default token exists; pressing it navigates to the Perps confirmation stack and triggers depositWithConfirmation(), logging any deposit errors.

Adds supporting config (PERPS_MIN_BALANCE_THRESHOLD, provider chain-id mapping + getPerpsProviderChainId), expands Perps view state fixtures for component tests, and updates/adds unit tests covering the new behaviors.

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

michalconsensys and others added 3 commits February 19, 2026 17:26
…erps balance

Co-authored-by: Cursor <cursoragent@cursor.com>
…on market details

Co-authored-by: Cursor <cursoragent@cursor.com>
@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.

@metamaskbot metamaskbot added the team-perps Perps team label Feb 19, 2026
…ndition

Co-authored-by: Cursor <cursoragent@cursor.com>
@michalconsensys michalconsensys marked this pull request as ready for review February 19, 2026 17:05
@michalconsensys michalconsensys requested a review from a team as a code owner February 19, 2026 17:05
Comment thread app/components/UI/Perps/hooks/useDefaultPayWithTokenWhenNoPerpsBalance.ts Outdated
Comment thread app/components/UI/Perps/Views/PerpsMarketDetailsView/PerpsMarketDetailsView.tsx Outdated
Comment thread app/components/UI/Perps/Views/PerpsMarketDetailsView/PerpsMarketDetailsView.tsx Outdated
michalconsensys and others added 3 commits February 20, 2026 11:20
…t unhandled rejection

Co-authored-by: Cursor <cursoragent@cursor.com>
…t chain

Co-authored-by: Cursor <cursoragent@cursor.com>
…nce and perpsStatePreset

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added size-L and removed size-M labels Feb 23, 2026
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.

Comment on lines +6 to +32
jest.mock('react-redux', () => ({
useSelector: jest.fn(),
}));

jest.mock('./index', () => ({
usePerpsNetwork: jest.fn(() => 'mainnet'),
}));

jest.mock('./usePerpsPaymentTokens', () => ({
usePerpsPaymentTokens: jest.fn(() => []),
}));

const mockUseSelector = jest.requireMock<typeof import('react-redux')>(
'react-redux',
).useSelector as jest.MockedFunction<
(typeof import('react-redux'))['useSelector']
>;
const mockUsePerpsNetwork = jest.requireMock<typeof import('./index')>(
'./index',
).usePerpsNetwork as jest.MockedFunction<
(typeof import('./index'))['usePerpsNetwork']
>;
const mockUsePerpsPaymentTokens = jest.requireMock<
typeof import('./usePerpsPaymentTokens')
>('./usePerpsPaymentTokens').usePerpsPaymentTokens as jest.MockedFunction<
(typeof import('./usePerpsPaymentTokens'))['usePerpsPaymentTokens']
>;
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.

way too many mocks. Can we use @testing-library/react-hooks? This look like AI verbose. Don't trust this a lot for unit testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 13930fc

Comment on lines +41 to +44
const hyperliquidChainId =
currentNetwork === 'testnet'
? HYPERLIQUID_TESTNET_CHAIN_ID
: HYPERLIQUID_MAINNET_CHAIN_ID;
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.

we need to make thinks more generic for other providers integration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 13930fc

Comment on lines +1311 to +1314
{hasLongShortButtons &&
!existingPosition &&
!isAtOICap &&
showAddFundsCTA && (
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.

can we have a more descriptive const above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 13930fc

Comment on lines +1329 to +1332
{hasLongShortButtons &&
!existingPosition &&
!isAtOICap &&
!showAddFundsCTA && (
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.

same here, reuse the const

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 13930fc

Copy link
Copy Markdown
Contributor

@aganglada aganglada left a comment

Choose a reason for hiding this comment

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

Don't trust a lot AI to do your unit test, use it to discover edge cases. But mocks will not cover most of the real cases.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 4, 2026

🔍 Smart E2E Test Selection

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

E2E Test Selection:
The changes are focused entirely on the Perps (perpetuals trading) feature:

  1. New Hook: useDefaultPayWithTokenWhenNoPerpsBalance - determines default payment token when user has no perps balance by selecting the allowlist token with highest USD balance.

  2. PerpsMarketDetailsView: Added "Add Funds" CTA button that shows when user has no perps balance and no allowlist token to preselect. Integrates with confirmation navigation and deposit flow.

  3. PerpsPayRow: Integrated the new hook to preselect allowlist token with highest balance when user has no perps balance.

  4. perpsConfig.ts: Added PERPS_MIN_BALANCE_THRESHOLD constant and provider chain ID mappings.

  5. Test Infrastructure: Updated perpsStatePreset.ts with additional state fixtures for testing.

Tag selection rationale:

  • SmokePerps: Primary tag - all changes are in the Perps feature (Views, hooks, constants)
  • SmokeWalletPlatform: Per tag description, Perps is a section inside the Trending tab, so changes to Perps views affect Trending
  • SmokeConfirmations: Per tag description, Add Funds deposits are on-chain transactions that require confirmations

The changes are well-scoped to Perps functionality with comprehensive unit tests. Risk is medium because while the changes are isolated to Perps, they affect user-facing payment flows and add a new CTA button.

Performance Test Selection:
The changes affect the Perps feature including: PerpsMarketDetailsView (new Add Funds CTA, conditional rendering logic), PerpsPayRow (payment token preselection), and new hooks for balance checking. These changes could impact perps market loading, add funds flow, and balance display - all covered by @PerformancePreps tag.

View GitHub Actions results

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 4, 2026

⚠️ E2E Fixture Validation — Structural changes detected

Category Count
New keys 60
Missing keys 0
Type mismatches 0
Value mismatches 7 (informational)

The committed fixture schema is out of date. To update, comment:

@metamaskbot update-mobile-fixture

View full details | Download diff report

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

@aganglada aganglada left a comment

Choose a reason for hiding this comment

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

way cleaner

@michalconsensys michalconsensys added this pull request to the merge queue Mar 6, 2026
Merged via the queue into main with commit 070c029 Mar 6, 2026
103 checks passed
@michalconsensys michalconsensys deleted the feat/perps/tokens-defaults branch March 6, 2026 19:14
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 6, 2026
@metamaskbot metamaskbot added the release-7.70.0 Issue or pull request that will be included in release 7.70.0 label Mar 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants