Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Jan 14, 2026

Description

This PR consolidates the following PRs into a single review-friendly PR targeting develop:

All above PRs will be closed in favor of this consolidated PR.

What's included:

Fixes:

  • Fix transaction modal showing skipped approval steps that shouldn't be visible
  • Fix "My Positions" showing empty after deposit/withdraw (now waits for data refresh)
  • Fix Action Center notifications staying stuck on "Pending" after transaction completes
  • Fix balance not updating for second-class chains (Monad, Tron, etc.) after yield transactions
  • Fix filters not working on asset symbol pages (e.g., /yields/asset/GHO)
  • Fix stale quote shown when re-entering deposit/withdraw modal after completing a transaction
  • Fix claim flow by properly passing passthrough and manageActionType from pendingActions
  • Fix APY in a few places for Cosmos SDK staking (ShapeShift DAO validator and Cosmostation)
  • Fix success step not showing when staking from earn CTA in account/asset page
  • Fix duplicate close buttons on success step

Features:

  • Add new earn tab in swapper under flag for one-click yield aping
  • Add metric clarity tooltips for Available to Earn, APY help text, Potential Earnings
  • Add recommendation strip above tabs showing top 3 opportunities based on holdings
  • Add type filter alongside network/provider with URL persistence
  • Add new one-click enter modal in account/asset pages
  • Add new flag for "Yield page" to soft toggle yield without full yields page
  • Create YieldForm, YieldHero, and YieldManager components for cleaner yield detail page

UX/UI Improvements:

  • Better information architecture of /yields route for mobile
  • Improve mobile layouts throughout
  • Make yield feature less ai-spewy and more consistent with design system
  • Honor various enter terminologies depending on yield type (stake/deposit/supply)
  • Use proper translation interpolation instead of string concatenation
  • Improve desktop layout with wider container and better spacing
  • Simplify YieldStats to 3-column grid without card wrapper
  • YieldPositionCard now hides when no balance
  • Render asset cards when there is a single yield for that asset
  • Prefer asset symbols for simplicity; leverage right-side APY for easy comparison

Cleanup:

  • Remove multi-validator support - only use default validator (ShapeShift DAO for Cosmos)
  • Delete unused components: ValidatorBreakdown, YieldEnterExit, YieldValidatorSelectModal (~1300 lines removed)
  • Remove unused translations
  • Perform code extraction/unification

Issue (if applicable)

Risk

Low - all changes are scoped to the yield feature which is behind a feature flag. No changes to transaction logic beyond fixing the claim flow passthrough.

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

Yield.xyz integrations, yield enter/exit/claim actions on all supported yield protocols.

Testing

Engineering

  • Ensure yield-specific page looks and performs well (stake/unstake/claim) in web and mobile viewports
  • Ensure multi-validator support is gone (only default validator used)
  • Navigate to /yields and apply network/provider/type filters - verify persistence
  • Click on an asset (e.g., USDC) - filters should persist in URL
  • Test deposit transaction and verify:
    • Only non-skipped steps shown in modal
    • "My Positions" shows balance immediately after completion
    • Action Center shows "Complete" not "Pending"
    • For Monad/Tron, native balance updates after tx
  • Test earn tab with USDT and another asset
  • Test subsequent deposits - should request approval again, not show stale quote
  • Ensure USDT deposits are gucci (approval needed, reset + approval needed, no approval needed)
  • Ensure ShapeShift DAO is still "preferred" for Cosmos SDK staking
  • Things look better on mobile now!

Operations

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

Screenshots (if applicable)

Yield detail page refactor:
https://jam.dev/c/2ff6b47e-d2dc-4147-a0d9-52c10a703069

Mobile improvements:
mobile1
mobile2
mobile3
mobile4

Type filter & recommendations:
https://jam.dev/c/8bae16b6-87fe-41a8-a480-f918a0b70679

Earn tab:
https://jam.dev/c/c9e81000-60cb-4430-95d0-89a51225629f
https://jam.dev/c/4fabf2af-06af-488f-8e5b-e93f513c278b

One-click enter flow - Mobile:
https://jam.dev/c/1ff8f48c-ca5e-4b79-992c-cc5bf9109ffb

One-click enter flow - Desktop:
https://jam.dev/c/1f93ce52-a66f-410c-a0ae-c92eb47d3ba9

USDT reset + approval flows:
https://jam.dev/c/2f4fe73b-095f-45f0-8e5d-7f11b654b9cf
https://jam.dev/c/c8a11f4e-aabb-4485-bab9-63a9276193c9

Initial fixes:
https://jam.dev/c/9f77b0f6-7185-4383-ac98-6dcd8f32517e
https://jam.dev/c/71010588-6804-4cf5-8974-b31cd602e5cd

Success step & duplicate close button fixes:

Summary by CodeRabbit

  • New Features

    • Earn tab with end-to-end Enter → Confirm → Success flow, including full-screen enter modal, compact confirm UI, manager/detail views, and confetti success screen.
    • Yield selector, provider/validator selection, transaction steps list, and wallet-integrated enter/exit flows.
  • Improvements

    • Terminology unified to Enter/Exit, expanded translations, tooltips, dynamic action labels, and responsive/mobile-first yields listing with filters and recommended strip.
    • Simplified, clearer footers, stats, and action behaviors.
  • Chores

    • Added feature flags for Yields page and Earn tab (dev & prod).

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

gomesalexandre and others added 30 commits January 11, 2026 16:22
- Remove unnecessary filteredYields dependency in YieldAssetDetails useMemo hooks
- Add validator breakdown utility functions
- Enhance yield action modal with additional transaction handling
- Refactor yield filters component for better code organization
- Update yields list component layout
- Improve yield filters hook logic
- Add yield transaction flow hooks
- Add missing translation key

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add APPROVAL type to TX_TYPE_TO_LABEL (button now shows "Approve" not "Approval")
- Filter SKIPPED transactions in displaySteps preview
- Use first CREATED transaction for button text
- Harmonize button/row labels: SUPPLY/ENTER -> "Deposit", EXIT -> "Withdraw"
- Fix useCallback missing dependencies in useYieldTransactionFlow
- Add icon background color for yield detail hero
- Add chainName to action transaction metadata

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change invalidateQueries to refetchQueries with await
- Ensures position data is fresh before modal closes
- Fixes "My Positions" showing empty after deposit/withdraw

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Since dispatchNotification is called after waitForActionCompletion,
the transaction is already confirmed. Dispatch with Complete status
directly instead of relying on Unchained subscriber (which doesn't
work for chains without Unchained support like Monad).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
After yield transaction completion, trigger portfolioApi.getAccount
refetch for second class chains (Monad, Tron, etc.) that don't have
Unchained support. This ensures wallet balances update immediately.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract sortedRows from table to use as dependency
- TanStack Table's table object reference is stable, so useMemo
  was not re-running when filtered data changed
- Using sortedRows as dependency triggers proper re-memoization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add searchString prop to YieldItem
- Pass current filter params when navigating to asset detail page
- Filters persist across navigation (e.g., network=ethereum)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Set staleTime: Infinity to prevent refetching during modal lifecycle
- Set gcTime: 0 to garbage collect cached quote when modal closes
- Ensures fresh quote on re-entry, no stale data from previous tx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove quote queries from cache when modal closes
- Ensures fresh quote fetch on subsequent modal opens
- Remove YIELD_POLISH.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create YieldEnterModal component with Trust Wallet-inspired design
- Big centered input with fiat/crypto toggle
- Asset icon, percent buttons (25%, 50%, 75%, Max)
- Debounced quote fetching (500ms) for pre-loading transactions
- Auto-select default validator (ShapeShift DAO for Cosmos)
- Stats section with APY, validator/provider info, and min deposit
- Modify YieldAssetSection to open modal instead of navigate
- Add translation key for "Stake {asset}"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TransactionStepsList component for shared step display
- Extract useConfetti hook to eliminate duplication
- Export poll/waitForActionCompletion from useYieldTransactionFlow
- Update YieldOpportunityCard with horizontal layout
- Use Card variant='dashboard' in YieldAssetSection
- Add tx hash links in success view

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ventions, style fixes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- YieldFilters: Use MenuOptionGroup/MenuItemOption for proper theme styling (no more blue.500)
- ValidatorBreakdown: Remove useColorModeValue, use direct color tokens
- YieldEnterModal: Extract hover style constants outside component
- YieldEnterExit: Extract style constants outside component, fix inline button handlers
- YieldActionModal: Use STATUS_LABEL_KEYS map to avoid nested ternaries
- useYieldTransactionFlow: Rename loadingMessage to statusLabel for consistency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…a.50

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- YieldValidatorSelectModal: gray.300, gray.500 -> text.subtle
- YieldActionModal: whiteAlpha.50 -> background.surface.raised.base

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SHAPESHIFT_VALIDATOR constant with fallback APR data
- normalizeCosmosValidators ensures ShapeShift is always first
- Only ShapeShift is marked as preferred for Cosmos SDK
- Add COSMOS_NETWORK_FALLBACK_APR (15%) for validators missing APR
- Remove redundant sortValidators call in modal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove redundant ASSET column from YieldActivePositions table
- Remove "Your Balance" label (already obvious from context)
- Move ensureValidatorApr to utils for reuse
- Fix React key warning in ReactTable (destructure key from spread props)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…hide section without wallet

- Extract TransactionStepStatus from anonymous IIFE in YieldActionModal
- Reuse existing poll utility from lib/poll instead of custom implementation
- Hide YieldAssetSection when wallet is not connected
- Reorder TransactionStep type fields for cleaner grouping
- Remove unnecessary curly braces in useYieldValidators

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…saction step

- Reverted poll changes to use original inline implementation
- Export waitForActionCompletion for YieldEnterModal usage
- Fix enterButtonText to use getTransactionButtonText for proper labels
  (shows "Approve" instead of "Stake USDT" when approval is first step)
- Add originalTitle and type to TransactionStep in YieldEnterModal
- Ensure consistent use of loadingMessage property

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… model

- Replace for-loop auto-execution with click-per-step model matching useYieldTransactionFlow
- Add activeStepIndex, rawTransactions, currentActionId state for multi-step tracking
- Extract executeSingleTransaction callback for single transaction execution
- Export filterExecutableTransactions from hook for code reuse
- Fix button text and steps display between transaction steps

[skip ci]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…dals

[skip ci]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds waitForTransactionConfirmation helper to poll backend until the
submitted transaction is confirmed, preventing nonce conflicts when
users quickly transition between Approve and Deposit transactions.

This resolves "replacement transaction underpriced" errors by ensuring
the on-chain nonce counter has incremented before constructing the next
transaction.

[skip ci]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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/MultiHopTrade/components/Earn/EarnConfirm.tsx`:
- Around line 282-285: The asset symbol and the "/yr" translation are rendered
back-to-back causing outputs like "1.5 ETH/yr"; update the JSX in EarnConfirm
(where GradientApy, estimatedYearlyEarnings, sellAsset?.symbol and
translate('yieldXYZ.perYear') are used) to include a space between the symbol
and the translation (e.g., ensure the symbol and translate('yieldXYZ.perYear')
are concatenated with a separating space or add a leading space to the
translation string) so the result renders as "1.5 ETH /yr" or "1.5 ETH / yr" per
project style.
♻️ Duplicate comments (1)
src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx (1)

196-196: The isLoading prop is unused by SharedConfirm.

This was identified in a previous review. The prop is passed on lines 196, 219, and 345 but SharedConfirm does not destructure or use it.

Also applies to: 219-219, 345-345

🧹 Nitpick comments (3)
src/pages/Yields/components/YieldActionModal.tsx (2)

208-208: Consider memoizing assetFlowDirection for consistency.

This conditional value is used as a dependency in animatedAvatarRow useMemo. While functionally correct, memoizing it would align with the aggressive memoization pattern used throughout this component.

Suggested change
- const assetFlowDirection = action === 'exit' ? 'exit' : 'enter'
+ const assetFlowDirection = useMemo(
+   () => (action === 'exit' ? 'exit' : 'enter'),
+   [action],
+ )

340-343: Unnecessary null check on vaultMetadata.

vaultMetadata is always defined due to the fallback on line 110 ({ name: 'Vault', logoURI: yieldItem.metadata.logoURI }), making the ternary check redundant.

Suggested simplification
  const successProviderInfo = useMemo(
-   () => (vaultMetadata ? { name: vaultMetadata.name, logoURI: vaultMetadata.logoURI } : null),
+   () => ({ name: vaultMetadata.name, logoURI: vaultMetadata.logoURI }),
    [vaultMetadata],
  )
src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx (1)

98-99: Consider explicit undefined handling for market data.

The || {} fallback after destructuring could silently mask cases where market data is genuinely unavailable. The price will be undefined in both missing data and fallback scenarios, but the fallback pattern obscures the source.

This is minor since the downstream code handles undefined correctly.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 473b6a5 and 0d73b26.

📒 Files selected for processing (2)
  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

**/*.{tsx,jsx}: ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging
ALWAYS use useErrorToast hook for displaying errors with translated error messages and handle different error types appropriately

Use PascalCase for React component names and match the component name to the file name

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{jsx,tsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless absolutely necessary, and ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components; NEVER use default exports for components
KEEP component files under 200 lines when possible; BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly in async operations
ALWAYS provide user-friendly error messages in error handling
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components using React.lazy for code splitting
ALWAYS use Suspense wrapper for lazy loaded components
USE local state for component-level state; LIFT state up when needed across multiple components; USE Context for avoiding prop drilling; USE Redux only for global state shared across multiple places
Wrap components receiving props with memo for performance optimization

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

Ensure TypeScript types are explicit and proper; avoid use of any type

Files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
🧠 Learnings (32)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR `#10418` for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: To add a new feature flag: (1) Add to `FeatureFlags` type in `src/state/slices/preferencesSlice/preferencesSlice.ts`, (2) Add environment variable validation in `src/config.ts`, (3) Add to initial state in `preferencesSlice.ts`, (4) Add to test mock in `src/test/mocks/store.ts`, (5) Set appropriate values in `.env`, `.env.development`, and `.env.production`
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-08T11:41:36.971Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:88-109
Timestamp: 2025-08-08T11:41:36.971Z
Learning: In MultiHopTrade Confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx), the Confirm route does not remount; navigating away goes to the swapper input page. Therefore, persistent deduplication across remounts for quote tracking is unnecessary; a ref-based single-mount dedupe is sufficient.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
📚 Learning: 2025-08-08T11:40:55.734Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx:41-41
Timestamp: 2025-08-08T11:40:55.734Z
Learning: In MultiHopTrade confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx and related hooks), there is only one active trade per flow. Because of this, persistent (module/Redux) dedupe for QuotesReceived in useTrackTradeQuotes is not necessary; the existing ref-based dedupe is acceptable.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
📚 Learning: 2025-09-12T11:52:39.280Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:18-21
Timestamp: 2025-09-12T11:52:39.280Z
Learning: In WalletConnect dApps integration, gomesalexandre has implemented intentional routing logic where EIP155TransactionConfirmation is typed for EthSignTransactionCallRequest only, while a separate SendTransactionConfirmation component handles EthSendTransactionCallRequest. The WalletConnectModalManager contains conditional logic to route native send transactions to SendTransactionConfirmation and other transaction types to EIP155TransactionConfirmation, creating a clean separation of concerns between signing and sending flows.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
📚 Learning: 2025-08-08T15:00:49.887Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-19T16:59:50.569Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11012
File: src/context/WalletProvider/Vultisig/components/Connect.tsx:24-59
Timestamp: 2025-11-19T16:59:50.569Z
Learning: In src/context/WalletProvider/*/components/Connect.tsx files across the ShapeShift web codebase, the established pattern for handling null/undefined adapter from getAdapter() is to simply check `if (adapter) { ... }` without an else clause. All wallet Connect components (Coinbase, Keplr, Phantom, Ledger, MetaMask, WalletConnectV2, KeepKey, Vultisig) follow this pattern—they reset loading state after the if block but do not show error messages when adapter is null. This is an intentional design decision and should be maintained for consistency.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-12-27T16:02:52.792Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11536
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx:252-265
Timestamp: 2025-12-27T16:02:52.792Z
Learning: When reviewing bug fixes, especially in shapeshift/web, prefer minimal changes that fix correctness over introducing broader refactors or quality-of-life improvements (e.g., extracting duplicated logic) unless such improvements are essential to the fix. Apply this guideline broadly to TSX files and related components, not just the specific location, to keep changes focused and maintainable.

Applied to files:

  • src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx
  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-22T12:59:01.210Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:26-29
Timestamp: 2025-08-22T12:59:01.210Z
Learning: In src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx, NeOMakinG declined wrapping the RewardDistributionActionCard component with React.memo, saying it was "too much", suggesting that like other action center components, memoization is not beneficial for this specific use case.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-10-17T07:51:58.374Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10783
File: src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx:344-349
Timestamp: 2025-10-17T07:51:58.374Z
Learning: In the shapeshift/web codebase, Chakra UI's ModalContent component supports the containerProps prop. When using the useModalRegistration hook from ModalStackProvider, spreading {...modalContentProps} directly onto ModalContent is correct and properly applies z-index and pointer-events through containerProps.sx. Do not suggest extracting sx from modalContentProps.containerProps.sx.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-25T12:59:43.842Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/Fox/components/RFOXSection.tsx:234-248
Timestamp: 2025-08-25T12:59:43.842Z
Learning: NeOMakinG considers suggestions to refactor working modal state management from useState to useDisclosure as too nitpicky, preferring to keep such cosmetic code improvements out of feature PRs unless they address actual issues.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-10-21T17:11:18.087Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10871
File: src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx:426-428
Timestamp: 2025-10-21T17:11:18.087Z
Learning: In src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, within the handleInputChange function, use .toFixed() without arguments (not .toString()) when converting BigNumber amounts for input field synchronization. This avoids exponential notation in the input while preserving precision for presentational components like <Amount.Crypto /> and <Amount.Fiat /> to format appropriately.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-08T14:59:40.422Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/pages/Explore/ExploreCategory.tsx:231-238
Timestamp: 2025-08-08T14:59:40.422Z
Learning: In src/pages/Explore/ExploreCategory.tsx, for the PageHeader filter trigger, NeOMakinG considers changing a clickable Chakra Icon to IconButton too nitpicky for this PR and prefers to keep the current Icon-based trigger; such minor a11y/UI nitpicks should be deferred to a follow-up if needed.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use Chakra UI components and conventions

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-10-07T03:44:27.350Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10760
File: src/components/ManageHiddenAssets/ManageHiddenAssetsList.tsx:78-84
Timestamp: 2025-10-07T03:44:27.350Z
Learning: In the ShapeShift web codebase, the following are stable references and do not need to be included in useCallback/useMemo dependency arrays:
- `navigate` from `useBrowserRouter()` hook
- Modal control objects (like `walletDrawer`) from `useModal()` hook (including their `isOpen`, `close`, and `open` methods)
- These are backed by stable context providers

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : EXTRACT complex logic into custom hooks

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : For static JSX icon elements (e.g., `<TbCopy />`) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : USE local state for component-level state; LIFT state up when needed across multiple components; USE Context for avoiding prop drilling; USE Redux only for global state shared across multiple places

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : ALWAYS use `useMemo` for conditional values and simple transformations

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-09-16T09:32:21.333Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10490
File: src/components/Layout/Header/NavBar/NavigationDropdown.tsx:96-103
Timestamp: 2025-09-16T09:32:21.333Z
Learning: In the shapeshift/web codebase, gomesalexandre confirms that using `item.icon && <Icon as={item.icon} boxSize={4} />` for Chakra UI MenuItem.icon prop is valid and acceptable - the boolean short-circuit pattern works fine with Chakra components and doesn't need to be changed to explicit undefined.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use `useAppSelector` for Redux state

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/state/slices/**/*.ts : Export selectors from slice using inline `selectors` property

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-10-17T07:53:40.088Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10783
File: src/components/Modals/Snaps/Snaps.tsx:36-38
Timestamp: 2025-10-17T07:53:40.088Z
Learning: Chakra UI's ModalContent component supports the containerProps prop, which accepts an object with sx and other styling properties. When using the modal stack manager's useModalRegistration hook, spreading {...modalContentProps} into ModalContent is the correct approach, as modalContentProps contains { containerProps: { sx: { zIndex, pointerEvents } } }. Do not suggest extracting sx from modalContentProps.containerProps.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Account for light/dark mode using `useColorModeValue` hook

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-14T17:54:32.563Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx:97-108
Timestamp: 2025-08-14T17:54:32.563Z
Learning: In ReusableLpStatus component (src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx), the txAssets dependency is stable from first render because poolAsset, baseAsset, actionSide, and action are all defined first render, making the current txAssetsStatuses initialization pattern safe without needing useEffect synchronization.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-06T09:47:29.865Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/Explore.tsx:174-178
Timestamp: 2025-08-06T09:47:29.865Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG prefers keeping complex height calculations inline rather than extracting them to useMemo, prioritizing perceived performance/execution speed over code readability, even when the calculation would only run when the dependency (isSearching) changes.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-08-22T12:59:01.702Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:37-53
Timestamp: 2025-08-22T12:59:01.702Z
Learning: In RewardDistributionActionCard component (src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx), NeOMakinG confirmed that runeAsset is expected to always be defined when the component renders, so defensive guards against undefined runeAsset are not needed.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2025-09-04T17:29:59.479Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx:28-33
Timestamp: 2025-09-04T17:29:59.479Z
Learning: In shapeshift/web, the useGetPopularAssetsQuery function in src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx intentionally uses primaryAssets[assetId] instead of falling back to assets[assetId]. The design distributes primary assets across chains by iterating through their related assets and adding the primary asset to each related asset's chain. This ensures primary assets appear in all chains where they have related assets, supporting the grouped asset system.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
📚 Learning: 2026-01-15T09:59:33.508Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11656
File: src/pages/Yields/components/YieldsList.tsx:1028-1046
Timestamp: 2026-01-15T09:59:33.508Z
Learning: In the Yields UI components (src/pages/Yields/components), do not render an in-app mobile filter UI due to limited screen space. Users on mobile should access filtered views via URL query parameters instead. This pattern applies to similar Yields UI components in the same directory; ensure the mobile UI remains navigable through URL parameters (e.g., ?filters=...), and document this behavior for consistency across the Yields-related components.

Applied to files:

  • src/pages/Yields/components/YieldActionModal.tsx
🧬 Code graph analysis (2)
src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx (11)
src/state/store.ts (1)
  • useAppSelector (145-145)
src/state/slices/tradeEarnInputSlice/selectors.ts (1)
  • selectSelectedYieldId (33-36)
src/lib/yieldxyz/constants.ts (1)
  • DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID (91-93)
src/pages/Yields/hooks/useYieldTransactionFlow.ts (1)
  • useYieldTransactionFlow (152-843)
src/lib/yieldxyz/utils.ts (1)
  • getTransactionButtonText (54-75)
src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx (1)
  • SharedConfirm (23-58)
src/pages/Yields/components/YieldSuccess.tsx (1)
  • YieldSuccess (28-139)
src/pages/Yields/components/YieldAssetFlow.tsx (1)
  • YieldAssetFlow (13-76)
src/components/Amount/Amount.tsx (1)
  • Amount (21-42)
src/pages/Yields/components/GradientApy.tsx (1)
  • GradientApy (9-20)
src/pages/Yields/components/TransactionStepsList.tsx (1)
  • TransactionStepsList (40-113)
src/pages/Yields/components/YieldActionModal.tsx (11)
src/lib/yieldxyz/utils.ts (1)
  • getTransactionButtonText (54-75)
src/pages/Yields/components/YieldAssetFlow.tsx (1)
  • YieldAssetFlow (13-76)
src/components/Text/Text.tsx (1)
  • Text (19-83)
src/components/Amount/Amount.tsx (1)
  • Amount (21-42)
src/pages/Yields/components/GradientApy.tsx (1)
  • GradientApy (9-20)
src/pages/Yields/components/TransactionStepsList.tsx (1)
  • TransactionStepsList (40-113)
src/pages/Yields/components/YieldSuccess.tsx (1)
  • YieldSuccess (28-139)
src/components/Modal/components/Dialog.tsx (1)
  • Dialog (150-150)
src/components/Modal/components/DialogHeader.tsx (1)
  • DialogHeader (15-48)
src/components/Modal/components/DialogCloseButton.tsx (1)
  • DialogCloseButton (15-41)
src/components/Modal/components/DialogFooter.tsx (1)
  • DialogFooter (9-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call / Static
🔇 Additional comments (7)
src/pages/Yields/components/YieldActionModal.tsx (2)

371-390: Dialog structure and state management look solid.

The Dialog structure properly handles:

  • Preventing overlay close during submission
  • Disabling close button while submitting
  • Conditional rendering based on modal step

410-425: Duplicate close button in success state.

The YieldSuccess component (rendered via successContent on line 389) already includes a close button that calls onDone (which is handleClose). This DialogFooter renders a second close button, resulting in duplicate close buttons in the success UI.

This contradicts PR objective #11650: "Remove duplicate close buttons in success UI flows."

Suggested fix: Remove the duplicate footer
      {isInProgress && (
        <DialogFooter borderTop='1px solid' borderColor='border.base' pt={4} pb={4}>
          <Button
            colorScheme='blue'
            size='lg'
            width='full'
            height='56px'
            fontSize='lg'
            fontWeight='semibold'
            borderRadius='xl'
            isDisabled={isButtonDisabled}
            isLoading={isButtonLoading}
            loadingText={loadingText}
            onClick={handleConfirm}
          >
            {buttonText}
          </Button>
        </DialogFooter>
      )}
-     {isSuccess && (
-       <DialogFooter borderTop='1px solid' borderColor='border.base' pt={4} pb={4}>
-         <Button
-           colorScheme='blue'
-           size='lg'
-           width='full'
-           height='56px'
-           fontSize='lg'
-           fontWeight='semibold'
-           borderRadius='xl'
-           onClick={handleClose}
-         >
-           {translate('common.close')}
-         </Button>
-       </DialogFooter>
-     )}
    </Dialog>
⛔ Skipped due to learnings
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Modal/components/DialogCloseButton.tsx:29-37
Timestamp: 2025-08-27T09:47:59.394Z
Learning: In shapeshift/web, for DialogCloseButton.tsx, the onClick handler must remain on Drawer.Close (not moved to IconButton with asChild) because stopPropagation() needs to be called at the Drawer.Close level to properly handle drawer closing behavior; moving event handling to the child IconButton would break the event flow that Drawer.Close expects.
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10361
File: src/pages/Markets/components/CardWithSparkline.tsx:83-92
Timestamp: 2025-08-25T23:32:13.876Z
Learning: In shapeshift/web PR `#10361`, premiumjibles considered the nested button accessibility issue (ChartErrorFallback retry Button inside Card rendered as Button in CardWithSparkline.tsx) out of scope for the error boundaries feature PR, consistent with deferring minor a11y improvements to follow-up PRs.
src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx (5)

77-92: Well-structured validator selection with appropriate fallback chain.

The logic correctly prioritizes: default validator by chain → preferred validator → first available validator. Dependencies are complete.


145-170: Loading states and button text logic are well-implemented.

The alignment with YieldEnterModal patterns and the comprehensive fallback chain for confirmButtonText provide consistent UX. The stepsToShow pattern correctly switches between displaySteps (pre-execution) and transactionSteps (during execution).


326-338: Footer implementation follows established patterns.

The button correctly combines:

  • isLoading for spinner during submission or quote fetching
  • isDisabled when submission isn't possible or data is loading
  • Dynamic confirmButtonText based on current transaction step

65-69: The selector usage is correct. The pattern selectAccountIdByAccountNumberAndChainId(state)[0]?.[yieldChainId] properly accesses account number 0's mapping by chain ID, matching the selector's return type of PartialRecord<number, PartialRecord<ChainId, AccountId>>. This consistent usage across the codebase confirms the implementation is sound.


35-35: The type assertion {} as AugmentedYieldDto is safe in this context. When selectedYield is undefined, the empty object is passed with isOpen: Boolean(selectedYield) set to false. The hook's useQuery is gated with enabled: ... && isOpen (line 273 of useYieldTransactionFlow), which prevents any API calls or property access on the empty object when the guard is false. Refactoring to pass undefined and making yieldItem optional would require conditional logic that violates React's Rules of Hooks. This pattern is intentional and correct.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

gomesalexandre and others added 4 commits January 15, 2026 11:48
- Fix YieldSelector modal to show ShapeShift DAO for Cosmos native staking
- Add earningsPerYear interpolated translation for proper i18n support
- Fix rewardsSchedule translation to include "every" (e.g., "every epoch")
- Add ShapeShift DAO fallback to YieldActionModal for consistency
- Remove redundant "Earn with" section from EarnFooter
- Clean up unused imports and props

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…bbitai

- YieldItem now fetches validators via react-query for staking yields
- Shows default/preferred validator name in modal (e.g., Luganodes for Solana)
- Validators are cached by react-query, so subsequent renders are instant

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…detail pages

- Add "Native Staking" title for all native staking yields (ATOM, SOL, etc.)
- Show ShapeShift DAO for Cosmos, Figment for Solana native staking
- Use provider info (from yieldProviders) for non-native staking yields
- Fix yield cards showing wrong provider name (e.g., "Stakekit" instead of "Morpho")
- Add titleOverride prop to YieldHero and YieldItem for consistent naming
- Add Figment validator constants for Solana

@coderabbitai - Addressed your comments: polling completion now properly handles
undefined tx (returns false instead of true), and display info now correctly
uses yieldProviders for non-native-staking yields.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use selectHasUserEnteredAmount from base selectors instead of maintaining
a duplicate wrapper selector that performs identical logic.

@coderabbitai - Addressed your comment about duplicate selector.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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: 2

🤖 Fix all issues with AI agents
In `@src/pages/Yields/YieldDetail.tsx`:
- Line 25: The file defines a duplicate constant SHAPESHIFT_VALIDATOR_NAME;
remove the local const and import the existing exported
SHAPESHIFT_VALIDATOR_NAME from '@/lib/yieldxyz/constants.ts' instead (update
YieldDetail.tsx imports and remove the local declaration), ensuring all
references in YieldDetail.tsx use the imported symbol to maintain a single
source of truth.
♻️ Duplicate comments (2)
src/pages/Yields/YieldDetail.tsx (1)

122-131: Rename usd key to reflect user currency denomination.

The value at line 128 is calculated in user currency (totalUsd.times(userCurrencyToUsdRate)), but the return key usd is misleading. Rename it to userCurrency to accurately reflect the denomination.

🔧 Suggested fix
     return {
-      usd: totalUsd.times(userCurrencyToUsdRate).toFixed(),
+      userCurrency: totalUsd.times(userCurrencyToUsdRate).toFixed(),
       crypto: totalCrypto.toFixed(),
     }
-  }, [balances, selectedValidatorAddress, userCurrencyToUsdRate])
+  }, [balances, selectedValidatorAddress, userCurrencyToUsdRate])

Then update the usage at line 185:

-          userBalanceUsd={userBalances.usd}
+          userBalanceUsd={userBalances.userCurrency}
src/components/MultiHopTrade/components/Earn/EarnConfirm.tsx (1)

186-200: Remove unused isLoading prop from SharedConfirm calls.

The isLoading prop is passed to SharedConfirm in multiple places (lines 196, 219, 347) but was flagged in a previous review as unused in the SharedConfirm component implementation.

Also applies to: 219-219, 344-350

🧹 Nitpick comments (14)
src/pages/Yields/components/YieldActionModal.tsx (2)

60-89: Consider destructuring manageActionType and accountId directly.

The rest spread ...props only contains manageActionType and accountId, which are then accessed via props.manageActionType and props.accountId. Destructuring them directly would be cleaner and more explicit.

♻️ Suggested refactor
   validatorLogoURI,
   passthrough,
-  ...props
-}: YieldActionModalProps) {
+  manageActionType,
+  accountId,
+}: YieldActionModalProps) {
   const translate = useTranslate()

   const {
     ...
   } = useYieldTransactionFlow({
     ...
-    manageActionType: props.manageActionType,
-    accountId: props.accountId,
+    manageActionType,
+    accountId,
   })

348-351: Redundant null check on vaultMetadata.

The vaultMetadata useMemo (lines 107-119) always returns an object - it never returns null or undefined. The conditional check is unnecessary.

♻️ Suggested simplification
  const successProviderInfo = useMemo(
-   () => (vaultMetadata ? { name: vaultMetadata.name, logoURI: vaultMetadata.logoURI } : null),
+   () => ({ name: vaultMetadata.name, logoURI: vaultMetadata.logoURI }),
    [vaultMetadata],
  )
src/pages/Yields/YieldAssetDetails.tsx (1)

447-456: The eslint-disable comment is justified but could be more specific.

The comment explains that sortedRows is needed to trigger re-memoization when filtered data changes since the table ref is stable. This is a valid reason to include it in the dependency array despite eslint's warning.

However, consider if filteredYields would be a more direct dependency since that's what actually changes.

Consider using filteredYields instead
   const listViewElement = useMemo(
     () => (
       <Box borderWidth='1px' borderRadius='xl' overflow='hidden'>
         <YieldTable table={table} isLoading={false} onRowClick={handleRowClick} />
       </Box>
     ),
-    // sortedRows needed to trigger re-memoization when filtered data changes (table ref is stable)
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-    [handleRowClick, sortedRows, table],
+    [handleRowClick, filteredYields, table],
   )
src/pages/Yields/components/YieldsList.tsx (2)

156-189: getYieldDisplayInfo helper is duplicated from YieldAssetDetails.tsx.

This helper function has identical logic to the one in YieldAssetDetails.tsx. Consider extracting it to a shared utility to avoid duplication and ensure consistent behavior.

Consider extracting to a shared utility

Create a shared utility in src/pages/Yields/utils/getYieldDisplayInfo.ts:

import type { AugmentedYieldDto } from '@/lib/yieldxyz/types'
import {
  COSMOS_ATOM_NATIVE_STAKING_YIELD_ID,
  FIGMENT_VALIDATOR_LOGO,
  FIGMENT_VALIDATOR_NAME,
  SHAPESHIFT_VALIDATOR_LOGO,
  SHAPESHIFT_VALIDATOR_NAME,
  SOLANA_SOL_NATIVE_MULTIVALIDATOR_STAKING_YIELD_ID,
} from '@/lib/yieldxyz/constants'

export const getYieldDisplayInfo = (
  yieldItem: AugmentedYieldDto,
  yieldProviders: Record<string, { name?: string; logoURI?: string }> | undefined,
  translate: (key: string) => string,
) => {
  // ... shared logic
}

Then import and use in both components.


670-755: Consider extracting repeated YieldItem rendering logic.

The grid and list elements have very similar rendering patterns for both isMyOpportunities and regular views. While not blocking, extracting common rendering logic could reduce code duplication.

Based on learnings, this is a recommended refactor that can be deferred to a follow-up PR to keep the current scope focused.

Also applies to: 757-883

src/pages/Yields/components/YieldManager.tsx (3)

28-29: Unsafe type assertion for action parameter.

The cast as 'enter' | 'exit' | 'claim' | undefined doesn't validate the actual value. If the URL contains an unexpected value (e.g., ?action=invalid), it will pass through as-is and may cause unexpected behavior downstream in YieldForm.

♻️ Suggested fix with validation
-  const action = searchParams.get('action') as 'enter' | 'exit' | 'claim' | undefined
+  const actionParam = searchParams.get('action')
+  const action = useMemo(() => {
+    const validActions = ['enter', 'exit', 'claim'] as const
+    return validActions.includes(actionParam as typeof validActions[number])
+      ? (actionParam as 'enter' | 'exit' | 'claim')
+      : undefined
+  }, [actionParam])

33-45: Fragile string pattern matching for Solana native staking detection.

The condition yieldId?.includes('solana') && yieldId?.includes('native') on line 38 is brittle and could match unintended yield IDs. Consider using a more explicit check or a dedicated constant/utility.

♻️ Suggested improvement
+const SOLANA_NATIVE_YIELD_ID_PATTERN = /^solana-.*-native/
+
 const validatorAddress = useMemo(() => {
   // For native staking with hardcoded defaults, always use the default validator (ignore URL param)
   if (
     yieldId === COSMOS_ATOM_NATIVE_STAKING_YIELD_ID ||
-    yieldId === SOLANA_SOL_NATIVE_MULTIVALIDATOR_STAKING_YIELD_ID ||
-    (yieldId?.includes('solana') && yieldId?.includes('native'))
+    (yieldId && SOLANA_NATIVE_YIELD_ID_PATTERN.test(yieldId))
   ) {
     return yieldItem?.chainId
       ? DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[yieldItem.chainId]
       : undefined
   }
   return validatorParam
 }, [yieldId, yieldItem?.chainId, validatorParam])

73-96: Inline arrow functions create new references on every render.

The onClose and onClick handlers create new function instances on each render. While the Dialog component may not be performance-critical, memoizing these callbacks aligns with project guidelines and prevents unnecessary re-renders of child components.

♻️ Suggested improvement
+  const handleClose = useCallback(() => navigate(-1), [navigate])
+
   return (
-    <Dialog isOpen={true} onClose={() => navigate(-1)} isFullScreen>
+    <Dialog isOpen={true} onClose={handleClose} isFullScreen>
       <DialogHeader>
         <DialogHeader.Left>{null}</DialogHeader.Left>
         <DialogHeader.Middle>
           <DialogTitle>{title}</DialogTitle>
         </DialogHeader.Middle>
         <DialogHeader.Right>
-          <DialogCloseButton onClick={() => navigate(-1)} />
+          <DialogCloseButton onClick={handleClose} />
         </DialogHeader.Right>
       </DialogHeader>
       <DialogBody py={0} px={4} flex={1}>
         <YieldForm
           yieldItem={yieldItem}
           balances={balances}
           action={action ?? 'enter'}
           validatorAddress={validatorAddress}
           accountNumber={accountNumber}
-          onClose={() => navigate(-1)}
-          onDone={() => navigate(-1)}
+          onClose={handleClose}
+          onDone={handleClose}
         />
       </DialogBody>
     </Dialog>
   )
src/lib/yieldxyz/constants.ts (1)

64-66: Inconsistent APR constant types and values.

COSMOS_SHAPESHIFT_FALLBACK_APR is a string '0.1425' (14.25%), while the new COSMOS_NETWORK_FALLBACK_APR is a number 0.15 (15%). The different types and values could cause confusion when choosing which constant to use. Consider documenting the intended use case for each or consolidating them.

src/pages/Yields/components/YieldStats.tsx (1)

50-60: Duplicate validator selection logic across components.

This native staking validator selection logic is duplicated in YieldManager.tsx (lines 35-44) and YieldDetail.tsx (lines 45-55). Consider extracting this into a shared utility function or custom hook to ensure consistency and reduce maintenance burden.

♻️ Suggested extraction to a shared utility

Create a utility in src/lib/yieldxyz/utils.ts:

export const getEffectiveValidatorAddress = (
  yieldId: string | undefined,
  chainId: ChainId | undefined,
  validatorParam: string | null | undefined,
  defaultValidator: string | undefined,
): string | undefined => {
  if (
    yieldId === COSMOS_ATOM_NATIVE_STAKING_YIELD_ID ||
    yieldId === SOLANA_SOL_NATIVE_MULTIVALIDATOR_STAKING_YIELD_ID ||
    (yieldId?.includes('solana') && yieldId?.includes('native'))
  ) {
    return chainId ? DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[chainId] : undefined
  }
  return validatorParam ?? defaultValidator
}
src/components/MultiHopTrade/components/Earn/components/YieldSelector.tsx (2)

49-50: Consolidate similar type-checking helpers.

isNativeStaking (line 49) and isStakingType (line 156) have overlapping logic but different definitions. This could lead to inconsistent behavior. Consider consolidating into a single helper or clearly documenting their different purposes.

♻️ Suggested consolidation
-const isNativeStaking = (type: string | undefined): boolean =>
-  ['native-staking', 'staking'].includes(type ?? '')
-
-const isStakingType = (type: string | undefined): boolean =>
-  ['native-staking', 'pooled-staking', 'staking'].includes(type ?? '')
+const NATIVE_STAKING_TYPES = ['native-staking', 'staking'] as const
+const ALL_STAKING_TYPES = ['native-staking', 'pooled-staking', 'staking'] as const
+
+const isNativeStaking = (type: string | undefined): boolean =>
+  NATIVE_STAKING_TYPES.includes(type as typeof NATIVE_STAKING_TYPES[number])
+
+const isStakingType = (type: string | undefined): boolean =>
+  ALL_STAKING_TYPES.includes(type as typeof ALL_STAKING_TYPES[number])

Also applies to: 156-157


140-141: Extract hardcoded fallback image URLs to constants.

The fallback image URL 'https://assets.coingecko.com/coins/images/279/small/ethereum.png' is duplicated on lines 140 and 273. Extract this to a constant for maintainability.

♻️ Suggested fix
+const FALLBACK_TOKEN_IMAGE = 'https://assets.coingecko.com/coins/images/279/small/ethereum.png'
+
 // In YieldItem component:
 <Image
   src={displayInfo.logoURI}
   alt={displayInfo.name}
   boxSize='40px'
   borderRadius='full'
-  fallbackSrc='https://assets.coingecko.com/coins/images/279/small/ethereum.png'
+  fallbackSrc={FALLBACK_TOKEN_IMAGE}
 />

 // In YieldSelector component:
 <Image
   src={selectedDisplayInfo.logoURI}
   alt={selectedDisplayInfo.name}
   boxSize='32px'
   borderRadius='full'
-  fallbackSrc='https://assets.coingecko.com/coins/images/279/small/ethereum.png'
+  fallbackSrc={FALLBACK_TOKEN_IMAGE}
 />

Also applies to: 273-274

src/components/MultiHopTrade/components/Earn/components/EarnFooter.tsx (1)

33-39: Type mismatch: statsBoxSx is typed as FlexProps but applied to a Box component.

The statsBoxSx constant is typed as FlexProps but is spread onto a Box component (line 196). This should be typed as BoxProps for correctness.

Suggested fix
-const statsBoxSx: FlexProps = {
+const statsBoxSx = {
   bg: 'background.surface.raised.base',
   borderRadius: 'lg',
   p: 3,
   borderWidth: '1px',
   borderColor: 'border.base',
 }
src/components/MultiHopTrade/components/Earn/EarnInput.tsx (1)

242-250: Consider logging JSON parse failures for debugging.

The catch block silently swallows parse errors when extracting gas data. Adding a console.error would help debug issues with malformed gasEstimate data.

Suggested fix
       try {
         const gasData = JSON.parse(tx.gasEstimate)
         return acc.plus(bnOrZero(gasData.amount))
       } catch {
+        console.error('Failed to parse gasEstimate:', tx.gasEstimate)
         return acc
       }

gomesalexandre and others added 4 commits January 15, 2026 12:47
- Remove unused isLoading prop from SharedConfirm component and call sites
- Use relative path 'confirm' for EarnRoutePaths.Confirm (matches TradeRoutePaths pattern)
- Import SHAPESHIFT_VALIDATOR_NAME from constants instead of duplicating
- Rename userBalances.usd to userBalances.userCurrency for clarity

@coderabbitai - Addressed remaining review comments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace fragile string parsing on metadata.name with useYieldProviders() hook
to properly map providerId to provider data. Also add Figment validator
fallback for Solana native staking.

@coderabbitai - Addressed comment about using providerId with provider mapping.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use availableBalanceUserCurrency instead of userBalanceUsd for recommended
  yields (user has no position yet, only wallet balance to stake)
- Use input token symbol (ETH) instead of output token symbol (stETH) for
  title consistency across all yield cards

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…from" to "Enter from"

- Convert YieldSelector from Chakra Modal to Dialog pattern for responsive behavior (drawer on mobile, modal on desktop)
- Change sell asset dialog title from "Trade from" to "Enter from" in Earn tab
- Add "earn.enterFrom" translation key

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.

Review Summary

3 maybe blocking blocking, 8 suggestions, 4 nitpicks

Big PR consolidating yield improvements. Behind feature flags so safe to ship, but worth addressing these before enabling.

Blocking Issues

  1. Missing Error Boundary on EarnTab (TradeTab has TradingErrorBoundary)
  2. Unsafe type assertion {} as AugmentedYieldDto in EarnConfirm
  3. Custom poll function without cancellation support (potential memory leak)

Key Suggestions

  • Duplicate selector selectEarnHasUserEnteredAmount - use existing selectHasUserEnteredAmount
  • SHAPESHIFT_VALIDATOR_NAME duplicated in 3 files - import from constants.ts
  • useEffect syncing state in useYieldFilters - could use useMemo instead
  • Manual base unit conversion - use toBaseUnit from @/lib/math
  • Several accessibility improvements needed on clickable elements

Nitpicks

  • Magic numbers should be constants (debounce 500ms, etc.)
  • Initial state inconsistency ('' vs '0' for sellAmountCryptoPrecision)

Runtime test:

https://jam.dev/c/2c3d22ee-4d13-44bf-95b3-a46208775f56

  • Can't deposit SOL into kamino and another provider with "cannot get quote" error, one worked thought
  • Withdrawing atom from a position but closing the modal is changing the action center element to "success" but the page isn't getting balances/status updates
  • The position detail page is weird on desktop, all centered, it's not desktop friendly but looks more like a mobile layout
  • Global "earn" view is not kept between navigations, this means if a user is staking some assets then coming page to this page he is going to be forced to click on "earn" again
  • Provider selection on the swapper route earn tab should use a drawer instead of a modal (see mobile testing at 4:35) in the screen record)
  • I've ended up in a state where the "deposit" button was under the menu bar, we need to add the menu height safe area at the bottom of this view because it's preventing me from depositing

Happy to stamp for the sake of progression, but we need to tackle those few bugs if its not done after this review already considering the current state 🙏

- Add TradingErrorBoundary to EarnTab for error handling
- Make useYieldTransactionFlow accept undefined yieldItem (removes unsafe {} as cast)
- Consolidate duplicate handleBack/handleClose in EarnConfirm
- Extract debounce magic number to SELL_AMOUNT_DEBOUNCE_MS constant
- Inline chainIdFilterPredicate in modal open call
- Restore isLoading optional prop in SharedConfirmProps for backwards compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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: 5

🤖 Fix all issues with AI agents
In `@src/components/MultiHopTrade/components/Earn/components/YieldSelector.tsx`:
- Around line 133-139: The Image components in YieldSelector (the JSX Image
element rendering displayInfo.logoURI with fallbackSrc set to a CoinGecko URL)
should use a first‑party/local fallback asset instead of the external CoinGecko
URL; import a local fallback icon (e.g., assets/images/token-fallback.png or
assets/icons/ethereum.png) at the top of the file and replace
fallbackSrc='https://assets.coingecko.com/coins/images/279/small/ethereum.png'
with fallbackSrc={tokenFallbackIcon}, and make the same change for the other
Image occurrence in this file so both fallback paths use the bundled asset.

In `@src/components/MultiHopTrade/components/Earn/EarnInput.tsx`:
- Around line 133-140: The path builder in the useEffect of EarnInput.tsx
currently encodes selectedYieldId but not sellAsset.assetId, so CAIP-19 assetIds
with “/” will break routing; update the navigate call in the useEffect (the code
that constructs `/earn/${sellAsset.assetId}/${encodedYieldId}/${baseUnit}`) to
encode the asset id as well (e.g. use encodeURIComponent on sellAsset.assetId)
so both path segments are URL-safe before calling navigate.
- Around line 431-438: The placeholder for SellAssetInput is hardcoded to
'$0.00' when isInputtingFiatSellAmount is true; change it to be currency-aware
or fall back to a neutral '0'. Update the placeholder prop on SellAssetInput
(the conditional using isInputtingFiatSellAmount) to use the user's fiat
currency formatter (e.g., formatCurrency(userCurrency, 0) or a locale-aware
Intl.NumberFormat call) or simply return '0' instead of the hardcoded USD string
so the UI reflects the correct currency.
- Around line 191-213: The txArguments memo can include validatorAddress:
undefined when the yield mechanics require it; update the useMemo for
txArguments so that when fieldNames.has('validatorAddress') you resolve const
validator = selectedValidatorAddress ??
DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[yieldChainId] and if validator is falsy
return null (or otherwise abort building args) instead of assigning undefined,
otherwise assign args.validatorAddress = validator; keep the rest of the
argument logic intact and ensure the dependency list still includes
selectedValidatorAddress and yieldChainId.
- Around line 121-129: In the useEffect inside EarnInput (the block that
computes amountCryptoPrecision using bnOrZero(...).div(...).toString()), replace
the final .toString() call with .toFixed() so the computed amountCryptoPrecision
string never uses exponential notation; update the expression in the effect that
assigns amountCryptoPrecision and keep the rest of the dispatch call to
tradeEarnInput.actions.setSellAmountCryptoPrecision unchanged.
🧹 Nitpick comments (4)
src/pages/Yields/components/YieldsList.tsx (1)

168-177: Broad string matching may catch unintended yields.

The condition yieldItem.id.includes('solana') && yieldItem.id.includes('native') could match future yields that contain both substrings but aren't the Figment multivalidator staking yield. Consider using a more specific check or adding this ID to the constants if it's a known pattern.

src/pages/Yields/YieldDetail.tsx (2)

95-123: Consider combining reduce operations for cleaner code.

The balance aggregation iterates over the same array twice (lines 107-112 and 114-117). For a 4-element array, the performance impact is negligible, but combining into a single reduce would be slightly cleaner:

♻️ Optional refactor
-    const totalCrypto = [
-      activeBalance,
-      enteringBalance,
-      exitingBalance,
-      withdrawableBalance,
-    ].reduce((sum, b) => sum.plus(bnOrZero(b?.aggregatedAmount)), bnOrZero(0))
-
-    const totalUsd = [activeBalance, enteringBalance, exitingBalance, withdrawableBalance].reduce(
-      (sum, b) => sum.plus(bnOrZero(b?.aggregatedAmountUsd)),
-      bnOrZero(0),
-    )
+    const balanceArray = [activeBalance, enteringBalance, exitingBalance, withdrawableBalance]
+    const { totalCrypto, totalUsd } = balanceArray.reduce(
+      (acc, b) => ({
+        totalCrypto: acc.totalCrypto.plus(bnOrZero(b?.aggregatedAmount)),
+        totalUsd: acc.totalUsd.plus(bnOrZero(b?.aggregatedAmountUsd)),
+      }),
+      { totalCrypto: bnOrZero(0), totalUsd: bnOrZero(0) },
+    )

48-58: The pattern is intentional and used consistently for extensibility.

The yieldId?.includes('solana') && yieldId?.includes('native') check in line 53 is a secondary guard that appears in five other locations across the Yields feature (YieldAssetDetails, YieldManager, YieldStats, YieldsList), always paired with the explicit SOLANA_SOL_NATIVE_MULTIVALIDATOR_STAKING_YIELD_ID check. Currently, only one Solana native staking yield ID exists ('solana-sol-native-multivalidator-staking'), so the pattern serves as future-proofing for additional Solana native staking variants while remaining specific enough to avoid false matches.

However, for maintainability, consider extracting this pattern into a helper function (e.g., isNativeSolanaStaking(yieldId)) to make the intent explicit and centralize the logic. This would also make future yield ID changes easier to track.

src/components/MultiHopTrade/components/Earn/components/YieldSelector.tsx (1)

93-117: Potential query fan-out: useYieldValidators() per YieldItem.
If a page can list many validator-required yields, this can trigger many validator fetches at once. Consider gating with dialog open state (or only fetching validators for the selected yield) if this shows up in profiling.

gomesalexandre and others added 2 commits January 15, 2026 13:30
- useYieldFilters: replace useState+useEffect with useMemo for sorting state
- useYieldTransactionFlow: use toBaseUnit from @/lib/math instead of manual conversion
- EarnInput: use fromBaseUnit from @/lib/math for base unit conversion
- tradeEarnInputSlice: fix initial state consistency ('' -> '0')
- YieldEnterModal/YieldForm: add accessibility attrs to fiat toggle (role, tabIndex, aria-label, keyboard support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove duplicate constant definition from YieldForm and YieldEnterModal,
import from @/lib/yieldxyz/constants instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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/pages/Yields/components/YieldEnterModal.tsx`:
- Around line 72-77: The type declaration CryptoAmountInputProps uses
React.ChangeEvent<HTMLInputElement> but the React namespace isn't imported; fix
by importing the appropriate symbol from React (either add "import React from
'react'" or import the specific type like "import { ChangeEvent } from 'react'")
and update CryptoAmountInputProps to use the imported type (e.g., onChange?: (e:
ChangeEvent<HTMLInputElement>) => void) so TypeScript compiles correctly.
♻️ Duplicate comments (1)
src/components/MultiHopTrade/components/Earn/EarnInput.tsx (1)

203-206: Potential undefined validatorAddress when field is required.

When fieldNames.has('validatorAddress') is true but neither selectedValidatorAddress nor DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[yieldChainId] exists (for chains other than Cosmos/Solana), args.validatorAddress will be undefined. This could cause API errors or unexpected behavior.

Proposed fix
       if (fieldNames.has('validatorAddress') && yieldChainId) {
-        args.validatorAddress =
-          selectedValidatorAddress || DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[yieldChainId]
+        const validatorAddress =
+          selectedValidatorAddress ?? DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID[yieldChainId]
+        if (!validatorAddress) return null
+        args.validatorAddress = validatorAddress
       }
🧹 Nitpick comments (4)
src/pages/Yields/components/YieldForm.tsx (1)

294-300: Consider using string literals for BigNumber multiplication.

Per project learnings, floating point literals should be passed as strings to BigNumber methods to maintain precision.

Suggested change
     const fiatAmount = useMemo(
-      () => bnOrZero(cryptoAmount).times(marketData?.price ?? 0),
+      () => bnOrZero(cryptoAmount).times(marketData?.price ?? '0'),
       [cryptoAmount, marketData?.price],
     )

Similar pattern applies to lines 303, 308.

src/pages/Yields/components/YieldEnterModal.tsx (2)

209-225: Consider using string literals for BigNumber operations.

Per project learnings, floating point literals should be passed as strings to maintain precision.

Suggested change
     const fiatAmount = useMemo(
-      () => bnOrZero(cryptoAmount).times(marketData?.price ?? 0),
+      () => bnOrZero(cryptoAmount).times(marketData?.price ?? '0'),
       [cryptoAmount, marketData?.price],
     )
     // Similar for estimatedYearlyEarningsFiat

46-105: Significant code duplication with YieldForm.tsx.

The CryptoAmountInputProps, CryptoAmountInput, YieldEnterModalSkeleton, INPUT_LENGTH_BREAKPOINTS, getInputFontSize, PRESET_PERCENTAGES, and SHAPESHIFT_VALIDATOR_NAME constants are duplicated between this file and YieldForm.tsx. Consider extracting these to a shared module to reduce maintenance burden.

This is a follow-up improvement that can be addressed separately from this PR to keep scope focused.

src/components/MultiHopTrade/components/Earn/EarnInput.tsx (1)

432-432: Minor: Hardcoded $0.00 placeholder for fiat input.

The $0.00 placeholder assumes USD. For non-USD user currencies, consider using a currency-aware formatter or a neutral '0' placeholder.

The yield.xyz API returns Solana transactions as base64-encoded strings
(following Solana conventions), but the code was trying to decode them
as hex, causing deserialization failures.

Use isHex from viem to detect encoding format - if hex use hex decoding,
otherwise use base64 (Solana convention).

Fixes "cannot get quote" error when depositing SOL into Kamino and
other Solana-based yield providers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gomesalexandre gomesalexandre force-pushed the feat_big_yield_consolidation_feat_polish_fixes branch from 013179d to 9e8f42c Compare January 15, 2026 12:50
gomesalexandre and others added 2 commits January 15, 2026 13:53
- Add SOLANA_YIELD_COMPUTE_UNIT_MARGIN_MULTIPLIER (1.6) constant
- Apply safety margin to estimated compute units (same as Jupiter swapper)
- Remove broken STAKE_COMPUTE_UNIT_BUFFER static minimum approach

Fixes "Computational budget exceeded" error when depositing SOL into
Kamino and other Solana yield providers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Display each exiting balance as separate row with completion date
- Use dayjs relative time for "available in X days" countdown
- Invalidate yield queries when transactions complete in background
- Add yieldXYZ.unstaking and yieldXYZ.availableDate translations
- Align unstaking/claimable sections consistently (badge top, action below)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gomesalexandre
Copy link
Contributor Author

Can't deposit SOL into kamino and another provider with "cannot get quote" error, one worked thought

gm https://jam.dev/c/cc0b92e2-098e-49a3-87c7-1cceff01ded0

Withdrawing atom from a position but closing the modal is changing the action center element to "success" but the page isn't getting balances/status updates

This one is expected since Cosmos SDK has a cooldown of sorts, balance will be the same, though unstaking should update, paranoia updated balances invalidation for claims here and confirmed worky. Also aligned visually with old DeFi opportunity:

  • Old Defi "abstraction"
image
  • Before
image
  • Now
image

https://jam.dev/c/a55f052b-6116-424d-8561-23c62a1fdc9b

The position detail page is weird on desktop, all centered, it's not desktop friendly but looks more like a mobile layout

Expected for now and will need some @reallybeard / @NeOMakinG goodness before - will let you guys know when in a good place to visually improve bits i.e v. v. soon

Global "earn" view is not kept between navigations, this means if a user is staking some assets then coming page to this page he is going to be forced to click on "earn" again

It's working if using back/forth browser nav which I believe is good enough for now!

https://jam.dev/c/288a661f-baed-4407-80bb-e7b80a53981b

I've ended up in a state where the "deposit" button was under the menu bar, we need to add the menu height safe area at the bottom of this view because it's preventing me from depositing

Ditto realm of neo-beard-y oil ⛽

Provider selection on the swapper route earn tab should use a drawer instead of a modal (see mobile testing at 4:35) in the screen record)

Already tackled! Great minds ser

image

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

🤖 Fix all issues with AI agents
In `@src/lib/yieldxyz/constants.ts`:
- Around line 58-61: Replace numeric JS floats used as exported constants with
string literals so downstream BigNumber math receives string inputs;
specifically change SOLANA_YIELD_COMPUTE_UNIT_MARGIN_MULTIPLIER and the other
APR/multiplier constants in this file (the constants around the 70-90 range)
from numeric values like 1.6 or 0.15 to string values like "1.6" or "0.15", and
ensure any usages that pass these into bnOrZero(...).times(...) or similar
BigNumber operations use the exported string constants directly.

In `@src/pages/Yields/components/YieldForm.tsx`:
- Around line 357-367: handleFormDone currently removes quote queries using the
wrong key variable (action) causing stale cache entries when
useYieldTransactionFlow maps actions to flowAction; update the removeQueries
call to use flowAction instead of action in the queryKey (['yieldxyz','quote',
flowAction, yieldItem.id]) and also add flowAction to the useCallback dependency
array so the closure invalidation is correct.
♻️ Duplicate comments (1)
src/pages/Yields/components/YieldEnterModal.tsx (1)

72-77: Fix TS type: React.ChangeEvent is referenced without importing React.
This will fail type-checking in builds that don’t have the React namespace types globally available.

Proposed fix
-import { memo, useCallback, useMemo, useState } from 'react'
+import type { ChangeEvent } from 'react'
+import { memo, useCallback, useMemo, useState } from 'react'
@@
 type CryptoAmountInputProps = {
   value?: string
-  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
+  onChange?: (e: ChangeEvent<HTMLInputElement>) => void
   placeholder?: string
   [key: string]: unknown
 }
🧹 Nitpick comments (2)
src/pages/Yields/components/YieldForm.tsx (1)

403-408: Remove the no-op useEffect block.
It currently doesn’t do anything and adds noise.

Proposed change
-    useEffect(() => {
-      if (step === ModalStep.Success) {
-        // Here we could auto-close or let YieldSuccess handle it
-      }
-    }, [step])
+    // (removed no-op effect)
src/lib/yieldxyz/constants.ts (1)

58-60: (Optional) Drop the new inline comments if not strictly needed.
Repo guidelines prefer avoiding new comments where the code can be self-documenting.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 10be817 and 8d8a8f0.

📒 Files selected for processing (7)
  • src/assets/translations/en/main.json
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/lib/yieldxyz/constants.ts
  • src/lib/yieldxyz/executeTransaction.ts
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
  • src/pages/Yields/components/YieldPositionCard.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

**/*.{tsx,jsx}: ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging
ALWAYS use useErrorToast hook for displaying errors with translated error messages and handle different error types appropriately

Use PascalCase for React component names and match the component name to the file name

Files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{jsx,tsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless absolutely necessary, and ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components; NEVER use default exports for components
KEEP component files under 200 lines when possible; BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly in async operations
ALWAYS provide user-friendly error messages in error handling
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components using React.lazy for code splitting
ALWAYS use Suspense wrapper for lazy loaded components
USE local state for component-level state; LIFT state up when needed across multiple components; USE Context for avoiding prop drilling; USE Redux only for global state shared across multiple places
Wrap components receiving props with memo for performance optimization

Files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

Ensure TypeScript types are explicit and proper; avoid use of any type

Files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
src/assets/translations/en/main.json

📄 CodeRabbit inference engine (CLAUDE.md)

Add English copy to src/assets/translations/en/main.json (find appropriate section)

Files:

  • src/assets/translations/en/main.json
🧠 Learnings (63)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR `#10418` for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • src/lib/yieldxyz/constants.ts
  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs

Applied to files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-05T23:36:13.214Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/state/slices/preferencesSlice/selectors.ts:21-25
Timestamp: 2025-08-05T23:36:13.214Z
Learning: The AssetId type from 'shapeshiftoss/caip' package is a string type alias, so it can be used directly as a return type for cache key resolvers in re-reselect selectors without needing explicit string conversion.

Applied to files:

  • src/lib/yieldxyz/constants.ts
📚 Learning: 2025-11-03T22:31:30.786Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts:0-0
Timestamp: 2025-11-03T22:31:30.786Z
Learning: In packages/swapper/src/swappers/PortalsSwapper, the rate and quote files intentionally use different approaches for calculating buyAmountBeforeSlippageCryptoBaseUnit: getPortalsTradeRate.tsx uses minOutputAmount / (1 - buffer) for conservative estimates, while getPortalsTradeQuote.ts uses outputAmount / (1 - buffer) for final quote display. This difference is validated by on-chain simulation testing and is intentional.

Applied to files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2026-01-08T23:17:05.494Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11578
File: src/pages/Yields/hooks/useYieldTransactionFlow.ts:183-185
Timestamp: 2026-01-08T23:17:05.494Z
Learning: In the Yield.xyz API integration (src/pages/Yields/hooks/useYieldTransactionFlow.ts), the cosmosPubKey argument field accepts the user's Cosmos address (userAddress), not the raw public key. This is the expected format for the Yield.xyz API endpoints (enterYield/exitYield/manageYield).

Applied to files:

  • src/lib/yieldxyz/constants.ts
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-22T12:59:01.210Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:26-29
Timestamp: 2025-08-22T12:59:01.210Z
Learning: In src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx, NeOMakinG declined wrapping the RewardDistributionActionCard component with React.memo, saying it was "too much", suggesting that like other action center components, memoization is not beneficial for this specific use case.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-10-13T11:55:57.439Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10751
File: src/Routes/RoutesCommon.tsx:190-190
Timestamp: 2025-10-13T11:55:57.439Z
Learning: In the shapeshift/web codebase, there are multiple independent claim systems: Arbitrum bridge claims (removed in PR `#10751`), RFOX claims (in src/pages/RFOX/components/Claim/), and TCY claims (in src/pages/TCY/). Each has its own routes, components, and logic. When reviewing claim-related changes, distinguish which system is being modified and avoid suggesting changes to unrelated claim systems.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-22T12:59:01.702Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:37-53
Timestamp: 2025-08-22T12:59:01.702Z
Learning: In RewardDistributionActionCard component (src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx), NeOMakinG confirmed that runeAsset is expected to always be defined when the component renders, so defensive guards against undefined runeAsset are not needed.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-08-25T23:32:13.876Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10361
File: src/pages/Markets/components/CardWithSparkline.tsx:83-92
Timestamp: 2025-08-25T23:32:13.876Z
Learning: In shapeshift/web PR `#10361`, premiumjibles considered the nested button accessibility issue (ChartErrorFallback retry Button inside Card rendered as Button in CardWithSparkline.tsx) out of scope for the error boundaries feature PR, consistent with deferring minor a11y improvements to follow-up PRs.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2026-01-15T09:59:33.508Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11656
File: src/pages/Yields/components/YieldsList.tsx:1028-1046
Timestamp: 2026-01-15T09:59:33.508Z
Learning: In the Yields UI components (src/pages/Yields/components), do not render an in-app mobile filter UI due to limited screen space. Users on mobile should access filtered views via URL query parameters instead. This pattern applies to similar Yields UI components in the same directory; ensure the mobile UI remains navigable through URL parameters (e.g., ?filters=...), and document this behavior for consistency across the Yields-related components.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use Chakra UI components and conventions

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-10-07T03:44:27.350Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10760
File: src/components/ManageHiddenAssets/ManageHiddenAssetsList.tsx:78-84
Timestamp: 2025-10-07T03:44:27.350Z
Learning: In the ShapeShift web codebase, the following are stable references and do not need to be included in useCallback/useMemo dependency arrays:
- `navigate` from `useBrowserRouter()` hook
- Modal control objects (like `walletDrawer`) from `useModal()` hook (including their `isOpen`, `close`, and `open` methods)
- These are backed by stable context providers

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : EXTRACT complex logic into custom hooks

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : USE local state for component-level state; LIFT state up when needed across multiple components; USE Context for avoiding prop drilling; USE Redux only for global state shared across multiple places

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-08-21T22:15:25.918Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useFetchBasePortfolio.ts:31-59
Timestamp: 2025-08-21T22:15:25.918Z
Learning: In the ShapeShift web codebase, the maintainer prefers inferred return types for React hooks over explicit return types, particularly for complex hooks that can have intricate return signatures.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-07-29T10:27:23.424Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/react-best-practices.mdc:8-14
Timestamp: 2025-07-29T10:27:23.424Z
Learning: The ShapeShift team practices aggressive memoization in React components as documented in .cursor/rules/react-best-practices.mdc. They use useMemo for all transformations, derived values, and conditional values, and useCallback for all event handlers and functions that could be passed as props. This approach was adopted after experiencing performance issues ("had hard time") and is their current established practice, though they acknowledge it may evolve in the future.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-10-17T07:51:58.374Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10783
File: src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx:344-349
Timestamp: 2025-10-17T07:51:58.374Z
Learning: In the shapeshift/web codebase, Chakra UI's ModalContent component supports the containerProps prop. When using the useModalRegistration hook from ModalStackProvider, spreading {...modalContentProps} directly onto ModalContent is correct and properly applies z-index and pointer-events through containerProps.sx. Do not suggest extracting sx from modalContentProps.containerProps.sx.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-08-14T17:54:32.563Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx:97-108
Timestamp: 2025-08-14T17:54:32.563Z
Learning: In ReusableLpStatus component (src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx), the txAssets dependency is stable from first render because poolAsset, baseAsset, actionSide, and action are all defined first render, making the current txAssetsStatuses initialization pattern safe without needing useEffect synchronization.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
📚 Learning: 2025-08-22T13:02:58.824Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx:33-41
Timestamp: 2025-08-22T13:02:58.824Z
Learning: In src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx, NeOMakinG declined optimizing useMemo dependencies to depend on lifetimeRewardDistributionsQuery.data instead of the entire query object, indicating indifference toward this type of performance optimization.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-12-27T16:02:52.792Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11536
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx:252-265
Timestamp: 2025-12-27T16:02:52.792Z
Learning: When reviewing bug fixes, especially in shapeshift/web, prefer minimal changes that fix correctness over introducing broader refactors or quality-of-life improvements (e.g., extracting duplicated logic) unless such improvements are essential to the fix. Apply this guideline broadly to TSX files and related components, not just the specific location, to keep changes focused and maintainable.

Applied to files:

  • src/pages/Yields/components/YieldPositionCard.tsx
  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-10-21T17:11:18.087Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10871
File: src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx:426-428
Timestamp: 2025-10-21T17:11:18.087Z
Learning: In src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, within the handleInputChange function, use .toFixed() without arguments (not .toString()) when converting BigNumber amounts for input field synchronization. This avoids exponential notation in the input while preserving precision for presentational components like <Amount.Crypto /> and <Amount.Fiat /> to format appropriately.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-05T17:00:30.416Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/components/AssetSearchRow.tsx:78-78
Timestamp: 2025-08-05T17:00:30.416Z
Learning: In BigNumber operations within the ShapeShift codebase, floating point literals like 0.01 should always be passed as strings like '0.01' to maintain precision. This applies to all BigNumber methods including .times(), .div(), .plus(), and .minus().

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-04T17:26:19.447Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/PriceChangeTag/PriceChangeTag.tsx:25-36
Timestamp: 2025-09-04T17:26:19.447Z
Learning: In the shapeshift/web project, NeOMakinG prefers to hide 0% price changes in the PriceChangeTag component rather than displaying "0.00%", so the falsy check `if (!changePercent24Hr) return null` is intentional design behavior.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-07-24T11:07:20.536Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10073
File: src/features/defi/providers/fox-farming/components/FoxFarmingManager/Claim/Claim.tsx:77-84
Timestamp: 2025-07-24T11:07:20.536Z
Learning: In fox farming components, the `opportunity?.rewardsCryptoBaseUnit?.amounts` property has a well-defined type signature that is always an array (never undefined), but can be empty: `readonly [] | readonly [string, string, string] | readonly [string, string] | readonly [string]`. Using optional chaining on the `amounts` property itself is unnecessary since it's always defined, though accessing `amounts[0]` on an empty array returns undefined which bnOrZero() handles safely.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-05T16:39:58.598Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/Explore.tsx:56-56
Timestamp: 2025-08-05T16:39:58.598Z
Learning: In the ShapeShift web codebase, the established pattern for handling floating point numbers is to use BigNumber operations (bnOrZero, bn) for calculations and convert to strings using .toString() before passing to UI components like Amount.Fiat, Amount.Crypto, and Amount.Percent. This prevents JavaScript floating point precision issues and maintains consistency across the application.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-03T05:46:24.190Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx:130-141
Timestamp: 2025-11-03T05:46:24.190Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx, gomesalexandre prefers "let it crash" approach when Portals returns zero outputAmount or 100% buffer causing division by zero, rather than adding defensive guards to surface zero quotes. He wants to fail fast with exceptions that bubble up to the try/catch wrapper, surfacing upstream data issues rather than masking them with defensive programming.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: The ShapeShift codebase's fromBaseUnit function correctly handles hex strings (like WalletConnect transaction.value) without manual conversion because bnOrZero -> bn -> new BigNumber() automatically detects and parses hex strings starting with "0x". gomesalexandre confirmed this with concrete evidence showing hex value 0x176d1c49189db correctly converts to 0.000412118294825435 ETH.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-10-15T15:57:39.956Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-08-13T15:51:43.290Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/components/RatingModal.tsx:98-0
Timestamp: 2025-08-13T15:51:43.290Z
Learning: In the ShapeShift web codebase, for user-facing feedback modals like RatingModal, the team prefers to avoid showing error messages to users when webhook submissions fail, instead opting to silently close the modal to prevent "spamming" users with additional notifications that could be boring or frustrating for them. The UX philosophy prioritizes keeping interactions minimal and smooth over technical transparency.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-08T15:00:49.887Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-25T12:59:43.842Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/Fox/components/RFOXSection.tsx:234-248
Timestamp: 2025-08-25T12:59:43.842Z
Learning: NeOMakinG considers suggestions to refactor working modal state management from useState to useDisclosure as too nitpicky, preferring to keep such cosmetic code improvements out of feature PRs unless they address actual issues.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.tsx : Ensure TypeScript types are explicit and proper; avoid use of `any` type

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:30.085Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-11-24T21:20:30.085Z
Learning: Applies to **/*.{ts,tsx} : Use `use` prefix for custom React hooks with camelCase naming after the prefix

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-13T15:52:25.116Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts:61-0
Timestamp: 2025-08-13T15:52:25.116Z
Learning: In the ShapeShift web codebase, specifically in src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts, message variants in the Message union type do not include inline comments documenting their expected return types. The codebase follows a pattern of keeping these type definitions clean without such documentation comments.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Avoid 'any' types - use specific type annotations instead

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-08-08T14:59:40.422Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/pages/Explore/ExploreCategory.tsx:231-238
Timestamp: 2025-08-08T14:59:40.422Z
Learning: In src/pages/Explore/ExploreCategory.tsx, for the PageHeader filter trigger, NeOMakinG considers changing a clickable Chakra Icon to IconButton too nitpicky for this PR and prefers to keep the current Icon-based trigger; such minor a11y/UI nitpicks should be deferred to a follow-up if needed.

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use strict typing - avoid `any`

Applied to files:

  • src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: gomesalexandre confirmed that fromBaseUnit in the ShapeShift codebase correctly handles hex strings (like transaction.value from WalletConnect) without requiring manual hex-to-decimal conversion, as bnOrZero handles this automatically via BigNumber.js.

Applied to files:

  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-12-09T21:06:15.748Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:66-68
Timestamp: 2025-12-09T21:06:15.748Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with throwing errors directly in getUnsignedSuiTransaction and similar transaction preparation methods, rather than using the Result pattern. The Result pattern with makeSwapErrorRight/TradeQuoteError is primarily for the main swapper API methods (getTradeQuote, getTradeRate), while helper/preparation methods can use throws.

Applied to files:

  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-12-17T14:50:01.629Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.

Applied to files:

  • src/lib/yieldxyz/executeTransaction.ts
📚 Learning: 2025-08-22T13:16:12.721Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx:104-105
Timestamp: 2025-08-22T13:16:12.721Z
Learning: In src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx, the guard `if (!actions[actionId]) return` before upserting completed reward distributions is intentional product behavior. NeOMakinG confirmed that the system should only show completion notifications for reward distributions that were previously seen in a pending state, not for distributions the user missed during the pending phase.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-08-22T14:59:04.889Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx:105-111
Timestamp: 2025-08-22T14:59:04.889Z
Learning: In the ShapeShift web Base chain handling, the await pattern inside forEach in useGenericTransactionSubscriber is intentional to delay the entire action completion flow (not just fetchBasePortfolio) for Base chain transactions. The user kaladinlight wants everything below the Base portfolio refresh - including dispatch, query invalidation, and toast notifications - to also be delayed by ~10 seconds to accommodate Base's degraded node state.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-08-22T12:58:26.590Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx:108-111
Timestamp: 2025-08-22T12:58:26.590Z
Learning: In the RFOX GenericTransactionDisplayType flow in src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx, the txHash is always guaranteed to be present according to NeOMakinG, so defensive null checks for txLink are not needed in this context.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-08-22T15:07:18.021Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:37-41
Timestamp: 2025-08-22T15:07:18.021Z
Learning: In src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx, kaladinlight prefers not to await the upsertBasePortfolio call in the Base chain handling block, indicating intentional fire-and-forget behavior for Base portfolio upserts in the THORChain LP completion flow.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-08-14T17:56:23.721Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:545-566
Timestamp: 2025-08-14T17:56:23.721Z
Learning: gomesalexandre prefers not to extract helper functions for toast rendering patterns in TransactionRow.tsx (src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx), considering it over-abstraction even when there's code duplication between deposit and withdraw flows.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : ALWAYS use `useCallback` for event handlers and functions passed as props

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Validate all inputs, especially user inputs

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : ALWAYS use `useCallback` for any function that could be passed as a prop or dependency

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-26T17:45:47.676Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10592
File: src/state/slices/tradeRampInputSlice/selectors.ts:53-63
Timestamp: 2025-09-26T17:45:47.676Z
Learning: gomesalexandre considers additional rate validation guards (like checking rate > 0) unnecessary when the mathematical operation already handles edge cases correctly (e.g., multiplying by 0 yields 0). He prefers to avoid defensive programming when domain knowledge indicates certain edge cases (like negative rates) are not valid concerns, consistent with his TypeScript-first approach over runtime validations.

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-09-13T16:45:17.166Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-19T16:59:50.569Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11012
File: src/context/WalletProvider/Vultisig/components/Connect.tsx:24-59
Timestamp: 2025-11-19T16:59:50.569Z
Learning: In src/context/WalletProvider/*/components/Connect.tsx files across the ShapeShift web codebase, the established pattern for handling null/undefined adapter from getAdapter() is to simply check `if (adapter) { ... }` without an else clause. All wallet Connect components (Coinbase, Keplr, Phantom, Ledger, MetaMask, WalletConnectV2, KeepKey, Vultisig) follow this pattern—they reset loading state after the if block but do not show error messages when adapter is null. This is an intentional design decision and should be maintained for consistency.

Applied to files:

  • src/pages/Yields/components/YieldForm.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/assets/translations/en/main.json : Add English copy to `src/assets/translations/en/main.json` (find appropriate section)

Applied to files:

  • src/assets/translations/en/main.json
📚 Learning: 2025-10-21T23:21:22.304Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10759
File: src/components/Modals/Send/hooks/useFormSend/useFormSend.tsx:41-50
Timestamp: 2025-10-21T23:21:22.304Z
Learning: In the shapeshift/web repository, the translation workflow follows an "English-first" approach: English translations in src/assets/translations/en/main.json are updated first in PRs, and translations for the other supported languages (de, es, fr, id, ja, ko, pt, ru, tr, uk, zh) are updated "after the fact" in follow-up work. Temporary mismatches between English and other language translation keys/formats during active development are expected and acceptable.
<!--

Applied to files:

  • src/assets/translations/en/main.json
📚 Learning: 2025-07-24T21:05:13.642Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10073
File: src/components/Layout/Header/ActionCenter/components/Details/ClaimDetails.tsx:10-11
Timestamp: 2025-07-24T21:05:13.642Z
Learning: In the ShapeShift web repository, translation workflow follows a two-step process: 1) First PR adds only English translations to src/assets/translations/en/main.json, 2) Globalization team handles follow-up PRs to add keys to remaining language files (de, es, fr, id, ja, ko, pt, ru, tr, uk, zh). Don't suggest verifying all locale files simultaneously during initial feature PRs.

Applied to files:

  • src/assets/translations/en/main.json
📚 Learning: 2025-08-17T23:39:00.407Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10291
File: src/assets/translations/en/main.json:216-218
Timestamp: 2025-08-17T23:39:00.407Z
Learning: In the shapeshift/web project, translations for non-English locales are handled as a separate follow-up process by language experts, not as part of the initial PR that adds English keys to src/assets/translations/en/main.json.

Applied to files:

  • src/assets/translations/en/main.json
📚 Learning: 2025-08-13T15:50:41.994Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/components/RatingModal.tsx:104-0
Timestamp: 2025-08-13T15:50:41.994Z
Learning: In the ShapeShift web codebase, internal strings like Discord webhook embed content (used for team notifications/feedback) don't need to be translated, only user-facing strings require translation keys. The team distinguishes between internal tooling strings and user-facing UI strings for internationalization purposes.

Applied to files:

  • src/assets/translations/en/main.json
🧬 Code graph analysis (4)
src/lib/yieldxyz/constants.ts (2)
src/lib/yieldxyz/types.ts (1)
  • ValidatorDto (285-297)
packages/caip/src/constants.ts (2)
  • cosmosChainId (84-84)
  • solanaChainId (89-89)
src/pages/Yields/components/YieldPositionCard.tsx (2)
src/components/Text/Text.tsx (1)
  • Text (19-83)
src/components/Amount/Amount.tsx (1)
  • Amount (21-42)
src/pages/Yields/components/YieldEnterModal.tsx (5)
src/react-queries/queries/yieldxyz/useYieldValidators.ts (1)
  • useYieldValidators (26-42)
src/lib/yieldxyz/constants.ts (4)
  • DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID (101-104)
  • SHAPESHIFT_COSMOS_VALIDATOR_ADDRESS (62-63)
  • SHAPESHIFT_VALIDATOR_NAME (72-72)
  • SHAPESHIFT_VALIDATOR_LOGO (65-66)
src/state/slices/common-selectors.ts (1)
  • selectPortfolioCryptoPrecisionBalanceByFilter (148-163)
src/pages/Yields/hooks/useYieldTransactionFlow.ts (1)
  • useYieldTransactionFlow (153-835)
src/lib/yieldxyz/utils.ts (1)
  • getTransactionButtonText (54-75)
src/lib/yieldxyz/executeTransaction.ts (1)
src/lib/yieldxyz/constants.ts (1)
  • SOLANA_YIELD_COMPUTE_UNIT_MARGIN_MULTIPLIER (60-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call / Static

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

gomesalexandre and others added 2 commits January 15, 2026 14:25
- Use locale-aware currency symbol for fiat placeholder
- URL-encode sellAsset.assetId in earn route
- Handle undefined validatorAddress properly
- Fix React.ChangeEvent type import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Image component with Avatar to avoid external CoinGecko fallback
URL. Avatar uses built-in fallback showing initials from name prop.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gomesalexandre gomesalexandre enabled auto-merge (squash) January 15, 2026 13:37
@gomesalexandre
Copy link
Contributor Author

@coderabbitai stop commenting you nit

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

@gomesalexandre, understood! I'll stop commenting on this PR.


🧠 Learnings used
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:21-24
Timestamp: 2025-09-12T13:16:27.004Z
Learning: gomesalexandre declined to add error boundaries to WalletConnect modals in PR `#10461`, stating "no error boundaries in this pr ser", consistent with his preference to keep PR scope focused and defer tangential improvements to separate efforts.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR `#10418` for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10572
File: src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx:9-9
Timestamp: 2025-09-18T09:19:59.425Z
Learning: gomesalexandre dismissed a technical suggestion about using location from useBrowserRouter instead of mixing useLocation with useBrowserRouter.navigate with "meh" in PR `#10572` for StakingPositionsByProvider.tsx, consistent with his pattern of preferring functional solutions over architectural purity when the current approach works adequately.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10879
File: src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx:64-81
Timestamp: 2025-10-22T22:11:22.918Z
Learning: In early WalletConnect POC/features behind a flag, gomesalexandre prioritizes connection correctness/stability over UX polish; minimal safety guards (like preventing concurrent connects) are preferred, while visuals will be wired later by reallybeard.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:69-74
Timestamp: 2025-09-10T15:35:36.547Z
Learning: gomesalexandre dismissed alt text accessibility suggestion with "meh" in PR `#10458` for EIP155SignTypedDataConfirmation.tsx Image component, consistent with team pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
✅ Actions performed

Reviews paused.

@gomesalexandre gomesalexandre merged commit f61622e into develop Jan 15, 2026
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_big_yield_consolidation_feat_polish_fixes branch January 15, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants