Skip to content

fix: yield improvements - validator handling, disabled states, UI consistency#11743

Merged
gomesalexandre merged 17 commits intodevelopfrom
feat_last_yield_bits_fr_this_time_no_cap
Jan 21, 2026
Merged

fix: yield improvements - validator handling, disabled states, UI consistency#11743
gomesalexandre merged 17 commits intodevelopfrom
feat_last_yield_bits_fr_this_time_no_cap

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Jan 20, 2026

Description

Validator Handling Improvements

  • Fixed yields like solana-sol-lido-staking (the only one with such issue atm, but could well apply to others) incorrectly showing Figment validator when requiresValidatorSelection: false
  • Replaced chain ID based default validator mapping with safer yield ID based mapping (DEFAULT_VALIDATOR_BY_YIELD_ID)
  • Added getDefaultValidatorForYield utility function for consistent validator lookup
  • Removed dangerous user's highest balance validator fallback (we only support single-validator for multi-validator yields atm) - navigation now only uses predefined defaults:
    • cosmos-atom-native-staking → ShapeShift DAO
    • solana-sol-native-multivalidator-staking → Figment

Disabled Yield States

  • Created isYieldDisabled utility function to centralize disabled check logic
  • Disabled yields are now filtered from "Other X Yields" section (unless user has balance)
  • Fixed filter options shrinking when filters applied by using unfiltered yield data for options

UI Consistency

  • Unified balance terminology to "Balance" (removed inconsistent "My Balance", "Your Balance")
  • Fixed yield modal close navigating to /yields instead of staying on current yield detail page
  • Added provider/validator icons in Earn tab yield selector
  • Fixed missing asset icons for yields in DeFi drawer tab (e.g., "Drift CASH Lending")

Code Cleanup

  • Removed dead translation keys: learnMore, myBalance, protocol, yourBalance
  • Added missing yieldXYZ.manage translation key
  • Added unit tests for getDefaultValidatorForYield and yield augmentation functions (65 tests passing)

Risk

Low-Medium risk. Changes affect yield UI display and navigation logic. No on-chain transaction modifications.

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Yield.xyz integration - display and navigation only, no transaction logic changes.

Testing

Engineering

Validator Display:

  1. Navigate to /#/yields/solana-sol-lido-staking?accountId=solana%3A5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp%3AETpdrEkK8n3jPLysUZCNe1LHdM76GSrbHgAtVpCvWYLp
    • Verify it does NOT show Figment validator info
    • Should show Lido provider info instead
  2. Navigate to /#/yields/cosmos-atom-native-staking
    • Verify ShapeShift DAO validator is displayed
  3. Navigate to /#/yields/solana-sol-native-multivalidator-staking
    • Verify Figment validator is displayed
  4. Test other staking yield detail pages - ensure they still look correct

Disabled Yields: (note disabled yield here is the one mentioned above i.e solana-sol-lido-staking, which has enter disabled upstream currently i.e the bug that MbMaria was experiencing)
5. Navigate to yields list - verify disabled yields are filtered out (unless user has balance)
6. Navigate to a yield detail page with "Other X Yields" section - verify disabled yields are not shown
7. Apply filters on yields list - verify filter dropdown options don't shrink

Modal Navigation:
8. Navigate to any yield deets page
9. Click deposit to open modal
10. Close modal - verify you remain on the yield detail page (not redirected to /yields)

DeFi Tab Icons:
11. Open wallet drawer → DeFi tab
12. Verify yield opportunities show their asset icons (e.g., CASH icon for "Drift CASH Lending")

Earn Tab:
13. Navigate to Trade → Earn tab
14. Click yield selector dropdown
15. Verify each yield shows provider/validator icon and name

Balance Terminology:
16. Check various yield pages - balance labels should consistently show "Balance" (not "My Balance" or "Your Balance")

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)

All changes are within the existing Yield.xyz feature flag scope.

Screenshots (if applicable)

  • Validator Display/Disabled yields:

https://jam.dev/c/d91e776f-f8ca-4816-b878-f7f15dd046c2

  • Close click

https://jam.dev/c/10a4ceae-a2ac-4038-9919-8e664a92b1de

  • DeFi icons

https://jam.dev/c/539b61da-ad34-4b47-ae32-f0df69eb5631

  • Balance Terminology

https://jam.dev/c/607887d1-a225-49ac-b2ac-a2173e3d96f5


🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • New translation keys and UI text for disabled deposits/withdrawals and a "Manage" action for yield assets.
  • Bug Fixes

    • Disabled yields hidden from lists when balance is zero.
    • Default validator resolution improved — now determined per-yield, yielding more reliable staking flows.
  • UI/UX Improvements

    • "Your Balance" renamed to "Balance".
    • Enhanced provider/validator display with avatars, badges, contextual tooltips.
    • Action buttons disabled with explanatory tooltips when unavailable.
  • Tests

    • Added tests for yield augmentation and default-validator lookup.

✏️ Tip: You can customize this high-level summary in your review settings.

gomesalexandre and others added 8 commits January 20, 2026 15:34
Yields like solana-sol-lido-staking have requiresValidatorSelection: false
but still require validatorAddress in the API request. This fix:

- UI: Only shows validator info when requiresValidatorSelection is true
- API: Still passes validatorAddress when the field exists in args

This prevents showing "Figment" validator in UI for yields that don't
actually require validator selection, while still satisfying API requirements.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
When closing the yield deposit modal on a yield-specific route
(e.g., /yields/solana-sol-lido-staking?modal=yield), the modal
now removes the modal search params instead of using navigate(-1).

This keeps the user on the yield detail page instead of
unexpectedly navigating back to the yields list.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Previously, yield opportunities in the DeFi drawer tab (e.g., "Drift CASH
Lending", "Kamino CASH Lending") showed no icon because:
1. The yieldId was used as assetId (invalid for icon lookup)
2. The provider icon was used but often empty/missing

Now:
- Added inputAssetId to YieldOpportunityDisplay type
- Pass inputAssetId when creating yield opportunity items
- Use AssetIcon component for yield items in position details

This ensures yields show the proper underlying asset icon (e.g., CASH icon
for CASH lending opportunities).

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add UI indicators for yields with status.enter=false
- Disable enter/exit buttons when status is false
- Show warning alerts in modals for disabled actions
- Filter disabled yields from lists unless user has balance
- Don't auto-select disabled yields as default
- Fix CASH icon not loading by handling null inputTokens array
- Add translations for depositsDisabled and withdrawalsDisabled

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Test augmenting inputTokens when array is provided
- Test fallback to token when inputTokens is null (CASH fix)
- Test fallback to token when inputTokens is empty array
- Test status preservation (enter/exit flags)
- Test metadata preservation (underMaintenance, deprecated)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Filter disabled yields from "Other X Yields" related markets section
- Fix "Available to Earn" filter options to use unfiltered data so options
  don't shrink when a filter is applied
- Unify balance terminology to "Balance" across all yield components
- Extract isYieldDisabled utility for code reuse

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Show provider/validator icon and name in Earn tab yield selector
- Add missing yieldXYZ.manage translation
- Remove dead translation keys: learnMore, myBalance, protocol, yourBalance

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Replace DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID with DEFAULT_VALIDATOR_BY_YIELD_ID
- Add getDefaultValidatorForYield utility function
- Remove user's highest balance validator fallback from navigation
- Default validators are now determined by yield ID, not chain ID:
  - cosmos-atom-native-staking: ShapeShift DAO
  - solana-sol-native-multivalidator-staking: Figment
- Update all yield components to use the new yield ID based approach
- Add unit tests for getDefaultValidatorForYield

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Adds yield-level disable flags and UI; centralizes default validator lookup by yield ID via getDefaultValidatorForYield; introduces isYieldDisabled; filters disabled yields without balance; propagates inputAssetId through yield opportunity flows; updates translations and numerous Yield-related components.

Changes

Cohort / File(s) Summary
Translations
src/assets/translations/en/main.json
Removed legacy balance keys and added defi.depositsDisabled, defi.depositsDisabledDescription, defi.withdrawalsDisabled, defi.withdrawalsDisabledDescription, yieldXYZ.asset.manage, yieldXYZ.manage, plus new yieldXYZ.providerDescriptions entries.
Yield utilities & constants
src/lib/yieldxyz/constants.ts, src/lib/yieldxyz/utils.ts, src/lib/yieldxyz/utils.test.ts
Replace chain-id default validator map with yield-id map (DEFAULT_VALIDATOR_BY_YIELD_ID); add getDefaultValidatorForYield() and isYieldDisabled(); export FIGMENT_SOLANA_VALIDATOR_ADDRESS; add tests for default lookup.
Token augmentation & tests
src/lib/yieldxyz/augment.ts, src/lib/yieldxyz/augment.test.ts
Compute augmented token once and reuse for fallback inputTokens; add tests validating inputTokens, status flags, and metadata preservation.
Validator selection & UI (earn flows)
src/components/MultiHopTrade/components/Earn/*.tsx, src/components/MultiHopTrade/components/Earn/components/YieldSelector.tsx
Swap chain-id constant usage for getDefaultValidatorForYield(yieldId); tighten guards for selectedYield; show provider/validator info and avatar; adjust validator defaults.
Yields pages & forms
src/pages/Yields/* (multiple files)
Add deposits/withdrawals disabled UI (alerts, badges, tooltips); disable enter/exit actions based on yield.status; filter yields via isYieldDisabled (hide when zero balance); route to /yields/{id}?validator={addr} when default validator exists.
Opportunities & dashboard
src/components/StakingVaults/hooks/useYieldAsOpportunities.ts, src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx
Propagate inputAssetId in aggregated opportunities; skip disabled yields with zero balance; simplify position filtering and conditional icon rendering.
Transaction flow & manager
src/pages/Yields/hooks/useYieldTransactionFlow.ts, src/pages/Yields/components/YieldManager.tsx, src/pages/Yields/components/YieldEnterModal.tsx
Use getDefaultValidatorForYield(yieldItem.id) for default validator selection across tx assembly, manager modal routing, and enter modal; remove chain-id constant usage.
Misc view/text updates
src/pages/Yields/components/*.tsx, src/pages/Yields/components/YieldViewHelpers.tsx, src/pages/Yields/components/YieldItem.tsx
Rename "Your Balance" → "Balance"; add deposits-disabled alert/badge and badges/tooltips for disabled actions; use isYieldDisabled filtering and getDefaultValidatorForYield consistently.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as Yields UI
  participant Utils as yieldxyz/utils
  participant Router
  participant Validators as ValidatorService

  User->>UI: Click yield entry
  UI->>Utils: isYieldDisabled(yield)
  Utils-->>UI: true/false
  alt disabled && zero balance
    UI-->>User: show tooltip / prevent navigation
  else
    UI->>Utils: getDefaultValidatorForYield(yieldId)
    Utils-->>UI: maybe-default-validator
    alt default validator exists
      UI->>Router: navigate to /yields/{yieldId}?validator={addr}
    else
      UI->>Validators: fetch validators (if required)
      Validators-->>UI: validators list
      UI->>Router: navigate to /yields/{yieldId}
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • NeOMakinG
  • 0xApotheosis

Poem

🐰 I hop through yields both old and new,
Validators found by ID, tidy and true,
Badges whisper "deposits paused" with charm,
Buttons rest safe, no unintended harm,
A rabbit cheers the code — light paws, bright view ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: validator handling improvements, disabled state handling, and UI consistency updates across the yield components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat_last_yield_bits_fr_this_time_no_cap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gomesalexandre gomesalexandre marked this pull request as ready for review January 20, 2026 16:46
@gomesalexandre gomesalexandre requested a review from a team as a code owner January 20, 2026 16:46
gomesalexandre and others added 2 commits January 20, 2026 17:50
Variables that early return null now use the maybe prefix for clarity.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx`:
- Around line 125-129: Remove the unreachable fallback to y.yieldId when mapping
opportunities in StakingPositionsByProvider.tsx: replace uses of y.inputAssetId
?? y.yieldId for assetId and underlyingAssetId with y.inputAssetId directly
(since useYieldAsOpportunities.ts guarantees inputAssetId is present);
alternatively, update the YieldOpportunityDisplay type to make inputAssetId
non-optional so callers and mappers like the map over yieldOpportunities reflect
that contract.

useYieldAsOpportunities filters out yields without inputAssetId,
so the fallback to yieldId was unreachable. Type now reflects the
actual guarantee.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (1)

73-81: Guard against missing default validator in balances.

If getDefaultValidatorForYield() returns a validator that isn’t present in balancesForYield.byValidator, validatorBalance becomes undefined and the UI shows 0 even when the user has balances on other validators. Add a presence check and fall back to the first available validator in that case.

🔧 Suggested fix
-        const defaultValidatorAddress = getDefaultValidatorForYield(yieldItem.id)
-        const validatorAddresses = Object.keys(balancesForYield.byValidator)
-        const selectedValidatorAddress = defaultValidatorAddress ?? validatorAddresses[0]
+        const defaultValidatorAddress = getDefaultValidatorForYield(yieldItem.id)
+        const validatorAddresses = Object.keys(balancesForYield.byValidator)
+        const selectedValidatorAddress =
+          defaultValidatorAddress &&
+          balancesForYield.byValidator[defaultValidatorAddress]
+            ? defaultValidatorAddress
+            : validatorAddresses[0]

Copy link
Collaborator

@NeOMakinG NeOMakinG left a comment

Choose a reason for hiding this comment

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

image image image https://jam.dev/c/de21eb01-d4a9-42e4-87d5-e5731f0094c2

Some protocols doesn't have icons in the filter dropdown

image Same in earn tab modal

Other than that the intended fix seems to work well!

gomesalexandre and others added 2 commits January 21, 2026 13:11
…ssing providers

- Fix YieldProviderInfo not showing for liquid staking yields like Lido
  (changed condition from !isStaking to !isStaking || !requiresValidatorSelection)
- Add fallback for providers not in API (e.g., Drift) to still show provider info
- Add provider descriptions for yearn, spark, rocket-pool, drift

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@gomesalexandre gomesalexandre enabled auto-merge (squash) January 21, 2026 12:14
@gomesalexandre
Copy link
Contributor Author

Some protocols doesn't have icons in the filter dropdown

Nice catch @NeOMakinG! Reported this one to Yield (missing in /providers).

@gomesalexandre gomesalexandre merged commit 288b84e into develop Jan 21, 2026
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_last_yield_bits_fr_this_time_no_cap branch January 21, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants